From 6ff709513ca7b69abc49969dbd1656e652601e31 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 20 Dec 2017 22:50:05 +0100 Subject: [PATCH] [dxbc] Added indexable temps --- src/dxbc/dxbc_compiler.cpp | 56 +++++++++++++++++++++++++++++++++++++- src/dxbc/dxbc_compiler.h | 18 ++++++++++-- src/dxbc/dxbc_defs.cpp | 6 +++- 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 03021c11b..c3f20a439 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -146,6 +146,9 @@ namespace dxvk { case DxbcOpcode::DclTemps: return this->emitDclTemps(ins); + case DxbcOpcode::DclIndexableTemp: + return this->emitDclIndexableTemp(ins); + case DxbcOpcode::DclInput: case DxbcOpcode::DclInputSgv: case DxbcOpcode::DclInputSiv: @@ -212,6 +215,27 @@ namespace dxvk { } + void DxbcCompiler::emitDclIndexableTemp(const DxbcShaderInstruction& ins) { + // dcl_indexable_temps has three operands: + // (imm0) Array register index (x#) + // (imm1) Number of vectors stored in the array + // (imm2) Component count of each individual vector + DxbcRegisterInfo info; + info.type.ctype = DxbcScalarType::Float32; + info.type.ccount = ins.imm[2].u32; + info.type.alength = ins.imm[1].u32; + info.sclass = spv::StorageClassPrivate; + + const uint32_t regId = ins.imm[0].u32; + + if (regId >= m_xRegs.size()) + m_xRegs.resize(regId + 1); + + m_xRegs.at(regId).ccount = info.type.ccount; + m_xRegs.at(regId).varId = emitNewVariable(info); + } + + void DxbcCompiler::emitDclInterfaceReg(const DxbcShaderInstruction& ins) { switch (ins.dst[0].type) { case DxbcOperandType::Input: @@ -1719,7 +1743,7 @@ namespace dxvk { DxbcRegisterPointer DxbcCompiler::emitGetTempPtr( - const DxbcRegister& operand) { + const DxbcRegister& operand) { // r# regs are indexed as follows: // (0) register index (immediate) DxbcRegisterPointer result; @@ -1730,6 +1754,33 @@ namespace dxvk { } + DxbcRegisterPointer DxbcCompiler::emitGetIndexableTempPtr( + const DxbcRegister& operand) { + // x# regs are indexed as follows: + // (0) register index (immediate) + // (1) element index (relative) + const uint32_t regId = operand.idx[0].offset; + + const DxbcRegisterValue vectorId + = emitIndexLoad(operand.idx[1]); + + DxbcRegisterInfo info; + info.type.ctype = DxbcScalarType::Float32; + info.type.ccount = m_xRegs[regId].ccount; + info.type.alength = 0; + info.sclass = spv::StorageClassPrivate; + + DxbcRegisterPointer result; + result.type.ctype = info.type.ctype; + result.type.ccount = info.type.ccount; + result.id = m_module.opAccessChain( + getPointerTypeId(info), + m_xRegs.at(regId).varId, + 1, &vectorId.id); + return result; + } + + DxbcRegisterPointer DxbcCompiler::emitGetInputPtr( const DxbcRegister& operand) { // In the vertex and pixel stages, @@ -1855,6 +1906,9 @@ namespace dxvk { case DxbcOperandType::Temp: return emitGetTempPtr(operand); + case DxbcOperandType::IndexableTemp: + return emitGetIndexableTempPtr(operand); + case DxbcOperandType::Input: return emitGetInputPtr(operand); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 74878dc19..5ac0951cc 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -80,6 +80,12 @@ namespace dxvk { }; + struct DxbcXreg { + uint32_t ccount = 0; + uint32_t varId = 0; + }; + + /** * \brief Vertex shader-specific structure */ @@ -183,9 +189,11 @@ namespace dxvk { // be used to map D3D11 bindings to DXVK bindings. std::vector m_resourceSlots; - /////////////////////////////// - // r# registers of type float4 + //////////////////////////////////////////////// + // Temporary r# vector registers with immediate + // indexing, and x# vector array registers. std::vector m_rRegs; + std::vector m_xRegs; /////////////////////////////////////////////////////////// // v# registers as defined by the shader. The type of each @@ -251,6 +259,9 @@ namespace dxvk { void emitDclTemps( const DxbcShaderInstruction& ins); + void emitDclIndexableTemp( + const DxbcShaderInstruction& ins); + void emitDclInterfaceReg( const DxbcShaderInstruction& ins); @@ -402,6 +413,9 @@ namespace dxvk { DxbcRegisterPointer emitGetTempPtr( const DxbcRegister& operand); + DxbcRegisterPointer emitGetIndexableTempPtr( + const DxbcRegister& operand); + DxbcRegisterPointer emitGetInputPtr( const DxbcRegister& operand); diff --git a/src/dxbc/dxbc_defs.cpp b/src/dxbc/dxbc_defs.cpp index 49d00cf11..80ed95c28 100644 --- a/src/dxbc/dxbc_defs.cpp +++ b/src/dxbc/dxbc_defs.cpp @@ -441,7 +441,11 @@ namespace dxvk { { DxbcOperandKind::Imm32, DxbcScalarType::Uint32 }, } }, /* DclIndexableTemp */ - { }, + { 3, DxbcInstClass::Declaration, { + { DxbcOperandKind::Imm32, DxbcScalarType::Uint32 }, + { DxbcOperandKind::Imm32, DxbcScalarType::Uint32 }, + { DxbcOperandKind::Imm32, DxbcScalarType::Uint32 }, + } }, /* DclGlobalFlags */ { 0, DxbcInstClass::Declaration }, /* Reserved0 */