diff --git a/renderdoc/3rdparty/glslang/SPIRV/GlslangToSpv.cpp b/renderdoc/3rdparty/glslang/SPIRV/GlslangToSpv.cpp index 151f98ab6..5993e1631 100644 --- a/renderdoc/3rdparty/glslang/SPIRV/GlslangToSpv.cpp +++ b/renderdoc/3rdparty/glslang/SPIRV/GlslangToSpv.cpp @@ -2720,15 +2720,12 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO bias = true; } - // Temporarily hacked out as it breaks on nvidia's driver - /* // See if the sampler param should really be just the SPV image part if (cracked.fetch) { // a fetch needs to have the image extracted first if (builder.isSampledImage(params.sampler)) params.sampler = builder.createUnaryOp(spv::OpImage, builder.getImageType(params.sampler), params.sampler); } - */ // set the rest of the arguments diff --git a/renderdoc/driver/vulkan/vk_common.h b/renderdoc/driver/vulkan/vk_common.h index 9fcf71935..2af59a625 100644 --- a/renderdoc/driver/vulkan/vk_common.h +++ b/renderdoc/driver/vulkan/vk_common.h @@ -74,6 +74,50 @@ extern const char *VulkanLibraryName; extern const uint32_t AMD_PCI_ID; extern const uint32_t NV_PCI_ID; +class VkDriverInfo +{ +public: + bool IsAMD() { return m_Vendor == AMD; } + bool IsNV() { return m_Vendor == NV; } + uint32_t Major() { return m_Major; } + uint32_t Minor() { return m_Minor; } + uint32_t Patch() { return m_Patch; } + VkDriverInfo(const VkPhysicalDeviceProperties &physProps) + { + if(physProps.vendorID == AMD_PCI_ID) + m_Vendor = AMD; + else if(physProps.vendorID == NV_PCI_ID) + m_Vendor = NV; + + m_Major = VK_VERSION_MAJOR(physProps.driverVersion); + m_Minor = VK_VERSION_MINOR(physProps.driverVersion); + m_Patch = VK_VERSION_PATCH(physProps.driverVersion); + + // nvidia uses its own version packing: + // 10 | 8 | 8 | 6 + // major|minor|secondary_branch|tertiary_branch + if(IsNV()) + { + m_Major = ((uint32_t)(physProps.driverVersion) >> (8 + 8 + 6)) & 0x3ff; + m_Minor = ((uint32_t)(physProps.driverVersion) >> (8 + 6)) & 0x0ff; + + uint32_t secondary = ((uint32_t)(physProps.driverVersion) >> 6) & 0x0ff; + uint32_t tertiary = physProps.driverVersion & 0x03f; + + m_Patch = (secondary << 8) | tertiary; + } + } + +private: + enum + { + AMD, + NV, + } m_Vendor; + + uint32_t m_Major, m_Minor, m_Patch; +}; + // structure for casting to easily iterate and template specialising Serialise struct VkGenericStruct { diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 5a2b8c046..93c8cf323 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -353,8 +353,7 @@ private: const VkPhysicalDeviceFeatures &GetDeviceFeatures() { return m_PhysicalDeviceData.features; } const VkPhysicalDeviceProperties &GetDeviceProps() { return m_PhysicalDeviceData.props; } - bool IsAMD() { return m_PhysicalDeviceData.props.vendorID == AMD_PCI_ID; } - bool IsNV() { return m_PhysicalDeviceData.props.vendorID == NV_PCI_ID; } + VkDriverInfo GetDriverVersion() { return VkDriverInfo(m_PhysicalDeviceData.props); } const VkFormatProperties &GetFormatProperties(VkFormat f) { return m_PhysicalDeviceData.fmtprops[f]; diff --git a/renderdoc/driver/vulkan/vk_debug.cpp b/renderdoc/driver/vulkan/vk_debug.cpp index 371767d61..61aaf4770 100644 --- a/renderdoc/driver/vulkan/vk_debug.cpp +++ b/renderdoc/driver/vulkan/vk_debug.cpp @@ -1433,61 +1433,36 @@ VulkanDebugManager::VulkanDebugManager(WrappedVulkan *driver, VkDevice dev) RDCASSERT(err.empty() && m_FixedColSPIRV); } - // the newest AMD driver (at time of committing) has texelFetch fixed, - // but it came out recently so I want a short transition period with the - // workaround in place while people update. So we just check if we're - // on AMD and look at the modified date of amdvlk32/64.dll. Cheeky! + // A workaround for a couple of bugs, removing texelFetch use from shaders. + // It means broken functionality but at least no instant crashes bool texelFetchBrokenDriver = false; - if(m_pDriver->IsNV()) + VkDriverInfo driverVersion = m_pDriver->GetDriverVersion(); + + if(driverVersion.IsNV()) { - // at time of writing, this isn't fixed on nv, but since we have a workaround - // that is harmless on other IHVs - keep it supported. Once a fixed version is - // out we will use this + a version check to stay working on older drivers. - // texelFetchBrokenDriver = true; + // drivers before 372.54 did not handle a glslang bugfix about separated samplers, + // and disabling texelFetch works as a workaround. + + if(driverVersion.Major() < 372 || (driverVersion.Major() == 372 && driverVersion.Minor() < 54)) + texelFetchBrokenDriver = true; } - if(m_pDriver->IsAMD()) + if(driverVersion.IsAMD()) { - // assume it's broken - texelFetchBrokenDriver = true; + // for AMD the bugfix version isn't clear as version numbering wasn't strong for a while, but + // any driver that reports a version of >= 1.0.0 is fine, as previous versions all reported + // 0.9.0 as the version. -#if defined(RENDERDOC_PLATFORM_WIN32) + if(driverVersion.Major() < 1) + texelFetchBrokenDriver = true; + } -#if defined(RDC64BIT) - const char *moduleName = "amdvlk64.dll"; -#else - const char *moduleName = "amdvlk32.dll"; -#endif - - // can't check version number reported as it's fixed at 0.9.0, so - // we go by module modified timestamp - HMODULE mod = GetModuleHandleA(moduleName); - if(mod) - { - wchar_t curFile[512] = {}; - GetModuleFileNameW(mod, curFile, 512); - - string vlkPath = StringFormat::Wide2UTF8(wstring(curFile)); - - uint64_t timestamp = FileIO::GetModifiedTimestamp(vlkPath); - - // Any driver with modified date after this time (2016-04-17) - // should be fine. - const uint64_t referenceTimestamp = 1460880000; - - if(timestamp > referenceTimestamp) - texelFetchBrokenDriver = false; - else - RDCWARN( - "Detected an older AMD driver, enabling workaround - try updating to the latest " - "version"); - } - else - { - RDCWARN("AMD device detected but can't find %s loaded", moduleName); - } -#endif + if(texelFetchBrokenDriver) + { + RDCWARN( + "Detected an older driver, enabling texelFetch workaround - try updating to the latest " + "version"); } for(size_t i = 0; i < ARRAY_COUNT(module); i++) diff --git a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp index 08e5672d6..6bd6b4963 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_device_funcs.cpp @@ -434,28 +434,6 @@ void WrappedVulkan::vkDestroyInstance(VkInstance instance, const VkAllocationCal m_Instance = VK_NULL_HANDLE; } -static void GetVulkanDriverVersion(const VkPhysicalDeviceProperties &physProps, uint32_t &major, - uint32_t &minor, uint32_t &patch) -{ - major = VK_VERSION_MAJOR(physProps.driverVersion); - minor = VK_VERSION_MINOR(physProps.driverVersion); - patch = VK_VERSION_PATCH(physProps.driverVersion); - - // nvidia uses its own version packing: - // 10 | 8 | 8 | 6 - // major|minor|secondary_branch|tertiary_branch - if(physProps.vendorID == NV_PCI_ID) - { - major = ((uint32_t)(physProps.driverVersion) >> (8 + 8 + 6)) & 0x3ff; - minor = ((uint32_t)(physProps.driverVersion) >> (8 + 6)) & 0x0ff; - - uint32_t secondary = ((uint32_t)(physProps.driverVersion) >> 6) & 0x0ff; - uint32_t tertiary = physProps.driverVersion & 0x03f; - - patch = (secondary << 8) | tertiary; - } -} - bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(Serialiser *localSerialiser, VkInstance instance, uint32_t *pPhysicalDeviceCount, @@ -563,22 +541,22 @@ bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(Serialiser *localSerial memcpy(storedMap, memIdxMap, sizeof(memIdxMap)); m_MemIdxMaps[physIndex] = storedMap; - uint32_t major = 0, minor = 0, patch = 0; - GetVulkanDriverVersion(physProps, major, minor, patch); + VkDriverInfo capturedVersion(physProps); RDCLOG("Captured log describes physical device %u:", physIndex); - RDCLOG(" - %s (ver %u.%u patch 0x%x) - %04x:%04x", physProps.deviceName, major, minor, patch, + RDCLOG(" - %s (ver %u.%u patch 0x%x) - %04x:%04x", physProps.deviceName, + capturedVersion.Major(), capturedVersion.Minor(), capturedVersion.Patch(), physProps.vendorID, physProps.deviceID); ObjDisp(pd)->GetPhysicalDeviceProperties(Unwrap(pd), &physProps); ObjDisp(pd)->GetPhysicalDeviceMemoryProperties(Unwrap(pd), &memProps); ObjDisp(pd)->GetPhysicalDeviceFeatures(Unwrap(pd), &physFeatures); - GetVulkanDriverVersion(physProps, major, minor, patch); + VkDriverInfo runningVersion(physProps); RDCLOG("Replaying on physical device %u:", physIndex); - RDCLOG(" - %s (ver %u.%u patch 0x%x) - %04x:%04x", physProps.deviceName, major, minor, patch, - physProps.vendorID, physProps.deviceID); + RDCLOG(" - %s (ver %u.%u patch 0x%x) - %04x:%04x", physProps.deviceName, runningVersion.Major(), + runningVersion.Minor(), runningVersion.Patch(), physProps.vendorID, physProps.deviceID); } return true;