[GPU] shader-compiler: Accept little-endian ucode
This commit is contained in:
parent
443d61c9e1
commit
69958cba9d
|
@ -22,9 +22,12 @@ namespace xe {
|
|||
namespace gpu {
|
||||
namespace d3d12 {
|
||||
|
||||
D3D12Shader::D3D12Shader(xenos::ShaderType shader_type, uint64_t data_hash,
|
||||
const uint32_t* dword_ptr, uint32_t dword_count)
|
||||
: DxbcShader(shader_type, data_hash, dword_ptr, dword_count) {}
|
||||
D3D12Shader::D3D12Shader(xenos::ShaderType shader_type,
|
||||
uint64_t ucode_data_hash, const uint32_t* ucode_dwords,
|
||||
size_t ucode_dword_count,
|
||||
std::endian ucode_source_endian)
|
||||
: DxbcShader(shader_type, ucode_data_hash, ucode_dwords, ucode_dword_count,
|
||||
ucode_source_endian) {}
|
||||
|
||||
void D3D12Shader::D3D12Translation::DisassembleDxbcAndDxil(
|
||||
const ui::d3d12::D3D12Provider& provider, bool disassemble_dxbc,
|
||||
|
|
|
@ -33,8 +33,9 @@ class D3D12Shader : public DxbcShader {
|
|||
IDxcCompiler* dxc_compiler = nullptr);
|
||||
};
|
||||
|
||||
D3D12Shader(xenos::ShaderType shader_type, uint64_t data_hash,
|
||||
const uint32_t* dword_ptr, uint32_t dword_count);
|
||||
D3D12Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||
const uint32_t* ucode_dwords, size_t ucode_dword_count,
|
||||
std::endian ucode_source_endian = std::endian::big);
|
||||
|
||||
// For owning subsystem like the pipeline cache, accessors for unique
|
||||
// identifiers (used instead of hashes to make sure collisions can't happen)
|
||||
|
|
|
@ -14,9 +14,11 @@
|
|||
namespace xe {
|
||||
namespace gpu {
|
||||
|
||||
DxbcShader::DxbcShader(xenos::ShaderType shader_type, uint64_t data_hash,
|
||||
const uint32_t* dword_ptr, uint32_t dword_count)
|
||||
: Shader(shader_type, data_hash, dword_ptr, dword_count) {}
|
||||
DxbcShader::DxbcShader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||
const uint32_t* ucode_dwords, size_t ucode_dword_count,
|
||||
std::endian ucode_source_endian)
|
||||
: Shader(shader_type, ucode_data_hash, ucode_dwords, ucode_dword_count,
|
||||
ucode_source_endian) {}
|
||||
|
||||
Shader::Translation* DxbcShader::CreateTranslationInstance(
|
||||
uint64_t modification) {
|
||||
|
|
|
@ -28,8 +28,9 @@ class DxbcShader : public Shader {
|
|||
: Translation(shader, modification) {}
|
||||
};
|
||||
|
||||
DxbcShader(xenos::ShaderType shader_type, uint64_t data_hash,
|
||||
const uint32_t* dword_ptr, uint32_t dword_count);
|
||||
DxbcShader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||
const uint32_t* ucode_dwords, size_t ucode_dword_count,
|
||||
std::endian ucode_source_endian = std::endian::big);
|
||||
|
||||
// Resource bindings are gathered after the successful translation of any
|
||||
// modification for simplicity of translation (and they don't depend on
|
||||
|
|
|
@ -25,11 +25,17 @@ namespace gpu {
|
|||
using namespace ucode;
|
||||
|
||||
Shader::Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||
const uint32_t* ucode_dwords, size_t ucode_dword_count)
|
||||
const uint32_t* ucode_dwords, size_t ucode_dword_count,
|
||||
std::endian ucode_source_endian)
|
||||
: shader_type_(shader_type), ucode_data_hash_(ucode_data_hash) {
|
||||
// We keep ucode data in host native format so it's easier to work with.
|
||||
ucode_data_.resize(ucode_dword_count);
|
||||
xe::copy_and_swap(ucode_data_.data(), ucode_dwords, ucode_dword_count);
|
||||
if (std::endian::native != ucode_source_endian) {
|
||||
xe::copy_and_swap(ucode_data_.data(), ucode_dwords, ucode_dword_count);
|
||||
} else {
|
||||
std::memcpy(ucode_data_.data(), ucode_dwords,
|
||||
sizeof(uint32_t) * ucode_dword_count);
|
||||
}
|
||||
}
|
||||
|
||||
Shader::~Shader() {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/base/byte_order.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/base/string_buffer.h"
|
||||
#include "xenia/gpu/ucode.h"
|
||||
|
@ -810,8 +811,11 @@ class Shader {
|
|||
std::string host_disassembly_;
|
||||
};
|
||||
|
||||
// ucode_source_endian specifies the endianness of the ucode_dwords argument -
|
||||
// inside the Shader, the ucode will be stored with the native byte order.
|
||||
Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||
const uint32_t* ucode_dwords, size_t ucode_dword_count);
|
||||
const uint32_t* ucode_dwords, size_t ucode_dword_count,
|
||||
std::endian ucode_source_endian = std::endian::big);
|
||||
virtual ~Shader();
|
||||
|
||||
// Whether the shader is identified as a vertex or pixel shader.
|
||||
|
|
|
@ -33,6 +33,11 @@ DEFINE_path(shader_input, "", "Input shader binary file path.", "GPU");
|
|||
DEFINE_string(shader_input_type, "",
|
||||
"'vs', 'ps', or unspecified to infer from the given filename.",
|
||||
"GPU");
|
||||
DEFINE_bool(
|
||||
shader_input_little_endian, false,
|
||||
"Whether the input shader binary is little-endian (from an Arm device with "
|
||||
"the Qualcomm Adreno 200, for instance).",
|
||||
"GPU");
|
||||
DEFINE_path(shader_output, "", "Output shader file path.", "GPU");
|
||||
DEFINE_string(shader_output_type, "ucode",
|
||||
"Translator to use: [ucode, spirv, spirvtext, dxbc, dxbctext].",
|
||||
|
@ -104,7 +109,9 @@ int shader_compiler_main(const std::vector<std::string>& args) {
|
|||
// TODO(benvanik): hash? need to return the data to big-endian format first.
|
||||
uint64_t ucode_data_hash = 0;
|
||||
auto shader = std::make_unique<Shader>(
|
||||
shader_type, ucode_data_hash, ucode_dwords.data(), ucode_dwords.size());
|
||||
shader_type, ucode_data_hash, ucode_dwords.data(), ucode_dwords.size(),
|
||||
cvars::shader_input_little_endian ? std::endian::little
|
||||
: std::endian::big);
|
||||
|
||||
StringBuffer ucode_disasm_buffer;
|
||||
shader->AnalyzeUcode(ucode_disasm_buffer);
|
||||
|
|
|
@ -22,9 +22,13 @@ namespace vulkan {
|
|||
using xe::ui::vulkan::util::CheckResult;
|
||||
|
||||
VulkanShader::VulkanShader(const ui::vulkan::VulkanProvider& provider,
|
||||
xenos::ShaderType shader_type, uint64_t data_hash,
|
||||
const uint32_t* dword_ptr, uint32_t dword_count)
|
||||
: Shader(shader_type, data_hash, dword_ptr, dword_count),
|
||||
xenos::ShaderType shader_type,
|
||||
uint64_t ucode_data_hash,
|
||||
const uint32_t* ucode_dwords,
|
||||
size_t ucode_dword_count,
|
||||
std::endian ucode_source_endian)
|
||||
: Shader(shader_type, ucode_data_hash, ucode_dwords, ucode_dword_count,
|
||||
ucode_source_endian),
|
||||
provider_(provider) {}
|
||||
|
||||
VulkanShader::VulkanTranslation::~VulkanTranslation() {
|
||||
|
|
|
@ -37,8 +37,9 @@ class VulkanShader : public Shader {
|
|||
};
|
||||
|
||||
VulkanShader(const ui::vulkan::VulkanProvider& provider,
|
||||
xenos::ShaderType shader_type, uint64_t data_hash,
|
||||
const uint32_t* dword_ptr, uint32_t dword_count);
|
||||
xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||
const uint32_t* ucode_dwords, size_t ucode_dword_count,
|
||||
std::endian ucode_source_endian = std::endian::big);
|
||||
|
||||
protected:
|
||||
Translation* CreateTranslationInstance(uint64_t modification) override;
|
||||
|
|
Loading…
Reference in New Issue