From 43dfba228736549838498c794eb3f6a036b5a082 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 13 Nov 2017 00:22:52 +0100 Subject: [PATCH] [dxbc] Separate code generator classed for each shader type --- src/dxbc/dxbc_compiler.cpp | 56 +++++++++++++-- src/dxbc/dxbc_compiler.h | 46 ++++++------ src/dxbc/dxbc_decoder.h | 13 ++++ src/dxbc/dxbc_module.cpp | 7 -- src/dxbc/dxbc_names.cpp | 13 ++++ src/dxbc/dxbc_names.h | 2 + src/dxbc/dxbc_type.cpp | 8 --- src/dxbc/dxbc_type.h | 28 ++------ src/dxbc/gen/dxbc_gen_common.cpp | 120 +++++++++++++++++++++++++++++++ src/dxbc/gen/dxbc_gen_common.h | 108 ++++++++++++++++++++++++++++ src/dxbc/gen/dxbc_gen_vertex.cpp | 38 ++++++++++ src/dxbc/gen/dxbc_gen_vertex.h | 38 ++++++++++ src/dxbc/meson.build | 3 + src/spirv/spirv_module.cpp | 103 ++++++++++++++++---------- src/spirv/spirv_module.h | 16 ++++- 15 files changed, 489 insertions(+), 110 deletions(-) create mode 100644 src/dxbc/gen/dxbc_gen_common.cpp create mode 100644 src/dxbc/gen/dxbc_gen_common.h create mode 100644 src/dxbc/gen/dxbc_gen_vertex.cpp create mode 100644 src/dxbc/gen/dxbc_gen_vertex.h diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 274ee7c9..2d5b60df 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -1,13 +1,10 @@ #include "dxbc_compiler.h" -#include "dxbc_names.h" namespace dxvk { DxbcCompiler::DxbcCompiler( - DxbcProgramVersion version) - : m_version(version) { - - } + const DxbcProgramVersion& version) + : m_gen(DxbcCodeGen::create(version)) { } DxbcCompiler::~DxbcCompiler() { @@ -16,13 +13,58 @@ namespace dxvk { void DxbcCompiler::processInstruction(const DxbcInstruction& ins) { + const DxbcOpcodeToken token = ins.token(); + switch (token.opcode()) { + case DxbcOpcode::DclGlobalFlags: + return this->dclGlobalFlags(ins); + + case DxbcOpcode::DclInput: + case DxbcOpcode::DclInputSiv: + case DxbcOpcode::DclInputSgv: + case DxbcOpcode::DclInputPs: + case DxbcOpcode::DclInputPsSiv: + case DxbcOpcode::DclInputPsSgv: + return this->dclInput(ins); + + case DxbcOpcode::DclOutput: + case DxbcOpcode::DclOutputSiv: + case DxbcOpcode::DclOutputSgv: + return this->dclOutput(ins); + + case DxbcOpcode::DclTemps: + return this->dclTemps(ins); + + default: + Logger::err(str::format( + "DxbcCompiler::processInstruction: Unhandled opcode: ", + token.opcode())); + } } Rc DxbcCompiler::finalize() { - return new DxvkShader(m_version.shaderStage(), - m_module.compile(), 0, nullptr); + return m_gen->finalize(); + } + + + void DxbcCompiler::dclGlobalFlags(const DxbcInstruction& ins) { + + } + + + void DxbcCompiler::dclInput(const DxbcInstruction& ins) { + + } + + + void DxbcCompiler::dclOutput(const DxbcInstruction& ins) { + + } + + + void DxbcCompiler::dclTemps(const DxbcInstruction& ins) { + m_gen->dclTemps(ins.arg(0)); } } \ No newline at end of file diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 1702c7a8..a3533e4a 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -1,49 +1,43 @@ #pragma once -#include "dxbc_chunk_isgn.h" -#include "dxbc_chunk_shex.h" -#include "dxbc_names.h" -#include "dxbc_type.h" - -#include "../spirv/spirv_module.h" +#include "./gen/dxbc_gen_common.h" namespace dxvk { /** - * \brief DXBC to SPIR-V compiler + * \brief DXBC compiler + * + * Interprets DXBC instructions and generates + * SPIR-V code for the appropriate shader type. */ class DxbcCompiler { public: DxbcCompiler( - DxbcProgramVersion version); + const DxbcProgramVersion& version); ~DxbcCompiler(); - DxbcCompiler (DxbcCompiler&&) = delete; - DxbcCompiler& operator = (DxbcCompiler&&) = delete; - - /** - * \brief Processes a single instruction - * - * \param [in] ins The instruction - * \returns \c true on success - */ void processInstruction( - const DxbcInstruction& ins); + const DxbcInstruction& ins); - /** - * \brief Creates actual shader object - * - * Combines all information gatherd during the - * shader compilation into one shader object. - */ Rc finalize(); private: - DxbcProgramVersion m_version; - SpirvModule m_module; + Rc m_gen; + + void dclGlobalFlags( + const DxbcInstruction& ins); + + void dclInput( + const DxbcInstruction& ins); + + void dclOutput( + const DxbcInstruction& ins); + + void dclTemps( + const DxbcInstruction& ins); }; diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 90006fb9..9d88cea6 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -527,6 +527,19 @@ namespace dxvk { return m_args.getWord(idx); } + /** + * \brief Reads an argument enum + * + * Casts the word at the given location to an enum. + * Some instructions take name tokens as operands. + * \param [in] idx Argument word index + * \returns The enum value of the given word + */ + template + T readEnum(uint32_t idx) const { + return static_cast(arg(idx)); + } + /** * \brief Retrieves an operand * diff --git a/src/dxbc/dxbc_module.cpp b/src/dxbc/dxbc_module.cpp index 09a43ad8..4555c4fa 100644 --- a/src/dxbc/dxbc_module.cpp +++ b/src/dxbc/dxbc_module.cpp @@ -45,13 +45,6 @@ namespace dxvk { throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); DxbcCompiler compiler(m_shexChunk->version()); - -// if (m_isgnChunk != nullptr) -// compiler.declareInputSignature(*m_isgnChunk); - -// if (m_osgnChunk != nullptr) -// compiler.declareOutputSignature(*m_osgnChunk); - for (auto ins : *m_shexChunk) compiler.processInstruction(ins); return compiler.finalize(); diff --git a/src/dxbc/dxbc_names.cpp b/src/dxbc/dxbc_names.cpp index 624246b7..56b7fa2a 100644 --- a/src/dxbc/dxbc_names.cpp +++ b/src/dxbc/dxbc_names.cpp @@ -390,3 +390,16 @@ std::ostream& operator << (std::ostream& os, DxbcSystemValue e) { ENUM_DEFAULT(e); } } + + +std::ostream& operator << (std::ostream& os, dxvk::DxbcProgramType e) { + switch (e) { + ENUM_NAME(DxbcProgramType::PixelShader); + ENUM_NAME(DxbcProgramType::VertexShader); + ENUM_NAME(DxbcProgramType::GeometryShader); + ENUM_NAME(DxbcProgramType::HullShader); + ENUM_NAME(DxbcProgramType::DomainShader); + ENUM_NAME(DxbcProgramType::ComputeShader); + ENUM_DEFAULT(e); + } +} diff --git a/src/dxbc/dxbc_names.h b/src/dxbc/dxbc_names.h index 4b419556..1b2719a4 100644 --- a/src/dxbc/dxbc_names.h +++ b/src/dxbc/dxbc_names.h @@ -2,6 +2,7 @@ #include +#include "dxbc_common.h" #include "dxbc_enums.h" std::ostream& operator << (std::ostream& os, dxvk::DxbcOpcode e); @@ -15,3 +16,4 @@ std::ostream& operator << (std::ostream& os, dxvk::DxbcResourceReturnType e); std::ostream& operator << (std::ostream& os, dxvk::DxbcRegisterComponentType e); std::ostream& operator << (std::ostream& os, dxvk::DxbcInstructionReturnType e); std::ostream& operator << (std::ostream& os, dxvk::DxbcSystemValue e); +std::ostream& operator << (std::ostream& os, dxvk::DxbcProgramType e); diff --git a/src/dxbc/dxbc_type.cpp b/src/dxbc/dxbc_type.cpp index 81366b10..ad68bfd7 100644 --- a/src/dxbc/dxbc_type.cpp +++ b/src/dxbc/dxbc_type.cpp @@ -14,12 +14,4 @@ namespace dxvk { return result; } - - DxbcComponentMask DxbcComponentSwizzle::mask(uint32_t n) const { - DxbcComponentMask mask; - for (uint32_t i = 0; i < n; i++) - mask.set(m_components.at(i)); - return mask; - } - } \ No newline at end of file diff --git a/src/dxbc/dxbc_type.h b/src/dxbc/dxbc_type.h index f820de7e..a6b652bc 100644 --- a/src/dxbc/dxbc_type.h +++ b/src/dxbc/dxbc_type.h @@ -30,10 +30,13 @@ namespace dxvk { struct DxbcValueType { DxbcValueType() { } DxbcValueType(DxbcScalarType s, uint32_t c) - : componentType(s), componentCount(c) { } + : DxbcValueType(s, c, 0) { } + DxbcValueType(DxbcScalarType s, uint32_t c, uint32_t e) + : componentType(s), componentCount(c), elementCount(e) { } DxbcScalarType componentType = DxbcScalarType::Uint32; uint32_t componentCount = 0; + uint32_t elementCount = 0; }; @@ -44,17 +47,7 @@ namespace dxvk { * result that can be used as an operand value. */ struct DxbcValue { - DxbcValue() { } - DxbcValue( - DxbcValueType p_type, - uint32_t p_typeId, - uint32_t p_valueId) - : type (p_type), - typeId (p_typeId), - valueId (p_valueId) { } - DxbcValueType type; - uint32_t typeId = 0; uint32_t valueId = 0; }; @@ -87,20 +80,11 @@ namespace dxvk { * class. Can be used as a memory operand. */ struct DxbcPointer { - DxbcPointer() { } - DxbcPointer( - DxbcPointerType p_type, - uint32_t p_typeId, - uint32_t p_valueId) - : type (p_type), - typeId (p_typeId), - valueId (p_valueId) { } - DxbcPointerType type; - uint32_t typeId = 0; uint32_t valueId = 0; }; + /** * \brief Component mask */ @@ -172,8 +156,6 @@ namespace dxvk { DxbcComponentSwizzle extract(DxbcComponentMask mask) const; - DxbcComponentMask mask(uint32_t n) const; - private: std::array m_components; diff --git a/src/dxbc/gen/dxbc_gen_common.cpp b/src/dxbc/gen/dxbc_gen_common.cpp new file mode 100644 index 00000000..9ddf9aae --- /dev/null +++ b/src/dxbc/gen/dxbc_gen_common.cpp @@ -0,0 +1,120 @@ +#include "dxbc_gen_common.h" +#include "dxbc_gen_vertex.h" + +#include "../dxbc_names.h" + +namespace dxvk { + + DxbcCodeGen::DxbcCodeGen() { + m_module.enableCapability(spv::CapabilityShader); + m_module.setMemoryModel( + spv::AddressingModelLogical, + spv::MemoryModelGLSL450); + m_entryPointId = m_module.allocateId(); + } + + + DxbcCodeGen::~DxbcCodeGen() { + + } + + + void DxbcCodeGen::dclTemps(uint32_t n) { + const uint32_t oldSize = m_rRegs.size(); + + if (n > oldSize) { + m_rRegs.resize(n); + + DxbcPointer reg; + reg.type = DxbcPointerType( + DxbcValueType(DxbcScalarType::Float32, 4), + spv::StorageClassPrivate); + + const uint32_t typeId = this->defPointerType(reg.type); + + for (uint32_t i = oldSize; i < n; i++) { + reg.valueId = m_module.newVar(typeId, spv::StorageClassPrivate); + m_module.setDebugName(reg.valueId, str::format("r", i).c_str()); + m_rRegs.at(i) = reg; + } + } + } + + + Rc DxbcCodeGen::create( + const DxbcProgramVersion& version) { + switch (version.type()) { + case DxbcProgramType::VertexShader: + return new DxbcVsCodeGen(); + + default: + throw DxvkError(str::format( + "DxbcCodeGen::create: Unsupported program type: ", + version.type())); + } + } + + + uint32_t DxbcCodeGen::defScalarType(DxbcScalarType type) { + switch (type) { + case DxbcScalarType::Uint32 : return m_module.defIntType(32, 0); + case DxbcScalarType::Uint64 : return m_module.defIntType(64, 0); + case DxbcScalarType::Sint32 : return m_module.defIntType(32, 1); + case DxbcScalarType::Sint64 : return m_module.defIntType(64, 1); + case DxbcScalarType::Float32: return m_module.defFloatType(32); + case DxbcScalarType::Float64: return m_module.defFloatType(64); + + default: + throw DxvkError("DxbcCodeGen::defScalarType: Invalid scalar type"); + } + } + + + uint32_t DxbcCodeGen::defValueType(const DxbcValueType& type) { + uint32_t typeId = this->defScalarType(type.componentType); + + if (type.componentCount > 1) + typeId = m_module.defVectorType(typeId, type.componentCount); + + if (type.elementCount > 0) + typeId = m_module.defArrayType(typeId, m_module.constu32(type.elementCount)); + + return typeId; + } + + + uint32_t DxbcCodeGen::defPointerType(const DxbcPointerType& type) { + uint32_t valueTypeId = this->defValueType(type.valueType); + return m_module.defPointerType(valueTypeId, type.storageClass); + } + + + uint32_t DxbcCodeGen::defPerVertexBlock() { + uint32_t s1f32 = this->defScalarType(DxbcScalarType::Float32); + uint32_t v4f32 = this->defValueType(DxbcValueType(DxbcScalarType::Float32, 4, 0)); + uint32_t a2f32 = this->defValueType(DxbcValueType(DxbcScalarType::Float32, 1, 2)); + + std::array members; + members[PerVertex_Position] = v4f32; + members[PerVertex_PointSize] = s1f32; + members[PerVertex_CullDist] = a2f32; + members[PerVertex_ClipDist] = a2f32; + + uint32_t typeId = m_module.defStructType( + members.size(), members.data()); + + m_module.memberDecorateBuiltIn(typeId, PerVertex_Position, spv::BuiltInPosition); + m_module.memberDecorateBuiltIn(typeId, PerVertex_PointSize, spv::BuiltInPointSize); + m_module.memberDecorateBuiltIn(typeId, PerVertex_CullDist, spv::BuiltInCullDistance); + m_module.memberDecorateBuiltIn(typeId, PerVertex_ClipDist, spv::BuiltInClipDistance); + m_module.decorateBlock(typeId); + + m_module.setDebugName(typeId, "per_vertex"); + m_module.setDebugMemberName(typeId, PerVertex_Position, "position"); + m_module.setDebugMemberName(typeId, PerVertex_PointSize, "point_size"); + m_module.setDebugMemberName(typeId, PerVertex_CullDist, "cull_dist"); + m_module.setDebugMemberName(typeId, PerVertex_ClipDist, "clip_dist"); + return typeId; + } + +} \ No newline at end of file diff --git a/src/dxbc/gen/dxbc_gen_common.h b/src/dxbc/gen/dxbc_gen_common.h new file mode 100644 index 00000000..807cf9ed --- /dev/null +++ b/src/dxbc/gen/dxbc_gen_common.h @@ -0,0 +1,108 @@ +#pragma once + +#include "../dxbc_common.h" +#include "../dxbc_decoder.h" +#include "../dxbc_type.h" + +#include "../../spirv/spirv_module.h" + +namespace dxvk { + + /** + * \brief System value mapping + * + * Maps a system value to a given set of + * components of an input or output register. + */ + struct DxbcSvMapping { + uint32_t regId; + DxbcComponentMask regMask; + DxbcSystemValue sv; + }; + + + /** + * \brief DXBC code generator + * + * SPIR-V code generator. Implements simple micro ops that are + * generated when parsing the DXBC shader code. Some of these + * may require different implementations for each shader stage + * and are therefore implemented in a sub class. + */ + class DxbcCodeGen : public RcObject { + + public: + + DxbcCodeGen(); + + virtual ~DxbcCodeGen(); + + /** + * \brief Declares temporary registers + * \param [in] n Number of temp registers + */ + void dclTemps(uint32_t n); + + /** + * \brief Declares an interface variable + * + * \param [in] regType Register type + * \param [in] regId Interface register index + * \param [in] regDim Array dimension of interface variable + * \param [in] regMask Component mask for this declaration + * \param [in] sv System value to map to the given components + */ + virtual void dclInterfaceVar( + DxbcOperandType regType, + uint32_t regId, + uint32_t regDim, + DxbcComponentMask regMask, + DxbcSystemValue sv) = 0; + + /** + * \brief Finalizes shader + * + * Depending on the shader stage, this may generate + * additional code to set up input variables, output + * variables, and execute shader phases. + * \returns DXVK shader module + */ + virtual Rc finalize() = 0; + + /** + * \brief Creates code generator for a given program type + * + * \param [in] version Program version + * \returns The code generator + */ + static Rc create( + const DxbcProgramVersion& version); + + protected: + + constexpr static uint32_t PerVertex_Position = 0; + constexpr static uint32_t PerVertex_PointSize = 1; + constexpr static uint32_t PerVertex_CullDist = 2; + constexpr static uint32_t PerVertex_ClipDist = 3; + + SpirvModule m_module; + + std::vector m_entryPointInterfaces; + uint32_t m_entryPointId = 0; + + std::vector m_rRegs; + + uint32_t defScalarType( + DxbcScalarType type); + + uint32_t defValueType( + const DxbcValueType& type); + + uint32_t defPointerType( + const DxbcPointerType& type); + + uint32_t defPerVertexBlock(); + + }; + +} \ No newline at end of file diff --git a/src/dxbc/gen/dxbc_gen_vertex.cpp b/src/dxbc/gen/dxbc_gen_vertex.cpp new file mode 100644 index 00000000..330f29bd --- /dev/null +++ b/src/dxbc/gen/dxbc_gen_vertex.cpp @@ -0,0 +1,38 @@ +#include "dxbc_gen_vertex.h" + +namespace dxvk { + + DxbcVsCodeGen::DxbcVsCodeGen() { + m_outPerVertex = m_module.newVar( + m_module.defPointerType(this->defPerVertexBlock(), spv::StorageClassOutput), + spv::StorageClassOutput); + } + + + DxbcVsCodeGen::~DxbcVsCodeGen() { + + } + + + void DxbcVsCodeGen::dclInterfaceVar( + DxbcOperandType regType, + uint32_t regId, + uint32_t regDim, + DxbcComponentMask regMask, + DxbcSystemValue sv) { + + } + + + Rc DxbcVsCodeGen::finalize() { + m_module.addEntryPoint(m_entryPointId, + spv::ExecutionModelVertex, "main", + m_entryPointInterfaces.size(), + m_entryPointInterfaces.data()); + m_module.setDebugName(m_entryPointId, "main"); + + return new DxvkShader(VK_SHADER_STAGE_VERTEX_BIT, + m_module.compile(), 0, nullptr); + } + +} \ No newline at end of file diff --git a/src/dxbc/gen/dxbc_gen_vertex.h b/src/dxbc/gen/dxbc_gen_vertex.h new file mode 100644 index 00000000..e798ac21 --- /dev/null +++ b/src/dxbc/gen/dxbc_gen_vertex.h @@ -0,0 +1,38 @@ +#pragma once + +#include "dxbc_gen_common.h" + +namespace dxvk { + + /** + * \brief Vertex shader code generator + */ + class DxbcVsCodeGen : public DxbcCodeGen { + + public: + + DxbcVsCodeGen(); + ~DxbcVsCodeGen(); + + void dclInterfaceVar( + DxbcOperandType regType, + uint32_t regId, + uint32_t regDim, + DxbcComponentMask regMask, + DxbcSystemValue sv); + + Rc finalize() final; + + private: + + uint32_t m_outPerVertex = 0; + + std::array m_vRegs; + std::array m_oRegs; + + std::vector m_svInputs; + std::vector m_svOutputs; + + }; + +} \ No newline at end of file diff --git a/src/dxbc/meson.build b/src/dxbc/meson.build index 04dcfbd6..037568dc 100644 --- a/src/dxbc/meson.build +++ b/src/dxbc/meson.build @@ -9,6 +9,9 @@ dxbc_src = files([ 'dxbc_names.cpp', 'dxbc_reader.cpp', 'dxbc_type.cpp', + + 'gen/dxbc_gen_common.cpp', + 'gen/dxbc_gen_vertex.cpp', ]) dxbc_lib = static_library('dxbc', dxbc_src, diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index ec4aba44..3150b5e8 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -15,8 +15,7 @@ namespace dxvk { result.append(m_execModeInfo); result.append(m_debugNames); result.append(m_annotations); - result.append(m_typeDefs); - result.append(m_constDefs); + result.append(m_typeConstDefs); result.append(m_variables); result.append(m_code); return result; @@ -98,14 +97,25 @@ namespace dxvk { } + void SpirvModule::setDebugMemberName( + uint32_t structId, + uint32_t memberId, + const char* debugName) { + m_debugNames.putIns (spv::OpMemberName, 3 + m_debugNames.strLen(debugName)); + m_debugNames.putWord(structId); + m_debugNames.putWord(memberId); + m_debugNames.putStr (debugName); + } + + uint32_t SpirvModule::constBool( bool v) { uint32_t typeId = this->defBoolType(); uint32_t resultId = this->allocateId(); - m_constDefs.putIns (v ? spv::OpConstantTrue : spv::OpConstantFalse, 3); - m_constDefs.putWord (typeId); - m_constDefs.putWord (resultId); + m_typeConstDefs.putIns (v ? spv::OpConstantTrue : spv::OpConstantFalse, 3); + m_typeConstDefs.putWord (typeId); + m_typeConstDefs.putWord (resultId); return resultId; } @@ -115,10 +125,10 @@ namespace dxvk { uint32_t typeId = this->defIntType(32, 1); uint32_t resultId = this->allocateId(); - m_constDefs.putIns (spv::OpConstant, 4); - m_constDefs.putWord (typeId); - m_constDefs.putWord (resultId); - m_constDefs.putInt32(v); + m_typeConstDefs.putIns (spv::OpConstant, 4); + m_typeConstDefs.putWord (typeId); + m_typeConstDefs.putWord (resultId); + m_typeConstDefs.putInt32(v); return resultId; } @@ -128,10 +138,10 @@ namespace dxvk { uint32_t typeId = this->defIntType(64, 1); uint32_t resultId = this->allocateId(); - m_constDefs.putIns (spv::OpConstant, 5); - m_constDefs.putWord (typeId); - m_constDefs.putWord (resultId); - m_constDefs.putInt64(v); + m_typeConstDefs.putIns (spv::OpConstant, 5); + m_typeConstDefs.putWord (typeId); + m_typeConstDefs.putWord (resultId); + m_typeConstDefs.putInt64(v); return resultId; } @@ -141,10 +151,10 @@ namespace dxvk { uint32_t typeId = this->defIntType(32, 0); uint32_t resultId = this->allocateId(); - m_constDefs.putIns (spv::OpConstant, 4); - m_constDefs.putWord (typeId); - m_constDefs.putWord (resultId); - m_constDefs.putInt32(v); + m_typeConstDefs.putIns (spv::OpConstant, 4); + m_typeConstDefs.putWord (typeId); + m_typeConstDefs.putWord (resultId); + m_typeConstDefs.putInt32(v); return resultId; } @@ -154,10 +164,10 @@ namespace dxvk { uint32_t typeId = this->defIntType(64, 0); uint32_t resultId = this->allocateId(); - m_constDefs.putIns (spv::OpConstant, 5); - m_constDefs.putWord (typeId); - m_constDefs.putWord (resultId); - m_constDefs.putInt64(v); + m_typeConstDefs.putIns (spv::OpConstant, 5); + m_typeConstDefs.putWord (typeId); + m_typeConstDefs.putWord (resultId); + m_typeConstDefs.putInt64(v); return resultId; } @@ -167,10 +177,10 @@ namespace dxvk { uint32_t typeId = this->defFloatType(32); uint32_t resultId = this->allocateId(); - m_constDefs.putIns (spv::OpConstant, 4); - m_constDefs.putWord (typeId); - m_constDefs.putWord (resultId); - m_constDefs.putFloat32(v); + m_typeConstDefs.putIns (spv::OpConstant, 4); + m_typeConstDefs.putWord (typeId); + m_typeConstDefs.putWord (resultId); + m_typeConstDefs.putFloat32(v); return resultId; } @@ -180,10 +190,10 @@ namespace dxvk { uint32_t typeId = this->defFloatType(64); uint32_t resultId = this->allocateId(); - m_constDefs.putIns (spv::OpConstant, 5); - m_constDefs.putWord (typeId); - m_constDefs.putWord (resultId); - m_constDefs.putFloat64(v); + m_typeConstDefs.putIns (spv::OpConstant, 5); + m_typeConstDefs.putWord (typeId); + m_typeConstDefs.putWord (resultId); + m_typeConstDefs.putFloat64(v); return resultId; } @@ -194,16 +204,23 @@ namespace dxvk { const uint32_t* constIds) { uint32_t resultId = this->allocateId(); - m_constDefs.putIns (spv::OpConstantComposite, 3 + constCount); - m_constDefs.putWord (typeId); - m_constDefs.putWord (resultId); + m_typeConstDefs.putIns (spv::OpConstantComposite, 3 + constCount); + m_typeConstDefs.putWord (typeId); + m_typeConstDefs.putWord (resultId); for (uint32_t i = 0; i < constCount; i++) - m_constDefs.putWord(constIds[i]); + m_typeConstDefs.putWord(constIds[i]); return resultId; } + void SpirvModule::decorateBlock(uint32_t object) { + m_annotations.putIns (spv::OpDecorate, 3); + m_annotations.putWord (object); + m_annotations.putWord (spv::DecorationBlock); + } + + void SpirvModule::decorateBuiltIn( uint32_t object, spv::BuiltIn builtIn) { @@ -234,6 +251,18 @@ namespace dxvk { } + void SpirvModule::memberDecorateBuiltIn( + uint32_t structId, + uint32_t memberId, + spv::BuiltIn builtIn) { + m_annotations.putIns (spv::OpMemberDecorate, 5); + m_annotations.putWord (structId); + m_annotations.putWord (memberId); + m_annotations.putWord (spv::DecorationBuiltIn); + m_annotations.putWord (builtIn); + } + + uint32_t SpirvModule::defVoidType() { return this->defType(spv::OpTypeVoid, 0, nullptr); } @@ -493,7 +522,7 @@ namespace dxvk { // Since the type info is stored in the code buffer, // we can use the code buffer to look up type IDs as // well. Result IDs are always stored as argument 1. - for (auto ins : m_typeDefs) { + for (auto ins : m_typeConstDefs) { bool match = ins.opCode() == op; for (uint32_t i = 0; i < argCount && match; i++) @@ -505,11 +534,11 @@ namespace dxvk { // Type not yet declared, create a new one. uint32_t resultId = this->allocateId(); - m_typeDefs.putIns (op, 2 + argCount); - m_typeDefs.putWord(resultId); + m_typeConstDefs.putIns (op, 2 + argCount); + m_typeConstDefs.putWord(resultId); for (uint32_t i = 0; i < argCount; i++) - m_typeDefs.putWord(argIds[i]); + m_typeConstDefs.putWord(argIds[i]); return resultId; } diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index a685878d..97c39c18 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -50,6 +50,11 @@ namespace dxvk { uint32_t expressionId, const char* debugName); + void setDebugMemberName( + uint32_t structId, + uint32_t memberId, + const char* debugName); + uint32_t constBool( bool v); @@ -76,6 +81,9 @@ namespace dxvk { uint32_t constCount, const uint32_t* constIds); + void decorateBlock( + uint32_t object); + void decorateBuiltIn( uint32_t object, spv::BuiltIn builtIn); @@ -88,6 +96,11 @@ namespace dxvk { uint32_t object, uint32_t location); + void memberDecorateBuiltIn( + uint32_t structId, + uint32_t memberId, + spv::BuiltIn builtIn); + uint32_t defVoidType(); uint32_t defBoolType(); @@ -188,8 +201,7 @@ namespace dxvk { SpirvCodeBuffer m_execModeInfo; SpirvCodeBuffer m_debugNames; SpirvCodeBuffer m_annotations; - SpirvCodeBuffer m_typeDefs; - SpirvCodeBuffer m_constDefs; + SpirvCodeBuffer m_typeConstDefs; SpirvCodeBuffer m_variables; SpirvCodeBuffer m_code;