diff --git a/src/dxbc/dxbc_chunk_isgn.cpp b/src/dxbc/dxbc_chunk_isgn.cpp new file mode 100644 index 000000000..b4c088391 --- /dev/null +++ b/src/dxbc/dxbc_chunk_isgn.cpp @@ -0,0 +1,39 @@ +#include "dxbc_chunk_isgn.h" + +namespace dxvk { + + DxbcIsgn::DxbcIsgn(DxbcReader reader) { + uint32_t elementCount = reader.readu32(); + reader.skip(sizeof(uint32_t)); + + std::array componentTypes = { + DxbcScalarType::Uint32, DxbcScalarType::Uint32, + DxbcScalarType::Sint32, DxbcScalarType::Float32, + }; + + for (uint32_t i = 0; i < elementCount; i++) { + DxbcSgnEntry entry; + entry.semanticName = reader.clone(reader.readu32()).readString(); + entry.semanticIndex = reader.readu32(); + entry.systemValue = static_cast(reader.readu32()); + entry.componentType = componentTypes.at(reader.readu32()); + entry.registerId = reader.readu32(); + entry.componentMask = bit::extract(reader.readu32(), 0, 3); + + Logger::info(str::format( + entry.semanticName, ",", + entry.semanticIndex, ",", + entry.systemValue, ",", +// entry.componentType, ",", + entry.registerId)); + + m_entries.push_back(entry); + } + } + + + DxbcIsgn::~DxbcIsgn() { + + } + +} \ No newline at end of file diff --git a/src/dxbc/dxbc_chunk_isgn.h b/src/dxbc/dxbc_chunk_isgn.h new file mode 100644 index 000000000..2e2084eda --- /dev/null +++ b/src/dxbc/dxbc_chunk_isgn.h @@ -0,0 +1,45 @@ +#pragma once + +#include "dxbc_common.h" +#include "dxbc_decoder.h" +#include "dxbc_enums.h" +#include "dxbc_reader.h" +#include "dxbc_type.h" + +namespace dxvk { + + /** + * \brief Signature entry + * + * Stores the semantic name of an input or + * output and the corresponding register. + */ + struct DxbcSgnEntry { + std::string semanticName; + uint32_t semanticIndex; + uint32_t registerId; + DxbcComponentMask componentMask; + DxbcScalarType componentType; + DxbcSystemValue systemValue; + }; + + /** + * \brief Input/Output signature chunk + * + * Stores information about the input and + * output registers used by the shader stage. + */ + class DxbcIsgn : public RcObject { + + public: + + DxbcIsgn(DxbcReader reader); + ~DxbcIsgn(); + + private: + + std::vector m_entries; + + }; + +} \ No newline at end of file diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 9b79b4102..4349d66ef 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -2,8 +2,13 @@ namespace dxvk { - DxbcCompiler::DxbcCompiler(DxbcProgramVersion version) - : m_version(version) { + DxbcCompiler::DxbcCompiler( + DxbcProgramVersion version, + const Rc& inputSig, + const Rc& outputSig) + : m_version (version), + m_inputSig (inputSig), + m_outputSig (outputSig) { m_entryPointId = m_module.allocateId(); this->declareCapabilities(); @@ -15,6 +20,9 @@ namespace dxvk { m_module.functionBegin(m_typeVoid, m_entryPointId, m_typeFunction, spv::FunctionControlMaskNone); + + // TODO implement proper control flow + m_module.opLabel(m_module.allocateId()); } @@ -23,31 +31,33 @@ namespace dxvk { } - bool DxbcCompiler::processInstruction(const DxbcInstruction& ins) { + void DxbcCompiler::processInstruction(const DxbcInstruction& ins) { const DxbcOpcodeToken token = ins.token(); switch (token.opcode()) { case DxbcOpcode::DclGlobalFlags: - return this->dclGlobalFlags(token.control()); - + return this->dclGlobalFlags(ins); + case DxbcOpcode::DclInput: return this->dclInput(ins); - case DxbcOpcode::DclTemps: - return this->dclTemps(ins.arg(0)); + case DxbcOpcode::DclOutputSiv: + return this->dclOutputSiv(ins); - case DxbcOpcode::DclThreadGroup: { - m_module.setLocalSize( - m_entryPointId, - ins.arg(0), - ins.arg(1), - ins.arg(2)); - } return true; + case DxbcOpcode::DclTemps: + return this->dclTemps(ins); + + case DxbcOpcode::DclThreadGroup: + return this->dclThreadGroup(ins); + + case DxbcOpcode::Mov: + return this->opMov(ins); + + case DxbcOpcode::Ret: + return this->opRet(ins); default: - Logger::err(str::format("DXBC: unhandled instruction: ", - static_cast(token.opcode()))); - return false; + throw DxvkError(str::format("DXBC: Unhandled instruction: ", ins.token().opcode())); } } @@ -91,7 +101,9 @@ namespace dxvk { } - bool DxbcCompiler::dclGlobalFlags(DxbcGlobalFlags flags) { + void DxbcCompiler::dclGlobalFlags(const DxbcInstruction& ins) { + const DxbcGlobalFlags flags(ins.token().control()); + if (!flags.test(DxbcGlobalFlag::RefactoringAllowed)) m_useRestrictedMath = true; @@ -103,37 +115,167 @@ namespace dxvk { // Raw and structured buffers are supported regardless // of whether the corresponding flag is set or not. - return true; } - bool DxbcCompiler::dclInput(const DxbcInstruction& ins) { -// const DxbcOperand operand = ins.operand(0); -// const DxbcOperandToken token = operand.token(); + void DxbcCompiler::dclInput(const DxbcInstruction& ins) { + const DxbcOperand operand = ins.operand(0); + const DxbcOperandToken token = operand.token(); - Logger::err("DXBC: dcl_input: Not implemented yet"); - return false; } - bool DxbcCompiler::dclTemps(uint32_t n) { + void DxbcCompiler::dclOutputSiv(const DxbcInstruction& ins) { + Logger::err("DXBC: dclOutputSiv: Not implemented yet"); + } + + + void DxbcCompiler::dclTemps(const DxbcInstruction& ins) { // Temporaries are treated as untyped 4x32-bit vectors. - uint32_t u32Type = m_module.defIntType(32, 0); - uint32_t regType = m_module.defVectorType(u32Type, 4); - uint32_t ptrType = m_module.defPointerType(regType, spv::StorageClassPrivate); + const DxbcValueType regType(DxbcScalarType::Uint32, 4); + const DxbcPointerType ptrType(regType, spv::StorageClassPrivate); + const uint32_t ptrTypeId = this->getPointerTypeId(ptrType); - for (uint32_t i = 0; i < n; i++) { - DxbcRegTypeR reg; - reg.varType = regType; - reg.ptrType = ptrType; - reg.varId = m_module.newVar(ptrType, spv::StorageClassPrivate); + for (uint32_t i = 0; i < ins.arg(0); i++) { + DxbcPointer reg; + reg.type = ptrType; + reg.typeId = ptrTypeId; + reg.valueId = m_module.newVar(ptrTypeId, spv::StorageClassPrivate); m_rRegs.push_back(reg); - m_module.setDebugName(reg.varId, + m_module.setDebugName(reg.valueId, str::format("r", i).c_str()); } + } + + + void DxbcCompiler::dclThreadGroup(const DxbcInstruction& ins) { + m_module.setLocalSize(m_entryPointId, + ins.arg(0), ins.arg(1), ins.arg(2)); + } + + + void DxbcCompiler::opMov(const DxbcInstruction& ins) { + const DxbcOperand dstOp = ins.operand(0); + const DxbcOperand srcOp = ins.operand(dstOp.length()); + + DxbcValueType dstType(DxbcScalarType::Uint32, 1); + this->loadOperand(srcOp, dstType); + + Logger::err("DXBC: mov: Not implemented yet"); + } + + + void DxbcCompiler::opRet(const DxbcInstruction& ins) { + // TODO implement proper control flow + m_module.opReturn(); + } + + + uint32_t DxbcCompiler::getScalarTypeId(const 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); + } + + throw DxvkError("DXBC: Invalid scalar type"); + } + + + uint32_t DxbcCompiler::getValueTypeId(const DxbcValueType& type) { + const uint32_t scalarTypeId = this->getScalarTypeId(type.componentType); + + return type.componentCount > 1 + ? m_module.defVectorType(scalarTypeId, type.componentCount) + : scalarTypeId; + } + + + uint32_t DxbcCompiler::getPointerTypeId(const DxbcPointerType& type) { + return m_module.defPointerType( + this->getValueTypeId(type.valueType), + type.storageClass); + } + + + DxbcValue DxbcCompiler::loadPointer(const DxbcPointer& pointer) { + DxbcValue result; + result.type = pointer.type.valueType; + result.typeId = this->getValueTypeId(result.type); + result.valueId = m_module.opLoad(result.typeId, pointer.valueId); + return result; + } + + + DxbcValue DxbcCompiler::loadOperand( + const DxbcOperand& operand, + const DxbcValueType& type) { + const DxbcOperandToken token = operand.token(); + + DxbcValue result; + + switch (token.type()) { + + case DxbcOperandType::Imm32: { + const uint32_t componentCount = token.numComponents(); + + result.type = DxbcValueType(DxbcScalarType::Uint32, componentCount); + result.typeId = this->getValueTypeId(result.type); + + if (componentCount == 1) { + result.valueId = m_module.constu32(operand.imm32(0)); + } else { + std::array constIds; + + for (uint32_t i = 0; i < componentCount; i++) + constIds.at(i) = m_module.constu32(operand.imm32(i)); + + result.valueId = m_module.constComposite( + result.typeId, componentCount, constIds.data()); + } + } break; + + case DxbcOperandType::Temp: { + const DxbcOperandIndex index = operand.index(0); + result = this->loadPointer(m_rRegs.at(index.immPart())); + } break; + + case DxbcOperandType::Input: { + const DxbcOperandIndex index = operand.index(0); + result = this->loadPointer(m_vRegs.at(index.immPart())); + } break; + + case DxbcOperandType::Output: { + const DxbcOperandIndex index = operand.index(0); + result = this->loadPointer(m_oRegs.at(index.immPart())); + } break; + + default: + throw DxvkError(str::format( + "DxbcCompiler::loadOperandRegister: Unhandled operand type: ", + token.type())); + } + + return result; + } + + + void DxbcCompiler::storePointer( + const DxbcPointer& pointer, + const DxbcValue& value) { + m_module.opStore(pointer.valueId, value.valueId); + } + + + void DxbcCompiler::storeOperand( + const DxbcOperand& operand, + const DxbcValueType& srcType, + uint32_t srcValue) { - return true; } } \ No newline at end of file diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index b1d5708e4..514561678 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -1,44 +1,25 @@ #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" namespace dxvk { - struct DxbcRegTypeR { - uint32_t varType; - uint32_t ptrType; - uint32_t varId; - }; - - - struct DxbcValueType { - spv::Op componentType = spv::OpTypeVoid; - uint32_t componentWidth = 0; - uint32_t componentSigned = 0; - uint32_t componentCount = 0; - }; - - - struct DxbcValue { - DxbcValueType type; - uint32_t typeId; - uint32_t valueId; - }; - - /** * \brief DXBC to SPIR-V compiler - * - * */ class DxbcCompiler { public: - DxbcCompiler(DxbcProgramVersion version); + DxbcCompiler( + DxbcProgramVersion version, + const Rc& inputSig, + const Rc& outputSig); ~DxbcCompiler(); DxbcCompiler (DxbcCompiler&&) = delete; @@ -50,7 +31,7 @@ namespace dxvk { * \param [in] ins The instruction * \returns \c true on success */ - bool processInstruction( + void processInstruction( const DxbcInstruction& ins); /** @@ -66,8 +47,13 @@ namespace dxvk { DxbcProgramVersion m_version; SpirvModule m_module; + Rc m_inputSig; + Rc m_outputSig; + std::vector m_interfaces; - std::vector m_rRegs; + std::vector m_rRegs; // Temps + std::vector m_vRegs; // Input registers + std::vector m_oRegs; // Output registers uint32_t m_entryPointId = 0; @@ -76,13 +62,37 @@ namespace dxvk { bool m_useRestrictedMath = false; - void declareCapabilities(); void declareMemoryModel(); - bool dclGlobalFlags(DxbcGlobalFlags flags); - bool dclInput(const DxbcInstruction& ins); - bool dclTemps(uint32_t n); + void dclGlobalFlags(const DxbcInstruction& ins); + void dclInput(const DxbcInstruction& ins); + void dclOutputSiv(const DxbcInstruction& ins); + void dclTemps(const DxbcInstruction& ins); + void dclThreadGroup(const DxbcInstruction& ins); + + void opMov(const DxbcInstruction& ins); + void opRet(const DxbcInstruction& ins); + + uint32_t getScalarTypeId(const DxbcScalarType& type); + uint32_t getValueTypeId(const DxbcValueType& type); + uint32_t getPointerTypeId(const DxbcPointerType& type); + + DxbcValue loadPointer( + const DxbcPointer& pointer); + + DxbcValue loadOperand( + const DxbcOperand& operand, + const DxbcValueType& type); + + void storePointer( + const DxbcPointer& pointer, + const DxbcValue& value); + + void storeOperand( + const DxbcOperand& operand, + const DxbcValueType& srcType, + uint32_t srcValue); }; diff --git a/src/dxbc/dxbc_decoder.cpp b/src/dxbc/dxbc_decoder.cpp index 707415dc9..de99958a9 100644 --- a/src/dxbc/dxbc_decoder.cpp +++ b/src/dxbc/dxbc_decoder.cpp @@ -114,16 +114,10 @@ namespace dxvk { // Immediate operands uint32_t length = 0; - uint32_t componentCount = 0; - switch (token.numComponents()) { - case DxbcOperandNumComponents::Component0: componentCount = 0; break; - case DxbcOperandNumComponents::Component1: componentCount = 1; break; - case DxbcOperandNumComponents::Component4: componentCount = 4; break; - } - - if (token.type() == DxbcOperandType::Imm32) length += 1 * componentCount; - if (token.type() == DxbcOperandType::Imm64) length += 2 * componentCount; + if (token.type() == DxbcOperandType::Imm32 + || token.type() == DxbcOperandType::Imm64) + length += token.numComponents(); // Indices into the register file, may contain additional operands for (uint32_t i = 0; i < token.indexDimension(); i++) { diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index d9b37d4b5..21b1e019d 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -10,6 +10,21 @@ namespace dxvk { class DxbcOperand; + /** + * \brief Component swizzle + */ + struct DxbcComponentSwizzle { + DxbcComponentName x; + DxbcComponentName y; + DxbcComponentName z; + DxbcComponentName w; + }; + + /** + * \brief Component mask + */ + using DxbcComponentMask = Flags; + /** * \brief DXBC instruction token * @@ -161,9 +176,9 @@ namespace dxvk { * has. Can be zero, one, or four. * \returns Number of components */ - DxbcOperandNumComponents numComponents() const { - return static_cast( - bit::extract(m_token, 0, 1)); + uint32_t numComponents() const { + std::array count = { 0, 1, 4 }; + return count.at(bit::extract(m_token, 0, 1)); } /** @@ -174,11 +189,48 @@ namespace dxvk { * a given set of components is used. * \returns Component selection mode */ - DxbcOperandComponentSelectionMode selectionMode() const { - return static_cast( + DxbcComponentSelectionMode selectionMode() const { + return static_cast( bit::extract(m_token, 2, 3)); } + /** + * \brief Component mask + * + * Used when the component selection mode is + * \c DxbcComponentSelectionMode::Mask. + * \returns The component mask + */ + DxbcComponentMask componentMask() const { + return DxbcComponentMask(bit::extract(m_token, 4, 7)); + } + + /** + * \brief Component swizzle + * + * Used when the component selection mode is + * \c DxbcComponentSelectionMode::Swizzle. + * \returns The component swizzle + */ + DxbcComponentSwizzle componentSwizzle() const { + return DxbcComponentSwizzle { + static_cast(bit::extract(m_token, 4, 5)), + static_cast(bit::extract(m_token, 6, 7)), + static_cast(bit::extract(m_token, 8, 9)), + static_cast(bit::extract(m_token, 10, 11)) }; + } + + /** + * \brief Component selection + * + * Used when the component selection mode is + * \c DxbcComponentSelectionMode::Select1. + */ + DxbcComponentName componentSelection() const { + return static_cast( + bit::extract(m_token, 4, 5)); + } + /** * \brief Operand type * @@ -404,6 +456,28 @@ namespace dxvk { std::optional queryOperandExt( DxbcOperandExt ext) const; + /** + * \brief Reads 32-bit immediate integer + * + * \param [in] idx Component index + * \returns The immediate operand + */ + uint32_t imm32(uint32_t idx) const { + return m_data.getWord(idx); + } + + /** + * \brief Reads 64-bit immediate integer + * + * \param [in] idx Component index + * \returns The immediate operand + */ + uint64_t imm64(uint32_t idx) const { + uint64_t hi = m_data.getWord(2 * idx + 0); + uint64_t lo = m_data.getWord(2 * idx + 1); + return (hi << 32) | (lo); + } + private: DxbcCodeReader m_info; diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index 750121252..7db82b37a 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -164,9 +164,9 @@ namespace dxvk { DclHsForkPhaseInstanceCount = 153, DclHsJoinPhaseInstanceCount = 154, DclThreadGroup = 155, - DclUnorderedAccessViewTyped = 156, - DclUnorderedAccessViewRaw = 157, - DclUnorderedAccessViewStructured = 158, + DclUavTyped = 156, + DclUavRaw = 157, + DclUavStructured = 158, DclThreadGroupSharedMemoryRaw = 159, DclThreadGroupSharedMemoryStructured = 160, DclResourceRaw = 161, @@ -286,7 +286,7 @@ namespace dxvk { * Used by operands to determine whether the * operand has one, four or zero components. */ - enum class DxbcOperandNumComponents : uint32_t { + enum class DxbcComponentCount : uint32_t { Component0 = 0, Component1 = 1, Component4 = 2, @@ -300,7 +300,7 @@ namespace dxvk { * component selection mode deterines which * components are used for the operation. */ - enum class DxbcOperandComponentSelectionMode : uint32_t { + enum class DxbcComponentSelectionMode : uint32_t { Mask = 0, Swizzle = 1, Select1 = 2, @@ -311,7 +311,7 @@ namespace dxvk { * \brief Component name * Used for component selection. */ - enum class DxbcOperandComponentName : uint32_t { + enum class DxbcComponentName : uint32_t { X = 0, Y = 1, Z = 2, W = 3, }; @@ -398,6 +398,32 @@ namespace dxvk { }; + enum class DxbcSystemValue : uint32_t { + None = 0, + Position = 1, + ClipDistance = 2, + CullDistance = 3, + RenderTargetId = 4, + ViewportId = 5, + VertexId = 6, + PrimitiveId = 7, + InstanceId = 8, + IsFrontFace = 9, + SampleIndex = 10, + FinalQuadEdgeTessFactor = 11, + FinalQuadInsideTessFactor = 12, + FinalTriEdgeTessFactor = 13, + FinalTriInsideTessFactor = 14, + FinalLineDetailTessFactor = 15, + FinalLineDensityTessFactor = 16, + Target = 64, + Depth = 65, + Coverage = 66, + DepthGe = 67, + DepthLe = 68 + }; + + enum class DxbcGlobalFlag : uint32_t { RefactoringAllowed = 0, DoublePrecision = 1, diff --git a/src/dxbc/dxbc_module.cpp b/src/dxbc/dxbc_module.cpp index 0461575be..256cebc18 100644 --- a/src/dxbc/dxbc_module.cpp +++ b/src/dxbc/dxbc_module.cpp @@ -14,12 +14,23 @@ namespace dxvk { // The chunk size follows right after the four-character // code. This does not include the eight bytes that are // consumed by the FourCC and chunk length entry. - auto chunkLength = chunkReader.readu32() + 8; - chunkReader = chunkReader.resize(chunkLength); + auto chunkLength = chunkReader.readu32(); + + chunkReader = chunkReader.clone(8); + chunkReader = chunkReader.resize(chunkLength); if ((tag == "SHDR") || (tag == "SHEX")) m_shexChunk = new DxbcShex(chunkReader); + if ((tag == "ISGN")) + m_isgnChunk = new DxbcIsgn(chunkReader); + + if ((tag == "OSGN")) + m_osgnChunk = new DxbcIsgn(chunkReader); + +// if ((tag == "OSG5")) +// m_osgnChunk = new DxbcIsgn(chunkReader); + } } @@ -33,7 +44,7 @@ namespace dxvk { if (m_shexChunk == nullptr) throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk"); - DxbcCompiler compiler(m_shexChunk->version()); + DxbcCompiler compiler(m_shexChunk->version(), m_isgnChunk, m_osgnChunk); for (auto ins : *m_shexChunk) compiler.processInstruction(ins); diff --git a/src/dxbc/dxbc_module.h b/src/dxbc/dxbc_module.h index bb0eb3d29..4c23fbf59 100644 --- a/src/dxbc/dxbc_module.h +++ b/src/dxbc/dxbc_module.h @@ -2,6 +2,7 @@ #include "../dxvk/dxvk_shader.h" +#include "dxbc_chunk_isgn.h" #include "dxbc_chunk_shex.h" #include "dxbc_header.h" #include "dxbc_reader.h" @@ -36,6 +37,8 @@ namespace dxvk { DxbcHeader m_header; + Rc m_isgnChunk; + Rc m_osgnChunk; Rc m_shexChunk; }; diff --git a/src/dxbc/dxbc_names.cpp b/src/dxbc/dxbc_names.cpp index 023b29606..45ece7770 100644 --- a/src/dxbc/dxbc_names.cpp +++ b/src/dxbc/dxbc_names.cpp @@ -160,9 +160,9 @@ std::ostream& operator << (std::ostream& os, DxbcOpcode e) { ENUM_NAME(DxbcOpcode::DclHsForkPhaseInstanceCount); ENUM_NAME(DxbcOpcode::DclHsJoinPhaseInstanceCount); ENUM_NAME(DxbcOpcode::DclThreadGroup); - ENUM_NAME(DxbcOpcode::DclUnorderedAccessViewTyped); - ENUM_NAME(DxbcOpcode::DclUnorderedAccessViewRaw); - ENUM_NAME(DxbcOpcode::DclUnorderedAccessViewStructured); + ENUM_NAME(DxbcOpcode::DclUavTyped); + ENUM_NAME(DxbcOpcode::DclUavRaw); + ENUM_NAME(DxbcOpcode::DclUavStructured); ENUM_NAME(DxbcOpcode::DclThreadGroupSharedMemoryRaw); ENUM_NAME(DxbcOpcode::DclThreadGroupSharedMemoryStructured); ENUM_NAME(DxbcOpcode::DclResourceRaw); @@ -275,32 +275,32 @@ std::ostream& operator << (std::ostream& os, DxbcOperandType e) { } -std::ostream& operator << (std::ostream& os, DxbcOperandNumComponents e) { +std::ostream& operator << (std::ostream& os, DxbcComponentCount e) { switch (e) { - ENUM_NAME(DxbcOperandNumComponents::Component0); - ENUM_NAME(DxbcOperandNumComponents::Component1); - ENUM_NAME(DxbcOperandNumComponents::Component4); + ENUM_NAME(DxbcComponentCount::Component0); + ENUM_NAME(DxbcComponentCount::Component1); + ENUM_NAME(DxbcComponentCount::Component4); ENUM_DEFAULT(e); } } -std::ostream& operator << (std::ostream& os, DxbcOperandComponentSelectionMode e) { +std::ostream& operator << (std::ostream& os, DxbcComponentSelectionMode e) { switch (e) { - ENUM_NAME(DxbcOperandComponentSelectionMode::Mask); - ENUM_NAME(DxbcOperandComponentSelectionMode::Swizzle); - ENUM_NAME(DxbcOperandComponentSelectionMode::Select1); + ENUM_NAME(DxbcComponentSelectionMode::Mask); + ENUM_NAME(DxbcComponentSelectionMode::Swizzle); + ENUM_NAME(DxbcComponentSelectionMode::Select1); ENUM_DEFAULT(e); } } -std::ostream& operator << (std::ostream& os, DxbcOperandComponentName e) { +std::ostream& operator << (std::ostream& os, DxbcComponentName e) { switch (e) { - ENUM_NAME(DxbcOperandComponentName::X); - ENUM_NAME(DxbcOperandComponentName::Y); - ENUM_NAME(DxbcOperandComponentName::Z); - ENUM_NAME(DxbcOperandComponentName::W); + ENUM_NAME(DxbcComponentName::X); + ENUM_NAME(DxbcComponentName::Y); + ENUM_NAME(DxbcComponentName::Z); + ENUM_NAME(DxbcComponentName::W); ENUM_DEFAULT(e); } } @@ -372,3 +372,32 @@ std::ostream& operator << (std::ostream& os, DxbcInstructionReturnType e) { ENUM_DEFAULT(e); } } + + +std::ostream& operator << (std::ostream& os, DxbcSystemValue e) { + switch (e) { + ENUM_NAME(DxbcSystemValue::None); + ENUM_NAME(DxbcSystemValue::Position); + ENUM_NAME(DxbcSystemValue::ClipDistance); + ENUM_NAME(DxbcSystemValue::CullDistance); + ENUM_NAME(DxbcSystemValue::RenderTargetId); + ENUM_NAME(DxbcSystemValue::ViewportId); + ENUM_NAME(DxbcSystemValue::VertexId); + ENUM_NAME(DxbcSystemValue::PrimitiveId); + ENUM_NAME(DxbcSystemValue::InstanceId); + ENUM_NAME(DxbcSystemValue::IsFrontFace); + ENUM_NAME(DxbcSystemValue::SampleIndex); + ENUM_NAME(DxbcSystemValue::FinalQuadEdgeTessFactor); + ENUM_NAME(DxbcSystemValue::FinalQuadInsideTessFactor); + ENUM_NAME(DxbcSystemValue::FinalTriEdgeTessFactor); + ENUM_NAME(DxbcSystemValue::FinalTriInsideTessFactor); + ENUM_NAME(DxbcSystemValue::FinalLineDetailTessFactor); + ENUM_NAME(DxbcSystemValue::FinalLineDensityTessFactor); + ENUM_NAME(DxbcSystemValue::Target); + ENUM_NAME(DxbcSystemValue::Depth); + ENUM_NAME(DxbcSystemValue::Coverage); + ENUM_NAME(DxbcSystemValue::DepthGe); + ENUM_NAME(DxbcSystemValue::DepthLe); + ENUM_DEFAULT(e); + } +} diff --git a/src/dxbc/dxbc_names.h b/src/dxbc/dxbc_names.h index 2584d0140..cc3bb8000 100644 --- a/src/dxbc/dxbc_names.h +++ b/src/dxbc/dxbc_names.h @@ -7,11 +7,12 @@ std::ostream& operator << (std::ostream& os, dxvk::DxbcOpcode e); std::ostream& operator << (std::ostream& os, dxvk::DxbcExtOpcode e); std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandType e); -std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandNumComponents e); -std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandComponentSelectionMode e); -std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandComponentName e); +std::ostream& operator << (std::ostream& os, dxvk::DxbcComponentCount e); +std::ostream& operator << (std::ostream& os, dxvk::DxbcComponentSelectionMode e); +std::ostream& operator << (std::ostream& os, dxvk::DxbcComponentName e); std::ostream& operator << (std::ostream& os, dxvk::DxbcOperandIndexRepresentation e); std::ostream& operator << (std::ostream& os, dxvk::DxbcResourceDim e); 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); diff --git a/src/dxbc/dxbc_type.h b/src/dxbc/dxbc_type.h new file mode 100644 index 000000000..c799c2244 --- /dev/null +++ b/src/dxbc/dxbc_type.h @@ -0,0 +1,104 @@ +#pragma once + +#include "dxbc_include.h" + +namespace dxvk { + + /** + * \brief Scalar value type + * + * Enumerates possible register component + * types. Scalar types are represented as + * a one-component vector type. + */ + enum class DxbcScalarType { + Uint32 = 0, + Uint64 = 1, + Sint32 = 2, + Sint64 = 3, + Float32 = 4, + Float64 = 5, + }; + + + /** + * \brief Vector value type + * + * Vector type definition that stores the scalar + * component type and the number of components. + */ + struct DxbcValueType { + DxbcValueType() { } + DxbcValueType(DxbcScalarType s, uint32_t c) + : componentType(s), componentCount(c) { } + + DxbcScalarType componentType = DxbcScalarType::Uint32; + uint32_t componentCount = 0; + }; + + + /** + * \brief Value + * + * Stores the type and SPIR-V ID of an expression + * 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; + }; + + + /** + * \brief Pointer type + * + * Stores the type of data that the pointer will + * point to, as well as the storage class of the + * SPIR-V object. + */ + struct DxbcPointerType { + DxbcPointerType() { } + DxbcPointerType( + DxbcValueType p_valueType, + spv::StorageClass p_storageClass) + : valueType (p_valueType), + storageClass(p_storageClass) { } + + DxbcValueType valueType; + spv::StorageClass storageClass = spv::StorageClassGeneric; + }; + + + /** + * \brief Pointer + * + * Stores the SPIR-V ID of a pointer value and + * the type of the pointer, including its storage + * 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; + }; + +} \ No newline at end of file diff --git a/src/dxbc/meson.build b/src/dxbc/meson.build index fe91536df..633685c95 100644 --- a/src/dxbc/meson.build +++ b/src/dxbc/meson.build @@ -1,4 +1,5 @@ dxbc_src = files([ + 'dxbc_chunk_isgn.cpp', 'dxbc_chunk_shex.cpp', 'dxbc_common.cpp', 'dxbc_compiler.cpp',