From bd17be472d4d2de48b8c9ec2e7ad8ec01a4713bc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 5 Apr 2018 20:10:00 +0200 Subject: [PATCH] [dxbc] Reciprocate W component of SV_POSITION in pixel shaders Fixes the fog effect in Nier:Automata, as well as some major visual issues in Rise of the Tomb Raider, and potentially other games. --- src/dxbc/dxbc_compiler.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index cd1e674dc7c..f3010bf85ff 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5002,12 +5002,25 @@ namespace dxvk { } DxbcRegisterPointer ptrIn; - ptrIn.type.ctype = DxbcScalarType::Float32; - ptrIn.type.ccount = 4; + ptrIn.type = { DxbcScalarType::Float32, 4 }; ptrIn.id = m_ps.builtinFragCoord; - return emitRegisterExtract( - emitValueLoad(ptrIn), mask); + // The X, Y and Z components of the SV_POSITION semantic + // are identical to Vulkan's FragCoord builtin, but we + // need to compute the reciprocal of the W component. + DxbcRegisterValue fragCoord = emitValueLoad(ptrIn); + + uint32_t componentIndex = 3; + uint32_t t_f32 = m_module.defFloatType(32); + uint32_t v_wComp = m_module.opCompositeExtract(t_f32, fragCoord.id, 1, &componentIndex); + v_wComp = m_module.opFDiv(t_f32, m_module.constf32(1.0f), v_wComp); + + fragCoord.id = m_module.opCompositeInsert( + getVectorTypeId(fragCoord.type), + v_wComp, fragCoord.id, + 1, &componentIndex); + + return emitRegisterExtract(fragCoord, mask); } break; case DxbcSystemValue::IsFrontFace: {