From 8644d75722857fddb79b35248090304454d122a2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 2 Jul 2019 22:53:58 +0200 Subject: [PATCH] [dxbc] Use OpDemoteToHelperInvocationEXT for discards if supported --- src/dxbc/dxbc_compiler.cpp | 20 +++++++++++++++----- src/dxbc/dxbc_options.cpp | 2 ++ src/dxbc/dxbc_options.h | 3 +++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index ab8f6bb8..4b01468d 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -4047,9 +4047,15 @@ namespace dxvk { m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone); m_module.opBranchConditional(zeroTest.id, cond.labelIf, cond.labelEnd); - // OpKill terminates the block m_module.opLabel(cond.labelIf); - m_module.opKill(); + + if (m_moduleInfo.options.useDemoteToHelperInvocation) { + m_module.opDemoteToHelperInvocation(); + m_module.opBranch(cond.labelEnd); + } else { + // OpKill terminates the block + m_module.opKill(); + } m_module.opLabel(cond.labelEnd); } else { @@ -6621,9 +6627,13 @@ namespace dxvk { m_module.defVoidType(), 0, nullptr)); this->emitFunctionLabel(); - // We may have to defer kill operations to the end of - // the shader in order to keep derivatives correct. - if (m_analysis->usesKill && m_analysis->usesDerivatives) { + if (m_analysis->usesKill && m_moduleInfo.options.useDemoteToHelperInvocation) { + // This extension basically implements D3D-style discard + m_module.enableExtension("SPV_EXT_demote_to_helper_invocation"); + m_module.enableCapability(spv::CapabilityDemoteToHelperInvocationEXT); + } else if (m_analysis->usesKill && m_analysis->usesDerivatives) { + // We may have to defer kill operations to the end of + // the shader in order to keep derivatives correct. m_ps.killState = m_module.newVarInit( m_module.defPointerType(m_module.defBoolType(), spv::StorageClassPrivate), spv::StorageClassPrivate, m_module.constBool(false)); diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index e277409c..ced75214 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -24,6 +24,8 @@ namespace dxvk { useSubgroupOpsForAtomicCounters = (devInfo.coreSubgroup.supportedStages & allShaderStages) == allShaderStages && (devInfo.coreSubgroup.supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT); + useDemoteToHelperInvocation + = (devFeatures.extShaderDemoteToHelperInvocation.shaderDemoteToHelperInvocation); useSubgroupOpsForEarlyDiscard = (devInfo.coreSubgroup.subgroupSize >= 4) && (devInfo.coreSubgroup.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index 7451e179..8aefce49 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -21,6 +21,9 @@ namespace dxvk { /// atomic operations for append/consume buffers. bool useSubgroupOpsForAtomicCounters = false; + /// Use a SPIR-V extension to implement D3D-style discards + bool useDemoteToHelperInvocation = false; + /// Use subgroup operations to discard fragment /// shader invocations if derivatives remain valid. bool useSubgroupOpsForEarlyDiscard = false;