From c3d19f87f01d3ff86c4418bbd1e735792119b907 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 22 Jun 2021 14:44:56 +0100 Subject: [PATCH] Disable buffer_device_address on older windows Intel drivers --- renderdoc/driver/vulkan/vk_common.cpp | 46 ++++++++++++++----- renderdoc/driver/vulkan/vk_common.h | 16 +++---- renderdoc/driver/vulkan/vk_postvs.cpp | 3 +- .../driver/vulkan/vk_shader_feedback.cpp | 2 +- renderdoc/driver/vulkan/vk_shaderdebug.cpp | 2 +- .../vulkan/wrappers/vk_device_funcs.cpp | 4 +- .../driver/vulkan/wrappers/vk_get_funcs.cpp | 4 +- 7 files changed, 48 insertions(+), 29 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_common.cpp b/renderdoc/driver/vulkan/vk_common.cpp index 9522be412..d489e2441 100644 --- a/renderdoc/driver/vulkan/vk_common.cpp +++ b/renderdoc/driver/vulkan/vk_common.cpp @@ -875,7 +875,7 @@ void DoSerialise(SerialiserType &ser, VkInitParams &el) INSTANTIATE_SERIALISE_TYPE(VkInitParams); -VkDriverInfo::VkDriverInfo(const VkPhysicalDeviceProperties &physProps) +VkDriverInfo::VkDriverInfo(const VkPhysicalDeviceProperties &physProps, bool active) { m_Vendor = GPUVendorFromPCIVendor(physProps.vendorID); @@ -932,7 +932,8 @@ VkDriverInfo::VkDriverInfo(const VkPhysicalDeviceProperties &physProps) if(Major() < 372 || (Major() == 372 && Minor() < 54)) { - RDCLOG("Enabling NV texel fetch workaround - update to a newer driver for fix"); + if(active) + RDCLOG("Enabling NV texel fetch workaround - update to a newer driver for fix"); texelFetchBrokenDriver = true; } } @@ -949,43 +950,66 @@ VkDriverInfo::VkDriverInfo(const VkPhysicalDeviceProperties &physProps) if(Major() < 1) { - RDCLOG("Enabling AMD texel fetch workaround - update to a newer driver for fix"); + if(active) + RDCLOG("Enabling AMD texel fetch workaround - update to a newer driver for fix"); texelFetchBrokenDriver = true; } // driver 18.5.2 which is vulkan version >= 2.0.33 contains the fix if(physProps.driverVersion < VK_MAKE_VERSION(2, 0, 33)) { - RDCLOG( - "Enabling AMD image memory requirements workaround - update to a newer driver for fix"); - unreliableImgMemReqs = true; + if(active) + RDCLOG( + "Enabling AMD image memory requirements workaround - update to a newer driver for fix"); + amdUnreliableImgMemReqs = true; } // driver 18.5.2 which is vulkan version >= 2.0.33 contains the fix if(physProps.driverVersion < VK_MAKE_VERSION(2, 0, 33)) { - RDCLOG("Enabling AMD image MSAA storage workaround - update to a newer driver for fix"); + if(active) + RDCLOG("Enabling AMD image MSAA storage workaround - update to a newer driver for fix"); amdStorageMSAABrokenDriver = true; } // driver 21.3.1 which is vulkan version >= 2.0.179 contains the fix if(physProps.driverVersion < VK_MAKE_VERSION(2, 0, 179)) { - RDCLOG("Disabling buffer_device_address on AMD - update to a newer driver for fix"); - amdBDABrokenDriver = true; + if(active) + RDCLOG("Disabling buffer_device_address on AMD - update to a newer driver for fix"); + bdaBrokenDriver = true; + } + } +#endif + +// Intel windows workarounds +#if ENABLED(RDOC_WIN32) + if(m_Vendor == GPUVendor::Intel) + { + // buffer device address doesn't work well on older drivers, even using it internally we get + // VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS thrown when creating multiple buffers, even though we + // don't provide opaque capture addresses at all... + // seems fixed in 100.9466. Intel's driver versioning is inconsistent and some drivers don't + // follow this scheme, but they also seem old? + if(m_Major <= 100 && m_Minor < 9466) + { + if(active) + RDCLOG("Disabling buffer_device_address on Intel - update to a newer driver for fix"); + bdaBrokenDriver = true; } } #endif if(m_Vendor == GPUVendor::Qualcomm) { - RDCLOG("Enabling Qualcomm driver workarounds"); + if(active) + RDCLOG("Enabling Qualcomm driver workarounds"); // not fixed yet that I know of, or unknown driver with fixes qualcommLeakingUBOOffsets = true; qualcommDrefNon2DCompileCrash = true; qualcommLineWidthCrash = true; - qualcommBDABrokenDriver = true; + bdaBrokenDriver = true; } } diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 705d1ed80..d05f45aec 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -227,18 +227,20 @@ public: uint32_t Major() { return m_Major; } uint32_t Minor() { return m_Minor; } uint32_t Patch() { return m_Patch; } - VkDriverInfo(const VkPhysicalDeviceProperties &physProps); + VkDriverInfo(const VkPhysicalDeviceProperties &physProps, bool active = false); // checks for when we're running on metal and some non-queryable things aren't supported bool RunningOnMetal() const { return metalBackend; } // A workaround for a couple of bugs, removing texelFetch use from shaders. // It means broken functionality but at least no instant crashes bool TexelFetchBrokenDriver() const { return texelFetchBrokenDriver; } + // Many drivers have issues with KHR_buffer_device_address :( + bool BufferDeviceAddressBrokenDriver() const { return bdaBrokenDriver; } // Older AMD driver versions could sometimes cause image memory requirements to vary randomly // between identical images. This means the memory required at capture could be less than at // replay. To counteract this, on drivers with this issue we pad out the memory requirements // enough to account for the change - bool UnreliableImageMemoryRequirements() const { return unreliableImgMemReqs; } + bool AMDUnreliableImageMemoryRequirements() const { return amdUnreliableImgMemReqs; } // another workaround, on some AMD driver versions creating an MSAA image with STORAGE_BIT // causes graphical corruption trying to sample from it. We workaround it by preventing the // MSAA <-> Array pipelines from creating, which removes the STORAGE_BIT and skips the copies. @@ -257,11 +259,6 @@ public: // hit the case where it's necessary (doing 'whole pass' partial replay of a subsection of a // command buffer where we need to apply dynamic state from earlier in the command buffer). bool QualcommLineWidthDynamicStateCrash() const { return qualcommLineWidthCrash; } - // Qualcomm's driver seems to crash when using buffer_device_address. - bool QualcommLineBufferDeviceAddressBrokenDriver() const { return qualcommBDABrokenDriver; } - // On AMD unfortunately the initial implementation of KHR_buffer_device_address is broken and - // produces bad results. - bool AMDBufferDeviceAddressBrokenDriver() const { return amdBDABrokenDriver; } private: GPUVendor m_Vendor; @@ -269,13 +266,12 @@ private: bool metalBackend = false; bool texelFetchBrokenDriver = false; - bool unreliableImgMemReqs = false; + bool bdaBrokenDriver = false; + bool amdUnreliableImgMemReqs = false; bool amdStorageMSAABrokenDriver = false; bool qualcommLeakingUBOOffsets = false; bool qualcommDrefNon2DCompileCrash = false; bool qualcommLineWidthCrash = false; - bool amdBDABrokenDriver = false; - bool qualcommBDABrokenDriver = false; }; enum diff --git a/renderdoc/driver/vulkan/vk_postvs.cpp b/renderdoc/driver/vulkan/vk_postvs.cpp index 275293a2a..248889053 100644 --- a/renderdoc/driver/vulkan/vk_postvs.cpp +++ b/renderdoc/driver/vulkan/vk_postvs.cpp @@ -1492,8 +1492,7 @@ void VulkanReplay::FetchVSOut(uint32_t eventId, VulkanRenderState &state) } if(Vulkan_Debug_DisableBufferDeviceAddress() || - m_pDriver->GetDriverInfo().AMDBufferDeviceAddressBrokenDriver() || - m_pDriver->GetDriverInfo().QualcommLineBufferDeviceAddressBrokenDriver()) + m_pDriver->GetDriverInfo().BufferDeviceAddressBrokenDriver()) storageMode = Binding; if(m_pDriver->GetDeviceProps().limits.maxPerStageDescriptorStorageBuffers - 2 < diff --git a/renderdoc/driver/vulkan/vk_shader_feedback.cpp b/renderdoc/driver/vulkan/vk_shader_feedback.cpp index 59e51722a..fedde7301 100644 --- a/renderdoc/driver/vulkan/vk_shader_feedback.cpp +++ b/renderdoc/driver/vulkan/vk_shader_feedback.cpp @@ -1312,7 +1312,7 @@ void VulkanReplay::FetchShaderFeedback(uint32_t eventId) m_pDriver->GetDeviceEnabledFeatures().shaderInt64; if(Vulkan_Debug_DisableBufferDeviceAddress() || - m_pDriver->GetDriverInfo().AMDBufferDeviceAddressBrokenDriver()) + m_pDriver->GetDriverInfo().BufferDeviceAddressBrokenDriver()) useBufferAddress = false; bool useBufferAddressKHR = m_pDriver->GetExtensions(NULL).ext_KHR_buffer_device_address; diff --git a/renderdoc/driver/vulkan/vk_shaderdebug.cpp b/renderdoc/driver/vulkan/vk_shaderdebug.cpp index 438c7c2be..aa3ee5b52 100644 --- a/renderdoc/driver/vulkan/vk_shaderdebug.cpp +++ b/renderdoc/driver/vulkan/vk_shaderdebug.cpp @@ -4079,7 +4079,7 @@ ShaderDebugTrace *VulkanReplay::DebugPixel(uint32_t eventId, uint32_t x, uint32_ } if(Vulkan_Debug_DisableBufferDeviceAddress() || - m_pDriver->GetDriverInfo().AMDBufferDeviceAddressBrokenDriver()) + m_pDriver->GetDriverInfo().BufferDeviceAddressBrokenDriver()) storageMode = Binding; rdcarray fragspv = shader.spirv.GetSPIRV(); diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 37f75edcb..a38b20255 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -3375,7 +3375,7 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi ->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.availFeatures); m_PhysicalDeviceData.enabledFeatures = enabledFeatures; - m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props); + m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props, true); m_Replay->SetDriverInformation(m_PhysicalDeviceData.props); @@ -3819,7 +3819,7 @@ VkResult WrappedVulkan::vkCreateDevice(VkPhysicalDevice physicalDevice, ->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.availFeatures); m_PhysicalDeviceData.enabledFeatures = enabledFeatures; - m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props); + m_PhysicalDeviceData.driverInfo = VkDriverInfo(m_PhysicalDeviceData.props, true); ChooseMemoryIndices(); diff --git a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp index 62c5aac33..76dfa08ee 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp @@ -251,7 +251,7 @@ void WrappedVulkan::vkGetImageMemoryRequirements(VkDevice device, VkImage image, // allow for this. The variability isn't quite clear, but for now we assume aligning size to // alignment * 4 should be sufficient (adding on a fixed padding won't help the problem as it // won't remove the variability, nor will adding then aligning for the same reason). - if(GetDriverInfo().UnreliableImageMemoryRequirements() && pMemoryRequirements->size > 0) + if(GetDriverInfo().AMDUnreliableImageMemoryRequirements() && pMemoryRequirements->size > 0) { VkMemoryRequirements &memreq = *pMemoryRequirements; @@ -317,7 +317,7 @@ void WrappedVulkan::vkGetImageMemoryRequirements2(VkDevice device, // allow for this. The variability isn't quite clear, but for now we assume aligning size to // alignment * 4 should be sufficient (adding on a fixed padding won't help the problem as it // won't remove the variability, nor will adding then aligning for the same reason). - if(GetDriverInfo().UnreliableImageMemoryRequirements() && + if(GetDriverInfo().AMDUnreliableImageMemoryRequirements() && pMemoryRequirements->memoryRequirements.size > 0) { VkMemoryRequirements &memreq = pMemoryRequirements->memoryRequirements;