From 032625882990ae843cbdcd526f3c72087ab31888 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 9 Mar 2019 19:59:56 +0100 Subject: [PATCH] [dxbc] Use SDiv instead of ShiftRightLogical for index calc on Nvidia Reportedly fixes Resident Evil 2 and Devil May Cry 5 on Nvidia. --- src/dxbc/dxbc_compiler.cpp | 16 +++++++++++----- src/dxbc/dxbc_options.cpp | 2 ++ src/dxbc/dxbc_options.h | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 9ebdb291..c8dd616e 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5122,9 +5122,13 @@ namespace dxvk { const uint32_t typeId = getVectorTypeId(result.type); + uint32_t offset = m_moduleInfo.options.useSdivForBufferIndex + ? m_module.opSDiv (typeId, structOffset.id, m_module.consti32(4)) + : m_module.opShiftRightLogical(typeId, structOffset.id, m_module.consti32(2)); + result.id = m_module.opIAdd(typeId, m_module.opIMul(typeId, structId.id, m_module.consti32(structStride / 4)), - m_module.opShiftRightLogical(typeId, structOffset.id, m_module.consti32(2))); + offset); return result; } @@ -5134,10 +5138,12 @@ namespace dxvk { DxbcRegisterValue result; result.type.ctype = DxbcScalarType::Sint32; result.type.ccount = 1; - result.id = m_module.opShiftRightLogical( - getVectorTypeId(result.type), - byteOffset.id, - m_module.consti32(2)); + + uint32_t typeId = getVectorTypeId(result.type); + + result.id = m_moduleInfo.options.useSdivForBufferIndex + ? m_module.opSDiv (typeId, byteOffset.id, m_module.consti32(4)) + : m_module.opShiftRightLogical(typeId, byteOffset.id, m_module.consti32(2)); return result; } diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 3ec58c05..cce13915 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -25,6 +25,8 @@ namespace dxvk { && (devInfo.coreSubgroup.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); useRawSsbo = (devInfo.core.properties.limits.minStorageBufferOffsetAlignment <= sizeof(uint32_t)); + useSdivForBufferIndex + = adapter->matchesDriver(DxvkGpuVendor::Nvidia, VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR, 0, 0); strictDivision = options.strictDivision; zeroInitWorkgroupMemory = options.zeroInitWorkgroupMemory; diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index ef332c16..9fdf554c 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -24,6 +24,10 @@ namespace dxvk { /// Use SSBOs instead of texel buffers /// for raw and structured buffers. bool useRawSsbo = false; + + /// Use SDiv instead of SHR to converte byte offsets to + /// dword offsets. Fixes RE2 and DMC5 on Nvidia drivers. + bool useSdivForBufferIndex = false; /// Enables sm4-compliant division-by-zero behaviour bool strictDivision = false;