From bc8cc76888d4d336d57409e124fe6d9dd20c1188 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 29 Oct 2017 02:35:16 +0200 Subject: [PATCH] [dxbc] Added operand index decoder, entry point declaration --- src/dxbc/dxbc_compiler.cpp | 46 ++++- src/dxbc/dxbc_compiler.h | 25 ++- src/dxbc/dxbc_decoder.cpp | 104 ++++++++++- src/dxbc/dxbc_decoder.h | 61 +++++- src/dxbc/dxbc_enums.h | 10 + src/dxbc/dxbc_names.cpp | 374 +++++++++++++++++++++++++++++++++++++ src/dxbc/dxbc_names.h | 17 ++ src/dxbc/meson.build | 1 + src/spirv/spirv_module.cpp | 19 +- src/spirv/spirv_module.h | 2 +- src/util/util_enum.h | 4 +- src/util/util_flags.h | 3 + 12 files changed, 640 insertions(+), 26 deletions(-) create mode 100644 src/dxbc/dxbc_names.cpp create mode 100644 src/dxbc/dxbc_names.h diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index e8c28b6f..9b79b410 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -27,9 +27,14 @@ namespace dxvk { const DxbcOpcodeToken token = ins.token(); switch (token.opcode()) { - case DxbcOpcode::DclTemps: { - this->dclTemps(ins.arg(0)); - } return true; + case DxbcOpcode::DclGlobalFlags: + return this->dclGlobalFlags(token.control()); + + case DxbcOpcode::DclInput: + return this->dclInput(ins); + + case DxbcOpcode::DclTemps: + return this->dclTemps(ins.arg(0)); case DxbcOpcode::DclThreadGroup: { m_module.setLocalSize( @@ -50,6 +55,11 @@ namespace dxvk { Rc DxbcCompiler::finalize() { m_module.functionEnd(); + m_module.addEntryPoint(m_entryPointId, + m_version.executionModel(), "main", + m_interfaces.size(), + m_interfaces.data()); + return new DxvkShader(m_version.shaderStage(), m_module.compile(), 0, nullptr); } @@ -80,7 +90,33 @@ namespace dxvk { spv::MemoryModelGLSL450); } - void DxbcCompiler::dclTemps(uint32_t n) { + + bool DxbcCompiler::dclGlobalFlags(DxbcGlobalFlags flags) { + if (!flags.test(DxbcGlobalFlag::RefactoringAllowed)) + m_useRestrictedMath = true; + + if (flags.test(DxbcGlobalFlag::DoublePrecision)) + m_module.enableCapability(spv::CapabilityFloat64); + + if (flags.test(DxbcGlobalFlag::EarlyFragmentTests)) + m_module.enableEarlyFragmentTests(m_entryPointId); + + // 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(); + + Logger::err("DXBC: dcl_input: Not implemented yet"); + return false; + } + + + bool DxbcCompiler::dclTemps(uint32_t n) { // Temporaries are treated as untyped 4x32-bit vectors. uint32_t u32Type = m_module.defIntType(32, 0); uint32_t regType = m_module.defVectorType(u32Type, 4); @@ -96,6 +132,8 @@ namespace dxvk { m_module.setDebugName(reg.varId, str::format("r", i).c_str()); } + + return true; } } \ No newline at end of file diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 3500491c..b1d5708e 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -1,6 +1,7 @@ #pragma once #include "dxbc_chunk_shex.h" +#include "dxbc_names.h" #include "../spirv/spirv_module.h" @@ -12,6 +13,22 @@ namespace dxvk { 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 * @@ -49,6 +66,7 @@ namespace dxvk { DxbcProgramVersion m_version; SpirvModule m_module; + std::vector m_interfaces; std::vector m_rRegs; uint32_t m_entryPointId = 0; @@ -56,10 +74,15 @@ namespace dxvk { uint32_t m_typeVoid = 0; uint32_t m_typeFunction = 0; + bool m_useRestrictedMath = false; + + void declareCapabilities(); void declareMemoryModel(); - void dclTemps(uint32_t n); + bool dclGlobalFlags(DxbcGlobalFlags flags); + bool dclInput(const DxbcInstruction& ins); + bool dclTemps(uint32_t n); }; diff --git a/src/dxbc/dxbc_decoder.cpp b/src/dxbc/dxbc_decoder.cpp index 50fe221a..707415dc 100644 --- a/src/dxbc/dxbc_decoder.cpp +++ b/src/dxbc/dxbc_decoder.cpp @@ -36,18 +36,109 @@ namespace dxvk { } + uint32_t DxbcOperandIndex::length() const { + switch (m_rep) { + case DxbcOperandIndexRepresentation::Imm32: return 1; + case DxbcOperandIndexRepresentation::Imm64: return 2; + case DxbcOperandIndexRepresentation::Relative: return this->relPart().length(); + case DxbcOperandIndexRepresentation::Imm32Relative: return this->relPart().length() + 1; + case DxbcOperandIndexRepresentation::Imm64Relative: return this->relPart().length() + 2; + } + + throw DxvkError(str::format("DXBC: Unknown index representation: ", m_rep)); + } + + + bool DxbcOperandIndex::hasImmPart() const { + return m_rep == DxbcOperandIndexRepresentation::Imm32 + || m_rep == DxbcOperandIndexRepresentation::Imm64 + || m_rep == DxbcOperandIndexRepresentation::Imm32Relative + || m_rep == DxbcOperandIndexRepresentation::Imm64Relative; + } + + + bool DxbcOperandIndex::hasRelPart() const { + return m_rep == DxbcOperandIndexRepresentation::Relative + || m_rep == DxbcOperandIndexRepresentation::Imm32Relative + || m_rep == DxbcOperandIndexRepresentation::Imm64Relative; + } + + + uint64_t DxbcOperandIndex::immPart() const { + switch (m_rep) { + case DxbcOperandIndexRepresentation::Imm32: + case DxbcOperandIndexRepresentation::Imm32Relative: + return m_code.getWord(0); + + case DxbcOperandIndexRepresentation::Imm64: + case DxbcOperandIndexRepresentation::Imm64Relative: + return (static_cast(m_code.getWord(0)) << 32) + | (static_cast(m_code.getWord(1))); + + default: + return 0; + } + } + + + DxbcOperand DxbcOperandIndex::relPart() const { + switch (m_rep) { + case DxbcOperandIndexRepresentation::Relative: + return DxbcOperand(m_code); + + case DxbcOperandIndexRepresentation::Imm32Relative: + return DxbcOperand(m_code + 1); + + case DxbcOperandIndexRepresentation::Imm64Relative: + return DxbcOperand(m_code + 2); + + default: + throw DxvkError("DXBC: Operand index is not relative"); + } + } + + DxbcOperand::DxbcOperand(const DxbcCodeReader& code) : m_info(code) { - DxbcOperandToken token(m_info.getWord(0)); + const DxbcOperandToken token(m_info.getWord(0)); - uint32_t numOperandTokens = 1; + uint32_t numTokens = 1; + // Count extended operand tokens if (token.isExtended()) { - while (DxbcOperandTokenExt(m_info.getWord(numOperandTokens++)).isExtended()) + while (DxbcOperandTokenExt(m_info.getWord(numTokens++)).isExtended()) continue; } - m_data = m_info + numOperandTokens; + m_data = m_info + numTokens; + + // 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; + + // Indices into the register file, may contain additional operands + for (uint32_t i = 0; i < token.indexDimension(); i++) { + m_indexOffsets[i] = length; + length += this->index(i).length(); + } + + m_length = length + numTokens; + } + + + DxbcOperandIndex DxbcOperand::index(uint32_t dim) const { + return DxbcOperandIndex( + m_data + m_indexOffsets.at(dim), + this->token().indexRepresentation(dim)); } @@ -69,11 +160,6 @@ namespace dxvk { } - uint32_t DxbcOperand::length() const { - - } - - DxbcInstruction::DxbcInstruction(const DxbcCodeReader& code) : m_op(code) { DxbcOpcodeToken token(m_op.getWord(0)); diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 909fc325..d9b37d4b 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -4,9 +4,12 @@ #include #include "dxbc_enums.h" +#include "dxbc_names.h" namespace dxvk { + class DxbcOperand; + /** * \brief DXBC instruction token * @@ -319,6 +322,39 @@ namespace dxvk { }; + /** + * \brief DXBC operand index + * + * Represents an index into an indexable register file. + * For each register file dimension, one operand index + * must be read from the encoded instruction. + */ + class DxbcOperandIndex { + + public: + + DxbcOperandIndex() { } + DxbcOperandIndex( + const DxbcCodeReader& code, + DxbcOperandIndexRepresentation rep) + : m_code(code), m_rep(rep) { } + + uint32_t length() const; + + bool hasImmPart() const; + bool hasRelPart() const; + + uint64_t immPart() const; + DxbcOperand relPart() const; + + private: + + DxbcCodeReader m_code; + DxbcOperandIndexRepresentation m_rep; + + }; + + /** * \brief DXBC operand * @@ -341,6 +377,22 @@ namespace dxvk { return DxbcOperandToken(m_info.getWord(0)); } + /** + * \brief Operand length, in DWORDs + * \returns Number of DWORDs + */ + uint32_t length() const { + return m_length; + } + + /** + * \brief Operand index for a single dimension + * + * \param [in] dim Dimension to query + * \returns Operand index + */ + DxbcOperandIndex index(uint32_t dim) const; + /** * \brief Queries an operand extension * @@ -352,17 +404,14 @@ namespace dxvk { std::optional queryOperandExt( DxbcOperandExt ext) const; - /** - * \brief Operand length, in DWORDs - * \returns Number of DWORDs - */ - uint32_t length() const; - private: DxbcCodeReader m_info; DxbcCodeReader m_data; + uint32_t m_length = 0; + std::array m_indexOffsets = { 0, 0, 0 }; + }; diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index 6d41be1e..75012125 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -397,4 +397,14 @@ namespace dxvk { Uint = 1, }; + + enum class DxbcGlobalFlag : uint32_t { + RefactoringAllowed = 0, + DoublePrecision = 1, + EarlyFragmentTests = 2, + RawStructuredBuffers = 3, + }; + + using DxbcGlobalFlags = Flags; + } \ No newline at end of file diff --git a/src/dxbc/dxbc_names.cpp b/src/dxbc/dxbc_names.cpp new file mode 100644 index 00000000..023b2960 --- /dev/null +++ b/src/dxbc/dxbc_names.cpp @@ -0,0 +1,374 @@ +#include "dxbc_names.h" + +using namespace dxvk; + +std::ostream& operator << (std::ostream& os, DxbcOpcode e) { + switch (e) { + ENUM_NAME(DxbcOpcode::Add); + ENUM_NAME(DxbcOpcode::And); + ENUM_NAME(DxbcOpcode::Break); + ENUM_NAME(DxbcOpcode::Breakc); + ENUM_NAME(DxbcOpcode::Call); + ENUM_NAME(DxbcOpcode::Callc); + ENUM_NAME(DxbcOpcode::Case); + ENUM_NAME(DxbcOpcode::Continue); + ENUM_NAME(DxbcOpcode::Continuec); + ENUM_NAME(DxbcOpcode::Cut); + ENUM_NAME(DxbcOpcode::Default); + ENUM_NAME(DxbcOpcode::DerivRtx); + ENUM_NAME(DxbcOpcode::DerivRty); + ENUM_NAME(DxbcOpcode::Discard); + ENUM_NAME(DxbcOpcode::Div); + ENUM_NAME(DxbcOpcode::Dp2); + ENUM_NAME(DxbcOpcode::Dp3); + ENUM_NAME(DxbcOpcode::Dp4); + ENUM_NAME(DxbcOpcode::Else); + ENUM_NAME(DxbcOpcode::Emit); + ENUM_NAME(DxbcOpcode::EmitThenCut); + ENUM_NAME(DxbcOpcode::EndIf); + ENUM_NAME(DxbcOpcode::EndLoop); + ENUM_NAME(DxbcOpcode::EndSwitch); + ENUM_NAME(DxbcOpcode::Eq); + ENUM_NAME(DxbcOpcode::Exp); + ENUM_NAME(DxbcOpcode::Frc); + ENUM_NAME(DxbcOpcode::FtoI); + ENUM_NAME(DxbcOpcode::FtoU); + ENUM_NAME(DxbcOpcode::Ge); + ENUM_NAME(DxbcOpcode::IAdd); + ENUM_NAME(DxbcOpcode::If); + ENUM_NAME(DxbcOpcode::IEq); + ENUM_NAME(DxbcOpcode::IGe); + ENUM_NAME(DxbcOpcode::ILt); + ENUM_NAME(DxbcOpcode::IMad); + ENUM_NAME(DxbcOpcode::IMax); + ENUM_NAME(DxbcOpcode::IMin); + ENUM_NAME(DxbcOpcode::IMul); + ENUM_NAME(DxbcOpcode::INe); + ENUM_NAME(DxbcOpcode::INeg); + ENUM_NAME(DxbcOpcode::IShl); + ENUM_NAME(DxbcOpcode::IShr); + ENUM_NAME(DxbcOpcode::ItoF); + ENUM_NAME(DxbcOpcode::Label); + ENUM_NAME(DxbcOpcode::Ld); + ENUM_NAME(DxbcOpcode::LdMs); + ENUM_NAME(DxbcOpcode::Log); + ENUM_NAME(DxbcOpcode::Loop); + ENUM_NAME(DxbcOpcode::Lt); + ENUM_NAME(DxbcOpcode::Mad); + ENUM_NAME(DxbcOpcode::Min); + ENUM_NAME(DxbcOpcode::Max); + ENUM_NAME(DxbcOpcode::CustomData); + ENUM_NAME(DxbcOpcode::Mov); + ENUM_NAME(DxbcOpcode::Movc); + ENUM_NAME(DxbcOpcode::Mul); + ENUM_NAME(DxbcOpcode::Ne); + ENUM_NAME(DxbcOpcode::Nop); + ENUM_NAME(DxbcOpcode::Not); + ENUM_NAME(DxbcOpcode::Or); + ENUM_NAME(DxbcOpcode::ResInfo); + ENUM_NAME(DxbcOpcode::Ret); + ENUM_NAME(DxbcOpcode::Retc); + ENUM_NAME(DxbcOpcode::RoundNe); + ENUM_NAME(DxbcOpcode::RoundNi); + ENUM_NAME(DxbcOpcode::RoundPi); + ENUM_NAME(DxbcOpcode::RoundZ); + ENUM_NAME(DxbcOpcode::Rsq); + ENUM_NAME(DxbcOpcode::Sample); + ENUM_NAME(DxbcOpcode::SampleC); + ENUM_NAME(DxbcOpcode::SampleClz); + ENUM_NAME(DxbcOpcode::SampleL); + ENUM_NAME(DxbcOpcode::SampleD); + ENUM_NAME(DxbcOpcode::SampleB); + ENUM_NAME(DxbcOpcode::Sqrt); + ENUM_NAME(DxbcOpcode::Switch); + ENUM_NAME(DxbcOpcode::SinCos); + ENUM_NAME(DxbcOpcode::UDiv); + ENUM_NAME(DxbcOpcode::ULt); + ENUM_NAME(DxbcOpcode::UGe); + ENUM_NAME(DxbcOpcode::UMul); + ENUM_NAME(DxbcOpcode::UMad); + ENUM_NAME(DxbcOpcode::UMax); + ENUM_NAME(DxbcOpcode::UMin); + ENUM_NAME(DxbcOpcode::UShr); + ENUM_NAME(DxbcOpcode::UtoF); + ENUM_NAME(DxbcOpcode::Xor); + ENUM_NAME(DxbcOpcode::DclResource); + ENUM_NAME(DxbcOpcode::DclConstantBuffer); + ENUM_NAME(DxbcOpcode::DclSampler); + ENUM_NAME(DxbcOpcode::DclIndexRange); + ENUM_NAME(DxbcOpcode::DclGsOutputPrimitiveTopology); + ENUM_NAME(DxbcOpcode::DclGsInputPrimitive); + ENUM_NAME(DxbcOpcode::DclMaxOutputVertexCount); + ENUM_NAME(DxbcOpcode::DclInput); + ENUM_NAME(DxbcOpcode::DclInputSgv); + ENUM_NAME(DxbcOpcode::DclInputSiv); + ENUM_NAME(DxbcOpcode::DclInputPs); + ENUM_NAME(DxbcOpcode::DclInputPsSgv); + ENUM_NAME(DxbcOpcode::DclInputPsSiv); + ENUM_NAME(DxbcOpcode::DclOutput); + ENUM_NAME(DxbcOpcode::DclOutputSgv); + ENUM_NAME(DxbcOpcode::DclOutputSiv); + ENUM_NAME(DxbcOpcode::DclTemps); + ENUM_NAME(DxbcOpcode::DclIndexableTemp); + ENUM_NAME(DxbcOpcode::DclGlobalFlags); + ENUM_NAME(DxbcOpcode::Reserved0); + ENUM_NAME(DxbcOpcode::Lod); + ENUM_NAME(DxbcOpcode::Gather4); + ENUM_NAME(DxbcOpcode::SamplePos); + ENUM_NAME(DxbcOpcode::SampleInfo); + ENUM_NAME(DxbcOpcode::Reserved1); + ENUM_NAME(DxbcOpcode::HsDecls); + ENUM_NAME(DxbcOpcode::HsControlPointPhase); + ENUM_NAME(DxbcOpcode::HsForkPhase); + ENUM_NAME(DxbcOpcode::HsJoinPhase); + ENUM_NAME(DxbcOpcode::EmitStream); + ENUM_NAME(DxbcOpcode::CutStream); + ENUM_NAME(DxbcOpcode::EmitThenCutStream); + ENUM_NAME(DxbcOpcode::InterfaceCall); + ENUM_NAME(DxbcOpcode::BufInfo); + ENUM_NAME(DxbcOpcode::DerivRtxCoarse); + ENUM_NAME(DxbcOpcode::DerivRtxFine); + ENUM_NAME(DxbcOpcode::DerivRtyCoarse); + ENUM_NAME(DxbcOpcode::DerivRtyFine); + ENUM_NAME(DxbcOpcode::Gather4C); + ENUM_NAME(DxbcOpcode::Gather4Po); + ENUM_NAME(DxbcOpcode::Gather4PoC); + ENUM_NAME(DxbcOpcode::Rcp); + ENUM_NAME(DxbcOpcode::F32toF16); + ENUM_NAME(DxbcOpcode::F16toF32); + ENUM_NAME(DxbcOpcode::UAddc); + ENUM_NAME(DxbcOpcode::USubb); + ENUM_NAME(DxbcOpcode::CountBits); + ENUM_NAME(DxbcOpcode::FirstBitHi); + ENUM_NAME(DxbcOpcode::FirstBitLo); + ENUM_NAME(DxbcOpcode::FirstBitShi); + ENUM_NAME(DxbcOpcode::UBfe); + ENUM_NAME(DxbcOpcode::IBfe); + ENUM_NAME(DxbcOpcode::Bfi); + ENUM_NAME(DxbcOpcode::BfRev); + ENUM_NAME(DxbcOpcode::Swapc); + ENUM_NAME(DxbcOpcode::DclStream); + ENUM_NAME(DxbcOpcode::DclFunctionBody); + ENUM_NAME(DxbcOpcode::DclFunctionTable); + ENUM_NAME(DxbcOpcode::DclInterface); + ENUM_NAME(DxbcOpcode::DclInputControlPointCount); + ENUM_NAME(DxbcOpcode::DclOutputControlPointCount); + ENUM_NAME(DxbcOpcode::DclTessDomain); + ENUM_NAME(DxbcOpcode::DclTessPartitioning); + ENUM_NAME(DxbcOpcode::DclTessOutputPrimitive); + ENUM_NAME(DxbcOpcode::DclHsMaxTessFactor); + 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::DclThreadGroupSharedMemoryRaw); + ENUM_NAME(DxbcOpcode::DclThreadGroupSharedMemoryStructured); + ENUM_NAME(DxbcOpcode::DclResourceRaw); + ENUM_NAME(DxbcOpcode::DclResourceStructured); + ENUM_NAME(DxbcOpcode::LdUavTyped); + ENUM_NAME(DxbcOpcode::StoreUavTyped); + ENUM_NAME(DxbcOpcode::LdRaw); + ENUM_NAME(DxbcOpcode::StoreRaw); + ENUM_NAME(DxbcOpcode::LdStructured); + ENUM_NAME(DxbcOpcode::StoreStructured); + ENUM_NAME(DxbcOpcode::AtomicAnd); + ENUM_NAME(DxbcOpcode::AtomicOr); + ENUM_NAME(DxbcOpcode::AtomicXor); + ENUM_NAME(DxbcOpcode::AtomicCmpStore); + ENUM_NAME(DxbcOpcode::AtomicIAdd); + ENUM_NAME(DxbcOpcode::AtomicIMax); + ENUM_NAME(DxbcOpcode::AtomicIMin); + ENUM_NAME(DxbcOpcode::AtomicUMax); + ENUM_NAME(DxbcOpcode::AtomicUMin); + ENUM_NAME(DxbcOpcode::ImmAtomicAlloc); + ENUM_NAME(DxbcOpcode::ImmAtomicConsume); + ENUM_NAME(DxbcOpcode::ImmAtomicIAdd); + ENUM_NAME(DxbcOpcode::ImmAtomicAnd); + ENUM_NAME(DxbcOpcode::ImmAtomicOr); + ENUM_NAME(DxbcOpcode::ImmAtomicXor); + ENUM_NAME(DxbcOpcode::ImmAtomicExch); + ENUM_NAME(DxbcOpcode::ImmAtomicCmpExch); + ENUM_NAME(DxbcOpcode::ImmAtomicImax); + ENUM_NAME(DxbcOpcode::ImmAtomicImin); + ENUM_NAME(DxbcOpcode::ImmAtomicUmax); + ENUM_NAME(DxbcOpcode::ImmAtomicUmin); + ENUM_NAME(DxbcOpcode::Sync); + ENUM_NAME(DxbcOpcode::DAdd); + ENUM_NAME(DxbcOpcode::DMax); + ENUM_NAME(DxbcOpcode::DMin); + ENUM_NAME(DxbcOpcode::DMul); + ENUM_NAME(DxbcOpcode::DEq); + ENUM_NAME(DxbcOpcode::DGe); + ENUM_NAME(DxbcOpcode::DLt); + ENUM_NAME(DxbcOpcode::DNe); + ENUM_NAME(DxbcOpcode::DMov); + ENUM_NAME(DxbcOpcode::DMovc); + ENUM_NAME(DxbcOpcode::DtoF); + ENUM_NAME(DxbcOpcode::FtoD); + ENUM_NAME(DxbcOpcode::EvalSnapped); + ENUM_NAME(DxbcOpcode::EvalSampleIndex); + ENUM_NAME(DxbcOpcode::EvalCentroid); + ENUM_NAME(DxbcOpcode::DclGsInstanceCount); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcExtOpcode e) { + switch (e) { + ENUM_NAME(DxbcExtOpcode::Empty); + ENUM_NAME(DxbcExtOpcode::SampleControls); + ENUM_NAME(DxbcExtOpcode::ResourceDim); + ENUM_NAME(DxbcExtOpcode::ResourceReturnType); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcOperandType e) { + switch (e) { + ENUM_NAME(DxbcOperandType::Temp); + ENUM_NAME(DxbcOperandType::Input); + ENUM_NAME(DxbcOperandType::Output); + ENUM_NAME(DxbcOperandType::IndexableTemp); + ENUM_NAME(DxbcOperandType::Imm32); + ENUM_NAME(DxbcOperandType::Imm64); + ENUM_NAME(DxbcOperandType::Sampler); + ENUM_NAME(DxbcOperandType::Resource); + ENUM_NAME(DxbcOperandType::ConstantBuffer); + ENUM_NAME(DxbcOperandType::ImmediateConstantBuffer); + ENUM_NAME(DxbcOperandType::Label); + ENUM_NAME(DxbcOperandType::InputPrimitiveId); + ENUM_NAME(DxbcOperandType::OutputDepth); + ENUM_NAME(DxbcOperandType::Null); + ENUM_NAME(DxbcOperandType::Rasterizer); + ENUM_NAME(DxbcOperandType::OutputCoverageMask); + ENUM_NAME(DxbcOperandType::Stream); + ENUM_NAME(DxbcOperandType::FunctionBody); + ENUM_NAME(DxbcOperandType::FunctionTable); + ENUM_NAME(DxbcOperandType::Interface); + ENUM_NAME(DxbcOperandType::FunctionInput); + ENUM_NAME(DxbcOperandType::FunctionOutput); + ENUM_NAME(DxbcOperandType::OutputControlPointId); + ENUM_NAME(DxbcOperandType::InputForkInstanceId); + ENUM_NAME(DxbcOperandType::InputJoinInstanceId); + ENUM_NAME(DxbcOperandType::InputControlPoint); + ENUM_NAME(DxbcOperandType::OutputControlPoint); + ENUM_NAME(DxbcOperandType::InputPatchConstant); + ENUM_NAME(DxbcOperandType::InputDomainPoint); + ENUM_NAME(DxbcOperandType::ThisPointer); + ENUM_NAME(DxbcOperandType::UnorderedAccessView); + ENUM_NAME(DxbcOperandType::ThreadGroupSharedMemory); + ENUM_NAME(DxbcOperandType::InputThreadId); + ENUM_NAME(DxbcOperandType::InputThreadGroupId); + ENUM_NAME(DxbcOperandType::InputThreadIdInGroup); + ENUM_NAME(DxbcOperandType::InputCoverageMask); + ENUM_NAME(DxbcOperandType::InputThreadIndexInGroup); + ENUM_NAME(DxbcOperandType::InputGsInstanceId); + ENUM_NAME(DxbcOperandType::OutputDepthGe); + ENUM_NAME(DxbcOperandType::OutputDepthLe); + ENUM_NAME(DxbcOperandType::CycleCounter); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcOperandNumComponents e) { + switch (e) { + ENUM_NAME(DxbcOperandNumComponents::Component0); + ENUM_NAME(DxbcOperandNumComponents::Component1); + ENUM_NAME(DxbcOperandNumComponents::Component4); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcOperandComponentSelectionMode e) { + switch (e) { + ENUM_NAME(DxbcOperandComponentSelectionMode::Mask); + ENUM_NAME(DxbcOperandComponentSelectionMode::Swizzle); + ENUM_NAME(DxbcOperandComponentSelectionMode::Select1); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcOperandComponentName e) { + switch (e) { + ENUM_NAME(DxbcOperandComponentName::X); + ENUM_NAME(DxbcOperandComponentName::Y); + ENUM_NAME(DxbcOperandComponentName::Z); + ENUM_NAME(DxbcOperandComponentName::W); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcOperandIndexRepresentation e) { + switch (e) { + ENUM_NAME(DxbcOperandIndexRepresentation::Imm32); + ENUM_NAME(DxbcOperandIndexRepresentation::Imm64); + ENUM_NAME(DxbcOperandIndexRepresentation::Relative); + ENUM_NAME(DxbcOperandIndexRepresentation::Imm32Relative); + ENUM_NAME(DxbcOperandIndexRepresentation::Imm64Relative); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcResourceDim e) { + switch (e) { + ENUM_NAME(DxbcResourceDim::Unknown); + ENUM_NAME(DxbcResourceDim::Buffer); + ENUM_NAME(DxbcResourceDim::Texture1D); + ENUM_NAME(DxbcResourceDim::Texture2D); + ENUM_NAME(DxbcResourceDim::Texture2DMs); + ENUM_NAME(DxbcResourceDim::Texture3D); + ENUM_NAME(DxbcResourceDim::TextureCube); + ENUM_NAME(DxbcResourceDim::Texture1DArr); + ENUM_NAME(DxbcResourceDim::Texture2DArr); + ENUM_NAME(DxbcResourceDim::Texture2DMsArr); + ENUM_NAME(DxbcResourceDim::TextureCubeArr); + ENUM_NAME(DxbcResourceDim::RawBuffer); + ENUM_NAME(DxbcResourceDim::StructuredBuffer); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcResourceReturnType e) { + switch (e) { + ENUM_NAME(DxbcResourceReturnType::Unorm); + ENUM_NAME(DxbcResourceReturnType::Snorm); + ENUM_NAME(DxbcResourceReturnType::Sint); + ENUM_NAME(DxbcResourceReturnType::Uint); + ENUM_NAME(DxbcResourceReturnType::Float); + ENUM_NAME(DxbcResourceReturnType::Mixed); + ENUM_NAME(DxbcResourceReturnType::Double); + ENUM_NAME(DxbcResourceReturnType::Continued); + ENUM_NAME(DxbcResourceReturnType::Unused); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcRegisterComponentType e) { + switch (e) { + ENUM_NAME(DxbcRegisterComponentType::Unknown); + ENUM_NAME(DxbcRegisterComponentType::Uint32); + ENUM_NAME(DxbcRegisterComponentType::Sint32); + ENUM_NAME(DxbcRegisterComponentType::Float32); + ENUM_DEFAULT(e); + } +} + + +std::ostream& operator << (std::ostream& os, DxbcInstructionReturnType e) { + switch (e) { + ENUM_NAME(DxbcInstructionReturnType::Float); + ENUM_NAME(DxbcInstructionReturnType::Uint); + ENUM_DEFAULT(e); + } +} diff --git a/src/dxbc/dxbc_names.h b/src/dxbc/dxbc_names.h new file mode 100644 index 00000000..2584d014 --- /dev/null +++ b/src/dxbc/dxbc_names.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include "dxbc_enums.h" + +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::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); diff --git a/src/dxbc/meson.build b/src/dxbc/meson.build index 22d37f5c..fe91536d 100644 --- a/src/dxbc/meson.build +++ b/src/dxbc/meson.build @@ -5,6 +5,7 @@ dxbc_src = files([ 'dxbc_decoder.cpp', 'dxbc_header.cpp', 'dxbc_module.cpp', + 'dxbc_names.cpp', 'dxbc_reader.cpp', ]) diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 5cb9b14d..47dec54e 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -24,7 +24,7 @@ namespace dxvk { uint32_t SpirvModule::allocateId() { - return ++m_id; + return m_id++; } @@ -48,7 +48,13 @@ namespace dxvk { const char* name, uint32_t interfaceCount, const uint32_t* interfaceIds) { + m_entryPoints.putIns (spv::OpEntryPoint, 3 + m_entryPoints.strLen(name) + interfaceCount); + m_entryPoints.putWord (executionModel); + m_entryPoints.putWord (entryPointId); + m_entryPoints.putStr (name); + for (uint32_t i = 0; i < interfaceCount; i++) + m_entryPoints.putWord(interfaceIds[i]); } @@ -63,7 +69,9 @@ namespace dxvk { void SpirvModule::enableEarlyFragmentTests( uint32_t entryPointId) { - + m_execModeInfo.putIns (spv::OpExecutionMode, 3); + m_execModeInfo.putWord(entryPointId); + m_execModeInfo.putWord(spv::ExecutionModeEarlyFragmentTests); } @@ -72,7 +80,12 @@ namespace dxvk { uint32_t x, uint32_t y, uint32_t z) { - + m_execModeInfo.putIns (spv::OpExecutionMode, 6); + m_execModeInfo.putWord (entryPointId); + m_execModeInfo.putWord (spv::ExecutionModeLocalSize); + m_execModeInfo.putInt32(x); + m_execModeInfo.putInt32(y); + m_execModeInfo.putInt32(z); } diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 446dfafb..2828e6ab 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -138,7 +138,7 @@ namespace dxvk { private: - uint32_t m_id = 0; + uint32_t m_id = 1; SpirvCodeBuffer m_capabilities; SpirvCodeBuffer m_memoryModel; diff --git a/src/util/util_enum.h b/src/util/util_enum.h index 12e412a9..85b9b21b 100644 --- a/src/util/util_enum.h +++ b/src/util/util_enum.h @@ -1,7 +1,7 @@ #pragma once #define ENUM_NAME(name) \ - case name: os << #name; break + case name: return os << #name #define ENUM_DEFAULT(name) \ - default: os << e + default: return os << static_cast(e) diff --git a/src/util/util_flags.h b/src/util/util_flags.h index 66636ad0..530c59e5 100644 --- a/src/util/util_flags.h +++ b/src/util/util_flags.h @@ -13,6 +13,9 @@ namespace dxvk { Flags() { } + Flags(IntType t) + : m_bits(t) { } + template Flags(T f, Tx... fx) { this->set(f, fx...);