From ac94c423800900ccfe346a1561aae5220d523b1a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 24 Mar 2018 16:23:31 +0100 Subject: [PATCH] Revert "[dxbc] Do not emit per-vertex input block" This reverts commit 4ce64bd8865bbb25baa25d622437c9258126c4d2. Fixes a regression in Sniper: Ghost Warrior 2 and Dishonored 2. --- src/dxbc/dxbc_compiler.cpp | 57 ++++++++++++++++++++++++++++++++++---- src/dxbc/dxbc_compiler.h | 5 ++++ 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 459f57df..94f67d9d 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -588,9 +588,6 @@ namespace dxvk { bool skipSv = sv == DxbcSystemValue::ClipDistance || sv == DxbcSystemValue::CullDistance; - if (m_version.type() != DxbcProgramType::PixelShader) - skipSv = skipSv || sv == DxbcSystemValue::Position; - if (!skipSv) m_vMappings.push_back({ regIdx, regMask, sv }); } @@ -1083,7 +1080,11 @@ namespace dxvk { m_gs.inputPrimitive = ins.controls.primitive; m_module.setExecutionMode(m_entryPointId, mode); - emitDclInputArray(primitiveVertexCount(m_gs.inputPrimitive)); + const uint32_t vertexCount + = primitiveVertexCount(m_gs.inputPrimitive); + + emitDclInputArray(vertexCount); + emitDclInputPerVertex(vertexCount, "gs_vertex_in"); } @@ -4929,8 +4930,33 @@ namespace dxvk { DxbcSystemValue sv, DxbcRegMask mask, uint32_t vertexId) { - throw DxvkError(str::format( - "DxbcCompiler: Unhandled GS SV input: ", sv)); + switch (sv) { + case DxbcSystemValue::Position: { + const std::array indices = { + m_module.consti32(vertexId), + m_module.consti32(PerVertex_Position), + }; + + DxbcRegisterPointer ptrIn; + ptrIn.type.ctype = DxbcScalarType::Float32; + ptrIn.type.ccount = 4; + + ptrIn.id = m_module.opAccessChain( + m_module.defPointerType( + getVectorTypeId(ptrIn.type), + spv::StorageClassInput), + m_perVertexIn, + indices.size(), + indices.data()); + + return emitRegisterExtract( + emitValueLoad(ptrIn), mask); + } break; + + default: + throw DxvkError(str::format( + "DxbcCompiler: Unhandled GS SV input: ", sv)); + } } @@ -5672,6 +5698,25 @@ namespace dxvk { } + void DxbcCompiler::emitDclInputPerVertex( + uint32_t vertexCount, + const char* varName) { + uint32_t typeId = getPerVertexBlockId(); + + if (vertexCount != 0) { + typeId = m_module.defArrayType(typeId, + m_module.constu32(vertexCount)); + } + + const uint32_t ptrTypeId = m_module.defPointerType( + typeId, spv::StorageClassInput); + + m_perVertexIn = m_module.newVar( + ptrTypeId, spv::StorageClassInput); + m_module.setDebugName(m_perVertexIn, varName); + } + + uint32_t DxbcCompiler::emitDclClipCullDistanceArray( uint32_t length, spv::BuiltIn builtIn, diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index f90590ce..6f50b37c 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -390,6 +390,7 @@ namespace dxvk { //////////////////////////////////////////////////// // Per-vertex input and output blocks. Depending on // the shader stage, these may be declared as arrays. + uint32_t m_perVertexIn = 0; uint32_t m_perVertexOut = 0; uint32_t m_clipDistances = 0; @@ -943,6 +944,10 @@ namespace dxvk { void emitDclInputArray( uint32_t vertexCount); + void emitDclInputPerVertex( + uint32_t vertexCount, + const char* varName); + uint32_t emitDclClipCullDistanceArray( uint32_t length, spv::BuiltIn builtIn,