diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index 955039de51..be07dd66c6 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -1391,3 +1391,43 @@ void VulkanContext::GetImageMemoryRequirements(VkImage image, VkMemoryRequiremen *dedicatedAllocation = false; } } + +bool IsHashMaliDriverVersion(const VkPhysicalDeviceProperties &props) { + // ARM used to put a hash in place of the driver version. + // Now they only use major versions. We'll just make a bad heuristic. + uint32_t major = VK_VERSION_MAJOR(props.driverVersion); + uint32_t minor = VK_VERSION_MINOR(props.driverVersion); + uint32_t branch = VK_VERSION_PATCH(props.driverVersion); + if (branch > 0) + return true; + if (branch > 100 || major > 100) + return true; + return false; +} + +// From Sascha's code +std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props) { + if (props.vendorID == VULKAN_VENDOR_NVIDIA) { + // For whatever reason, NVIDIA has their own scheme. + // 10 bits = major version (up to r1023) + // 8 bits = minor version (up to 255) + // 8 bits = secondary branch version/build version (up to 255) + // 6 bits = tertiary branch/build version (up to 63) + uint32_t major = (props.driverVersion >> 22) & 0x3ff; + uint32_t minor = (props.driverVersion >> 14) & 0x0ff; + uint32_t secondaryBranch = (props.driverVersion >> 6) & 0x0ff; + uint32_t tertiaryBranch = (props.driverVersion) & 0x003f; + return StringFromFormat("%d.%d.%d.%d", major, minor, secondaryBranch, tertiaryBranch); + } else if (props.vendorID == VULKAN_VENDOR_ARM) { + // ARM used to just put a hash here. No point in splitting it up. + if (IsHashMaliDriverVersion(props)) { + return StringFromFormat("(hash) %08x", props.driverVersion); + } + } + // Qualcomm has an inscrutable versioning scheme. Let's just display it as normal. + // Standard scheme, use the standard macros. + uint32_t major = VK_VERSION_MAJOR(props.driverVersion); + uint32_t minor = VK_VERSION_MINOR(props.driverVersion); + uint32_t branch = VK_VERSION_PATCH(props.driverVersion); + return StringFromFormat("%d.%d.%d (%08x)", major, minor, branch, props.driverVersion); +} diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index d3ecb96963..63fa5108e7 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -359,3 +359,7 @@ void finalize_glslang(); bool GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std::vector &spirv, std::string *errorMessage = nullptr); const char *VulkanResultToString(VkResult res); +std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props); + +// Simple heuristic. +bool IsHashMaliDriverVersion(const VkPhysicalDeviceProperties &props); diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 0e55bbd84e..5acdc68a43 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -17,6 +17,7 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include + #include "base/logging.h" #include "base/timeutil.h" #include "profiler/profiler.h" @@ -197,12 +198,15 @@ void GPU_Vulkan::CheckGPUFeatures() { features |= GPU_SUPPORTS_ACCURATE_DEPTH; break; case VULKAN_VENDOR_ARM: - // Also required on older ARM Mali drivers, like the one on many Galaxy S7. - if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || - vulkan_->GetPhysicalDeviceProperties().properties.driverVersion <= VK_MAKE_VERSION(428, 811, 2674)) { + { + // This check is probably not exactly accurate. But old drivers had problems with reverse-Z, just like AMD and Qualcomm. + bool driverTooOld = IsHashMaliDriverVersion(vulkan_->GetPhysicalDeviceProperties().properties) + || VK_VERSION_MAJOR(vulkan_->GetPhysicalDeviceProperties().properties.driverVersion) < 14; + if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth || driverTooOld) { features |= GPU_SUPPORTS_ACCURATE_DEPTH; } break; + } default: if (!PSP_CoreParameter().compat.flags().DisableAccurateDepth) features |= GPU_SUPPORTS_ACCURATE_DEPTH; diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 960f224180..dafd15808d 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -429,30 +429,6 @@ public: void FlushState() override {} - // From Sascha's code - static std::string FormatDriverVersion(const VkPhysicalDeviceProperties &props) { - if (props.vendorID == VULKAN_VENDOR_NVIDIA) { - // 10 bits = major version (up to r1023) - // 8 bits = minor version (up to 255) - // 8 bits = secondary branch version/build version (up to 255) - // 6 bits = tertiary branch/build version (up to 63) - uint32_t major = (props.driverVersion >> 22) & 0x3ff; - uint32_t minor = (props.driverVersion >> 14) & 0x0ff; - uint32_t secondaryBranch = (props.driverVersion >> 6) & 0x0ff; - uint32_t tertiaryBranch = (props.driverVersion) & 0x003f; - return StringFromFormat("%d.%d.%d.%d (%08x)", major, minor, secondaryBranch, tertiaryBranch, props.driverVersion); - } else if (props.vendorID == VULKAN_VENDOR_ARM) { - // ARM just puts a hash here, let's just output it as is. - return StringFromFormat("%08x", props.driverVersion); - } else { - // Standard scheme, use the standard macros. - uint32_t major = VK_VERSION_MAJOR(props.driverVersion); - uint32_t minor = VK_VERSION_MINOR(props.driverVersion); - uint32_t branch = VK_VERSION_PATCH(props.driverVersion); - return StringFromFormat("%d.%d.%d (%08x)", major, minor, branch, props.driverVersion); - } - } - std::string GetInfoString(InfoField info) const override { // TODO: Make these actually query the right information switch (info) {