Add workaround for NV descriptor buffer bug

This commit is contained in:
baldurk
2025-06-12 11:11:48 +01:00
parent 9c259e8ccf
commit 30cfee6f2b
3 changed files with 24 additions and 0 deletions
+8
View File
@@ -1277,6 +1277,14 @@ VkDriverInfo::VkDriverInfo(const VkPhysicalDeviceProperties &physProps,
if(active)
RDCLOG("Enabling NV workaround for unaligned BDA memory capture/replay");
nvidiaUnalignedBDAIssue = true;
// this was found in the initial implementation, if mesh output is fetched and a user descriptor
// set has no vertex bindings at all (and they're not also compute bindings) then a descriptor
// set layout devoid of any compute bindings being bound causes problems. To fix this we set one
// binding visible to all stages in every descriptor set layout.
if(active)
RDCLOG("Enabling NV workaround for descriptor buffers to preserve compute bindings");
nvidiaDescriptorBufferExtraBinding = true;
}
if(driverProps.driverID == VK_DRIVER_ID_AMD_PROPRIETARY ||
+6
View File
@@ -378,6 +378,11 @@ public:
// this is believed to be a windows bug currently, it only manifests on NV and a workaround will
// be arriving in later NV drivers, so for now we treat this as a driver bug.
bool NVUnalignedBDAIssue() const { return nvidiaUnalignedBDAIssue; }
// on NV there is an issue with descriptor buffer bindings where if a descriptor set being set as
// an offset has no bindings for compute whatsoever but is bound to the compute pipeline, it will
// break other descriptor sets. As a workaround we make the first binding of all descriptor
// set layouts have all-stages visibility
bool NVDescriptorBufferExtraBinding() const { return nvidiaDescriptorBufferExtraBinding; }
private:
GPUVendor m_Vendor;
@@ -395,6 +400,7 @@ private:
bool nvidiaStaticPipelineRebindStates = false;
bool maliBrokenASDeviceSerialisation = false;
bool nvidiaUnalignedBDAIssue = false;
bool nvidiaDescriptorBufferExtraBinding = false;
};
struct DynamicRenderingLocalRead
@@ -390,6 +390,16 @@ bool WrappedVulkan::Serialise_vkCreateDescriptorSetLayout(
}
}
if(m_DescriptorBuffers && GetDriverInfo().NVDescriptorBufferExtraBinding() &&
(unwrapped.flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT))
{
if(unwrapped.bindingCount > 0)
{
VkDescriptorSetLayoutBinding &bind = (VkDescriptorSetLayoutBinding &)unwrapped.pBindings[0];
bind.stageFlags |= VK_SHADER_STAGE_COMPUTE_BIT;
}
}
VkResult ret =
ObjDisp(device)->CreateDescriptorSetLayout(Unwrap(device), &unwrapped, NULL, &layout);