1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-04-06 18:57:31 +02:00

[dxbc] Track bindings with order-invariant atomic stores

This commit is contained in:
Philip Rebohle 2025-02-15 13:34:20 +01:00 committed by Philip Rebohle
parent d94e3633dc
commit e01a6eec3e
3 changed files with 48 additions and 12 deletions

View File

@ -35,6 +35,28 @@ namespace dxvk {
const uint32_t registerId = ins.dst[operandId].idx[0].offset;
m_analysis->uavInfos[registerId].accessAtomicOp = true;
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
// Check whether the atomic operation is order-invariant
DxvkAccessOp store = DxvkAccessOp::None;
switch (ins.op) {
case DxbcOpcode::AtomicAnd: store = DxvkAccessOp::And; break;
case DxbcOpcode::AtomicOr: store = DxvkAccessOp::Or; break;
case DxbcOpcode::AtomicXor: store = DxvkAccessOp::Xor; break;
case DxbcOpcode::AtomicIAdd: store = DxvkAccessOp::Add; break;
case DxbcOpcode::AtomicIMax: store = DxvkAccessOp::IMax; break;
case DxbcOpcode::AtomicIMin: store = DxvkAccessOp::IMin; break;
case DxbcOpcode::AtomicUMax: store = DxvkAccessOp::UMax; break;
case DxbcOpcode::AtomicUMin: store = DxvkAccessOp::UMin; break;
default: break;
}
if (m_analysis->uavInfos[registerId].atomicStore == DxvkAccessOp::None)
m_analysis->uavInfos[registerId].atomicStore = store;
// Maintain ordering if the UAV is accessed via other operations as well
if (store == DxvkAccessOp::None || m_analysis->uavInfos[registerId].atomicStore != store)
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
}
} break;
@ -58,6 +80,7 @@ namespace dxvk {
const uint32_t registerId = ins.src[operandId].idx[0].offset;
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
m_analysis->uavInfos[registerId].sparseFeedback |= sparseFeedback;
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
} else if (ins.src[operandId].type == DxbcOperandType::Resource) {
const uint32_t registerId = ins.src[operandId].idx[0].offset;
m_analysis->srvInfos[registerId].sparseFeedback |= sparseFeedback;
@ -68,6 +91,7 @@ namespace dxvk {
if (ins.dst[0].type == DxbcOperandType::UnorderedAccessView) {
const uint32_t registerId = ins.dst[0].idx[0].offset;
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
}
} break;
@ -75,11 +99,13 @@ namespace dxvk {
const uint32_t registerId = ins.src[1].idx[0].offset;
m_analysis->uavInfos[registerId].accessTypedLoad = true;
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
} break;
case DxbcInstClass::TypedUavStore: {
const uint32_t registerId = ins.dst[0].idx[0].offset;
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
} break;
default:

View File

@ -20,6 +20,8 @@ namespace dxvk {
bool accessTypedLoad = false;
bool accessAtomicOp = false;
bool sparseFeedback = false;
bool nonInvariantAccess = false;
DxvkAccessOp atomicStore = DxvkAccessOp::None;
VkAccessFlags accessFlags = 0;
};

View File

@ -1098,6 +1098,9 @@ namespace dxvk {
: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
binding.access = m_analysis->uavInfos[registerId].accessFlags;
if (!m_analysis->uavInfos[registerId].nonInvariantAccess)
binding.accessOp = m_analysis->uavInfos[registerId].atomicStore;
if (!(binding.access & VK_ACCESS_SHADER_WRITE_BIT))
m_module.decorate(varId, spv::DecorationNonWritable);
if (!(binding.access & VK_ACCESS_SHADER_READ_BIT))
@ -1234,9 +1237,14 @@ namespace dxvk {
: (isUav ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
binding.resourceBinding = bindingId;
binding.access = isUav
? m_analysis->uavInfos[registerId].accessFlags
: VkAccessFlags(VK_ACCESS_SHADER_READ_BIT);
binding.access = VK_ACCESS_SHADER_READ_BIT;
if (isUav) {
binding.access = m_analysis->uavInfos[registerId].accessFlags;
if (!m_analysis->uavInfos[registerId].nonInvariantAccess)
binding.accessOp = m_analysis->uavInfos[registerId].atomicStore;
}
if (useRawSsbo || isUav) {
if (!(binding.access & VK_ACCESS_SHADER_WRITE_BIT))