1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-17 17:52:11 +01:00

[dxbc] Accurately determine access flags for UAVs

This commit is contained in:
Philip Rebohle 2021-09-09 15:39:35 +02:00
parent c9f7ccc7f9
commit 5db76784bd
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 40 additions and 16 deletions

View File

@ -34,6 +34,7 @@ namespace dxvk {
if (ins.dst[operandId].type == DxbcOperandType::UnorderedAccessView) {
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;
}
} break;
@ -49,9 +50,31 @@ namespace dxvk {
m_analysis->usesKill = true;
} break;
case DxbcInstClass::BufferLoad: {
uint32_t operandId = ins.op == DxbcOpcode::LdStructured ? 2 : 1;
if (ins.src[operandId].type == DxbcOperandType::UnorderedAccessView) {
const uint32_t registerId = ins.src[operandId].idx[0].offset;
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
}
} break;
case DxbcInstClass::BufferStore: {
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;
}
} break;
case DxbcInstClass::TypedUavLoad: {
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;
} break;
case DxbcInstClass::TypedUavStore: {
const uint32_t registerId = ins.dst[0].idx[0].offset;
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
} break;
default:

View File

@ -19,6 +19,7 @@ namespace dxvk {
struct DxbcUavInfo {
bool accessTypedLoad = false;
bool accessAtomicOp = false;
VkAccessFlags accessFlags = 0;
};
/**

View File

@ -1003,12 +1003,6 @@ namespace dxvk {
if (ins.controls.uavFlags().test(DxbcUavFlag::GloballyCoherent))
m_module.decorate(varId, spv::DecorationCoherent);
// On GPUs which don't support storageImageReadWithoutFormat,
// we have to decorate untyped UAVs as write-only
if (isUav && imageFormat == spv::ImageFormatUnknown
&& !m_moduleInfo.options.useStorageImageReadWithoutFormat)
m_module.decorate(varId, spv::DecorationNonReadable);
// Declare a specialization constant which will
// store whether or not the resource is bound.
const uint32_t specConstId = m_module.specConstBool(true);
@ -1060,19 +1054,24 @@ namespace dxvk {
DxvkResourceSlot resource;
resource.slot = bindingId;
resource.view = typeInfo.vtype;
resource.access = VK_ACCESS_SHADER_READ_BIT;
if (isUav) {
resource.type = resourceType == DxbcResourceDim::Buffer
? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
resource.access |= VK_ACCESS_SHADER_WRITE_BIT;
resource.access = m_analysis->uavInfos[registerId].accessFlags;
} else {
resource.type = resourceType == DxbcResourceDim::Buffer
? VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
resource.access = VK_ACCESS_SHADER_READ_BIT;
}
if (!(resource.access & VK_ACCESS_SHADER_WRITE_BIT))
m_module.decorate(varId, spv::DecorationNonWritable);
if (!(resource.access & VK_ACCESS_SHADER_READ_BIT))
m_module.decorate(varId, spv::DecorationNonReadable);
m_resourceSlots.push_back(resource);
}
@ -1137,9 +1136,6 @@ namespace dxvk {
m_module.setDebugName(structType,
str::format(isUav ? "u" : "t", registerId, "_t").c_str());
m_module.setDebugMemberName(structType, 0, "m");
if (!isUav)
m_module.decorate(varId, spv::DecorationNonWritable);
} else {
// Structured and raw buffers are represented as
// texel buffers consisting of 32-bit integers.
@ -1210,10 +1206,14 @@ namespace dxvk {
? VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
: VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER);
resource.view = VK_IMAGE_VIEW_TYPE_MAX_ENUM;
resource.access = VK_ACCESS_SHADER_READ_BIT;
resource.access = isUav
? m_analysis->uavInfos[registerId].accessFlags
: VK_ACCESS_SHADER_READ_BIT;
if (isUav)
resource.access |= VK_ACCESS_SHADER_WRITE_BIT;
if (!(resource.access & VK_ACCESS_SHADER_WRITE_BIT))
m_module.decorate(varId, spv::DecorationNonWritable);
if (!(resource.access & VK_ACCESS_SHADER_READ_BIT))
m_module.decorate(varId, spv::DecorationNonReadable);
m_resourceSlots.push_back(resource);
}

View File

@ -4939,7 +4939,7 @@ namespace dxvk {
// Skip write-after-write barriers if explicitly requested
if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite))
&& (m_execBarriers.getSrcStages() == VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT)
&& (srcAccess == DxvkAccess::Write) && (dstAccess == DxvkAccess::Write))
&& ((srcAccess | dstAccess) == DxvkAccess::Write))
continue;
requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write);
@ -5133,7 +5133,7 @@ namespace dxvk {
// Skip write-after-write barriers if explicitly requested
if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite))
&& (srcAccess == DxvkAccess::Write) && (dstAccess == DxvkAccess::Write))
&& ((srcAccess | dstAccess) == DxvkAccess::Write))
continue;
requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write);