diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index cf5765e12..133f7b2f2 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -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 || diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 9b5e5e7ec..ea3fcbff1 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -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 diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index 65f1c5393..51028866c 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -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);