[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 gpu {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
|
||||||
D3D12Shader::D3D12Shader(xenos::ShaderType shader_type, uint64_t data_hash,
|
D3D12Shader::D3D12Shader(xenos::ShaderType shader_type,
|
||||||
const uint32_t* dword_ptr, uint32_t dword_count)
|
uint64_t ucode_data_hash, const uint32_t* ucode_dwords,
|
||||||
: DxbcShader(shader_type, data_hash, dword_ptr, dword_count) {}
|
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(
|
void D3D12Shader::D3D12Translation::DisassembleDxbcAndDxil(
|
||||||
const ui::d3d12::D3D12Provider& provider, bool disassemble_dxbc,
|
const ui::d3d12::D3D12Provider& provider, bool disassemble_dxbc,
|
||||||
|
|
|
@ -33,8 +33,9 @@ class D3D12Shader : public DxbcShader {
|
||||||
IDxcCompiler* dxc_compiler = nullptr);
|
IDxcCompiler* dxc_compiler = nullptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
D3D12Shader(xenos::ShaderType shader_type, uint64_t data_hash,
|
D3D12Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||||
const uint32_t* dword_ptr, uint32_t dword_count);
|
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
|
// For owning subsystem like the pipeline cache, accessors for unique
|
||||||
// identifiers (used instead of hashes to make sure collisions can't happen)
|
// identifiers (used instead of hashes to make sure collisions can't happen)
|
||||||
|
|
|
@ -14,9 +14,11 @@
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
DxbcShader::DxbcShader(xenos::ShaderType shader_type, uint64_t data_hash,
|
DxbcShader::DxbcShader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||||
const uint32_t* dword_ptr, uint32_t dword_count)
|
const uint32_t* ucode_dwords, size_t ucode_dword_count,
|
||||||
: Shader(shader_type, data_hash, dword_ptr, 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(
|
Shader::Translation* DxbcShader::CreateTranslationInstance(
|
||||||
uint64_t modification) {
|
uint64_t modification) {
|
||||||
|
|
|
@ -28,8 +28,9 @@ class DxbcShader : public Shader {
|
||||||
: Translation(shader, modification) {}
|
: Translation(shader, modification) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
DxbcShader(xenos::ShaderType shader_type, uint64_t data_hash,
|
DxbcShader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||||
const uint32_t* dword_ptr, uint32_t dword_count);
|
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
|
// Resource bindings are gathered after the successful translation of any
|
||||||
// modification for simplicity of translation (and they don't depend on
|
// modification for simplicity of translation (and they don't depend on
|
||||||
|
|
|
@ -25,11 +25,17 @@ namespace gpu {
|
||||||
using namespace ucode;
|
using namespace ucode;
|
||||||
|
|
||||||
Shader::Shader(xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
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) {
|
: 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.
|
// We keep ucode data in host native format so it's easier to work with.
|
||||||
ucode_data_.resize(ucode_dword_count);
|
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() {
|
Shader::~Shader() {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "xenia/base/byte_order.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/base/string_buffer.h"
|
#include "xenia/base/string_buffer.h"
|
||||||
#include "xenia/gpu/ucode.h"
|
#include "xenia/gpu/ucode.h"
|
||||||
|
@ -810,8 +811,11 @@ class Shader {
|
||||||
std::string host_disassembly_;
|
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,
|
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();
|
virtual ~Shader();
|
||||||
|
|
||||||
// Whether the shader is identified as a vertex or pixel 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, "",
|
DEFINE_string(shader_input_type, "",
|
||||||
"'vs', 'ps', or unspecified to infer from the given filename.",
|
"'vs', 'ps', or unspecified to infer from the given filename.",
|
||||||
"GPU");
|
"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_path(shader_output, "", "Output shader file path.", "GPU");
|
||||||
DEFINE_string(shader_output_type, "ucode",
|
DEFINE_string(shader_output_type, "ucode",
|
||||||
"Translator to use: [ucode, spirv, spirvtext, dxbc, dxbctext].",
|
"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.
|
// TODO(benvanik): hash? need to return the data to big-endian format first.
|
||||||
uint64_t ucode_data_hash = 0;
|
uint64_t ucode_data_hash = 0;
|
||||||
auto shader = std::make_unique<Shader>(
|
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;
|
StringBuffer ucode_disasm_buffer;
|
||||||
shader->AnalyzeUcode(ucode_disasm_buffer);
|
shader->AnalyzeUcode(ucode_disasm_buffer);
|
||||||
|
|
|
@ -22,9 +22,13 @@ namespace vulkan {
|
||||||
using xe::ui::vulkan::util::CheckResult;
|
using xe::ui::vulkan::util::CheckResult;
|
||||||
|
|
||||||
VulkanShader::VulkanShader(const ui::vulkan::VulkanProvider& provider,
|
VulkanShader::VulkanShader(const ui::vulkan::VulkanProvider& provider,
|
||||||
xenos::ShaderType shader_type, uint64_t data_hash,
|
xenos::ShaderType shader_type,
|
||||||
const uint32_t* dword_ptr, uint32_t dword_count)
|
uint64_t ucode_data_hash,
|
||||||
: Shader(shader_type, data_hash, dword_ptr, dword_count),
|
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) {}
|
provider_(provider) {}
|
||||||
|
|
||||||
VulkanShader::VulkanTranslation::~VulkanTranslation() {
|
VulkanShader::VulkanTranslation::~VulkanTranslation() {
|
||||||
|
|
|
@ -37,8 +37,9 @@ class VulkanShader : public Shader {
|
||||||
};
|
};
|
||||||
|
|
||||||
VulkanShader(const ui::vulkan::VulkanProvider& provider,
|
VulkanShader(const ui::vulkan::VulkanProvider& provider,
|
||||||
xenos::ShaderType shader_type, uint64_t data_hash,
|
xenos::ShaderType shader_type, uint64_t ucode_data_hash,
|
||||||
const uint32_t* dword_ptr, uint32_t dword_count);
|
const uint32_t* ucode_dwords, size_t ucode_dword_count,
|
||||||
|
std::endian ucode_source_endian = std::endian::big);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Translation* CreateTranslationInstance(uint64_t modification) override;
|
Translation* CreateTranslationInstance(uint64_t modification) override;
|
||||||
|
|
Loading…
Reference in New Issue