mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 13:54:18 +01:00
[dxbc] Use subgroup operations for early discard
Can improve performance in some complex fragment shaders.
This commit is contained in:
parent
a574829bb6
commit
4f76b89941
@ -3892,6 +3892,26 @@ namespace dxvk {
|
|||||||
uint32_t killState = m_module.opLoad (typeId, m_ps.killState);
|
uint32_t killState = m_module.opLoad (typeId, m_ps.killState);
|
||||||
killState = m_module.opLogicalOr(typeId, killState, zeroTest.id);
|
killState = m_module.opLogicalOr(typeId, killState, zeroTest.id);
|
||||||
m_module.opStore(m_ps.killState, killState);
|
m_module.opStore(m_ps.killState, killState);
|
||||||
|
|
||||||
|
if (m_moduleInfo.options.useSubgroupOpsForEarlyDiscard) {
|
||||||
|
uint32_t killSubgroup = m_module.opGroupNonUniformLogicalAnd(
|
||||||
|
m_module.defBoolType(),
|
||||||
|
m_module.constu32(spv::ScopeSubgroup),
|
||||||
|
spv::GroupOperationReduce, killState, 0);
|
||||||
|
|
||||||
|
DxbcConditional cond;
|
||||||
|
cond.labelIf = m_module.allocateId();
|
||||||
|
cond.labelEnd = m_module.allocateId();
|
||||||
|
|
||||||
|
m_module.opSelectionMerge(cond.labelEnd, spv::SelectionControlMaskNone);
|
||||||
|
m_module.opBranchConditional(killSubgroup, cond.labelIf, cond.labelEnd);
|
||||||
|
|
||||||
|
// OpKill terminates the block
|
||||||
|
m_module.opLabel(cond.labelIf);
|
||||||
|
m_module.opKill();
|
||||||
|
|
||||||
|
m_module.opLabel(cond.labelEnd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6166,6 +6186,11 @@ namespace dxvk {
|
|||||||
spv::StorageClassPrivate, m_module.constBool(false));
|
spv::StorageClassPrivate, m_module.constBool(false));
|
||||||
|
|
||||||
m_module.setDebugName(m_ps.killState, "ps_kill");
|
m_module.setDebugName(m_ps.killState, "ps_kill");
|
||||||
|
|
||||||
|
if (m_moduleInfo.options.useSubgroupOpsForEarlyDiscard) {
|
||||||
|
m_module.enableCapability(spv::CapabilityGroupNonUniform);
|
||||||
|
m_module.enableCapability(spv::CapabilityGroupNonUniformArithmetic);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main function of the pixel shader
|
// Main function of the pixel shader
|
||||||
|
@ -11,8 +11,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxbcOptions::DxbcOptions(const Rc<DxvkDevice>& device) {
|
DxbcOptions::DxbcOptions(const Rc<DxvkDevice>& device) {
|
||||||
const DxvkDeviceFeatures& devFeatures = device->features();
|
const DxvkDeviceFeatures& devFeatures = device->features();
|
||||||
|
const DxvkDeviceInfo& devInfo = device->adapter()->devicePropertiesExt();
|
||||||
useStorageImageReadWithoutFormat = devFeatures.core.features.shaderStorageImageReadWithoutFormat;
|
|
||||||
|
useStorageImageReadWithoutFormat
|
||||||
|
= devFeatures.core.features.shaderStorageImageReadWithoutFormat;
|
||||||
|
useSubgroupOpsForEarlyDiscard
|
||||||
|
= (devInfo.coreSubgroup.subgroupSize >= 4)
|
||||||
|
&& (devInfo.coreSubgroup.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT)
|
||||||
|
&& (devInfo.coreSubgroup.supportedOperations & VK_SUBGROUP_FEATURE_ARITHMETIC_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -10,6 +10,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
/// Use the ShaderImageReadWithoutFormat capability.
|
/// Use the ShaderImageReadWithoutFormat capability.
|
||||||
bool useStorageImageReadWithoutFormat = false;
|
bool useStorageImageReadWithoutFormat = false;
|
||||||
|
|
||||||
|
/// Use subgroup operations to discard fragment
|
||||||
|
/// shader invocations if derivatives remain valid.
|
||||||
|
bool useSubgroupOpsForEarlyDiscard = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user