mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-04-05 16:40:17 +02:00
[dxbc] Track bindings with order-invariant atomic stores
This commit is contained in:
parent
d94e3633dc
commit
e01a6eec3e
@ -30,26 +30,48 @@ namespace dxvk {
|
|||||||
switch (ins.opClass) {
|
switch (ins.opClass) {
|
||||||
case DxbcInstClass::Atomic: {
|
case DxbcInstClass::Atomic: {
|
||||||
const uint32_t operandId = ins.dstCount - 1;
|
const uint32_t operandId = ins.dstCount - 1;
|
||||||
|
|
||||||
if (ins.dst[operandId].type == DxbcOperandType::UnorderedAccessView) {
|
if (ins.dst[operandId].type == DxbcOperandType::UnorderedAccessView) {
|
||||||
const uint32_t registerId = ins.dst[operandId].idx[0].offset;
|
const uint32_t registerId = ins.dst[operandId].idx[0].offset;
|
||||||
m_analysis->uavInfos[registerId].accessAtomicOp = true;
|
m_analysis->uavInfos[registerId].accessAtomicOp = true;
|
||||||
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
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;
|
} break;
|
||||||
|
|
||||||
case DxbcInstClass::TextureSample:
|
case DxbcInstClass::TextureSample:
|
||||||
case DxbcInstClass::TextureGather:
|
case DxbcInstClass::TextureGather:
|
||||||
case DxbcInstClass::TextureQueryLod:
|
case DxbcInstClass::TextureQueryLod:
|
||||||
case DxbcInstClass::VectorDeriv: {
|
case DxbcInstClass::VectorDeriv: {
|
||||||
m_analysis->usesDerivatives = true;
|
m_analysis->usesDerivatives = true;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DxbcInstClass::ControlFlow: {
|
case DxbcInstClass::ControlFlow: {
|
||||||
if (ins.op == DxbcOpcode::Discard)
|
if (ins.op == DxbcOpcode::Discard)
|
||||||
m_analysis->usesKill = true;
|
m_analysis->usesKill = true;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DxbcInstClass::BufferLoad: {
|
case DxbcInstClass::BufferLoad: {
|
||||||
uint32_t operandId = ins.op == DxbcOpcode::LdStructured ? 2 : 1;
|
uint32_t operandId = ins.op == DxbcOpcode::LdStructured ? 2 : 1;
|
||||||
bool sparseFeedback = ins.dstCount == 2;
|
bool sparseFeedback = ins.dstCount == 2;
|
||||||
@ -58,16 +80,18 @@ namespace dxvk {
|
|||||||
const uint32_t registerId = ins.src[operandId].idx[0].offset;
|
const uint32_t registerId = ins.src[operandId].idx[0].offset;
|
||||||
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
|
||||||
m_analysis->uavInfos[registerId].sparseFeedback |= sparseFeedback;
|
m_analysis->uavInfos[registerId].sparseFeedback |= sparseFeedback;
|
||||||
|
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
|
||||||
} else if (ins.src[operandId].type == DxbcOperandType::Resource) {
|
} else if (ins.src[operandId].type == DxbcOperandType::Resource) {
|
||||||
const uint32_t registerId = ins.src[operandId].idx[0].offset;
|
const uint32_t registerId = ins.src[operandId].idx[0].offset;
|
||||||
m_analysis->srvInfos[registerId].sparseFeedback |= sparseFeedback;
|
m_analysis->srvInfos[registerId].sparseFeedback |= sparseFeedback;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DxbcInstClass::BufferStore: {
|
case DxbcInstClass::BufferStore: {
|
||||||
if (ins.dst[0].type == DxbcOperandType::UnorderedAccessView) {
|
if (ins.dst[0].type == DxbcOperandType::UnorderedAccessView) {
|
||||||
const uint32_t registerId = ins.dst[0].idx[0].offset;
|
const uint32_t registerId = ins.dst[0].idx[0].offset;
|
||||||
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
|
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -75,13 +99,15 @@ namespace dxvk {
|
|||||||
const uint32_t registerId = ins.src[1].idx[0].offset;
|
const uint32_t registerId = ins.src[1].idx[0].offset;
|
||||||
m_analysis->uavInfos[registerId].accessTypedLoad = true;
|
m_analysis->uavInfos[registerId].accessTypedLoad = true;
|
||||||
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
|
||||||
|
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case DxbcInstClass::TypedUavStore: {
|
case DxbcInstClass::TypedUavStore: {
|
||||||
const uint32_t registerId = ins.dst[0].idx[0].offset;
|
const uint32_t registerId = ins.dst[0].idx[0].offset;
|
||||||
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
|
||||||
|
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,11 @@ namespace dxvk {
|
|||||||
* will be used to generate image types.
|
* will be used to generate image types.
|
||||||
*/
|
*/
|
||||||
struct DxbcUavInfo {
|
struct DxbcUavInfo {
|
||||||
bool accessTypedLoad = false;
|
bool accessTypedLoad = false;
|
||||||
bool accessAtomicOp = false;
|
bool accessAtomicOp = false;
|
||||||
bool sparseFeedback = false;
|
bool sparseFeedback = false;
|
||||||
|
bool nonInvariantAccess = false;
|
||||||
|
DxvkAccessOp atomicStore = DxvkAccessOp::None;
|
||||||
VkAccessFlags accessFlags = 0;
|
VkAccessFlags accessFlags = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1098,6 +1098,9 @@ namespace dxvk {
|
|||||||
: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
binding.access = m_analysis->uavInfos[registerId].accessFlags;
|
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))
|
if (!(binding.access & VK_ACCESS_SHADER_WRITE_BIT))
|
||||||
m_module.decorate(varId, spv::DecorationNonWritable);
|
m_module.decorate(varId, spv::DecorationNonWritable);
|
||||||
if (!(binding.access & VK_ACCESS_SHADER_READ_BIT))
|
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);
|
: (isUav ? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
|
||||||
binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
|
binding.viewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
|
||||||
binding.resourceBinding = bindingId;
|
binding.resourceBinding = bindingId;
|
||||||
binding.access = isUav
|
binding.access = VK_ACCESS_SHADER_READ_BIT;
|
||||||
? m_analysis->uavInfos[registerId].accessFlags
|
|
||||||
: VkAccessFlags(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 (useRawSsbo || isUav) {
|
||||||
if (!(binding.access & VK_ACCESS_SHADER_WRITE_BIT))
|
if (!(binding.access & VK_ACCESS_SHADER_WRITE_BIT))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user