From 8c0e797f37c5edad48d785bb165fd914bb9ef54b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 1 Jan 2018 23:31:01 +0100 Subject: [PATCH] [dxbc] Vertex inputs now respect attribute type Fixes issues with integer attributes which were encountered in Nier: Automata. --- src/dxbc/dxbc_chunk_isgn.cpp | 10 ++++++++++ src/dxbc/dxbc_chunk_isgn.h | 3 +++ src/dxbc/dxbc_compiler.cpp | 32 +++++++++++++++++++++++++++----- src/dxbc/dxbc_compiler.h | 3 +++ 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/dxbc/dxbc_chunk_isgn.cpp b/src/dxbc/dxbc_chunk_isgn.cpp index 38083171..3fa36eb6 100644 --- a/src/dxbc/dxbc_chunk_isgn.cpp +++ b/src/dxbc/dxbc_chunk_isgn.cpp @@ -30,6 +30,16 @@ namespace dxvk { } + const DxbcSgnEntry* DxbcIsgn::findByRegister(uint32_t registerId) const { + for (auto e = this->begin(); e != this->end(); e++) { + if (e->registerId == registerId) + return &(*e); + } + + return nullptr; + } + + const DxbcSgnEntry* DxbcIsgn::find( const std::string& semanticName, uint32_t semanticIndex) const { diff --git a/src/dxbc/dxbc_chunk_isgn.h b/src/dxbc/dxbc_chunk_isgn.h index a6b9636c..1297bbeb 100644 --- a/src/dxbc/dxbc_chunk_isgn.h +++ b/src/dxbc/dxbc_chunk_isgn.h @@ -38,6 +38,9 @@ namespace dxvk { auto begin() const { return m_entries.cbegin(); } auto end () const { return m_entries.cend(); } + const DxbcSgnEntry* findByRegister( + uint32_t registerId) const; + const DxbcSgnEntry* find( const std::string& semanticName, uint32_t semanticIndex) const; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 51710e76..cdee97bb 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -428,9 +428,11 @@ namespace dxvk { // This may happen when multiple system values are // mapped to different parts of the same register. if (m_vRegs.at(regIdx) == 0 && sv == DxbcSystemValue::None) { + const DxbcVectorType regType = getInputRegType(regIdx); + DxbcRegisterInfo info; - info.type.ctype = DxbcScalarType::Float32; - info.type.ccount = 4; + info.type.ctype = regType.ctype; + info.type.ccount = regType.ccount; info.type.alength = regDim; info.sclass = spv::StorageClassInput; @@ -3424,7 +3426,9 @@ namespace dxvk { const uint32_t registerId = m_module.consti32(i); m_module.opStore( m_module.opAccessChain(ptrTypeId, m_vArray, 1, ®isterId), - m_module.opLoad(vecTypeId, m_vRegs.at(i))); + m_module.opBitcast(vecTypeId, m_module.opLoad( + getVectorTypeId(getInputRegType(i)), + m_vRegs.at(i)))); } } @@ -3471,9 +3475,10 @@ namespace dxvk { m_module.opStore( m_module.opAccessChain(dstPtrTypeId, m_vArray, indices.size(), indices.data()), - m_module.opLoad(vecTypeId, + m_module.opBitcast(vecTypeId, m_module.opLoad( + getVectorTypeId(getInputRegType(i)), m_module.opAccessChain(srcPtrTypeId, - m_vRegs.at(i), 1, indices.data()))); + m_vRegs.at(i), 1, indices.data())))); } } } @@ -4014,6 +4019,23 @@ namespace dxvk { } + DxbcVectorType DxbcCompiler::getInputRegType(uint32_t regIdx) const { + DxbcVectorType result; + result.ctype = DxbcScalarType::Float32; + result.ccount = 4; + + // Vertex shader inputs must match the type of the input layout + if (m_version.type() == DxbcProgramType::VertexShader) { + const DxbcSgnEntry* entry = m_isgn->findByRegister(regIdx); + + if (entry != nullptr) + result.ctype = entry->componentType; + } + + return result; + } + + uint32_t DxbcCompiler::getScalarTypeId(DxbcScalarType type) { switch (type) { case DxbcScalarType::Uint32: return m_module.defIntType(32, 0); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 75cb103a..bab7ef3f 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -693,6 +693,9 @@ namespace dxvk { DxbcRegMask getTexCoordMask( const DxbcImageInfo& imageType) const; + DxbcVectorType getInputRegType( + uint32_t regIdx) const; + /////////////////////////// // Type definition methods uint32_t getScalarTypeId(