diff --git a/Source/Core/VideoBackends/Metal/MTLUtil.mm b/Source/Core/VideoBackends/Metal/MTLUtil.mm index ed50d7773f..987d36cbfc 100644 --- a/Source/Core/VideoBackends/Metal/MTLUtil.mm +++ b/Source/Core/VideoBackends/Metal/MTLUtil.mm @@ -245,8 +245,6 @@ void Metal::Util::PopulateBackendInfoFeatures(VideoConfig* config, id [device supportsFamily:MTLGPUFamilyMac2] || [device supportsFamily:MTLGPUFamilyApple6]; config->backend_info.bSupportsFramebufferFetch = [device supportsFamily:MTLGPUFamilyApple1]; } - if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_SUBGROUP_OPS)) - g_features.subgroup_ops = false; #if TARGET_OS_OSX if (@available(macOS 11, *)) if (vendor == DriverDetails::VENDOR_INTEL) @@ -434,6 +432,13 @@ std::optional Metal::Util::TranslateShaderToMSL(ShaderStage stage, full_source.append(header); if (Metal::g_features.subgroup_ops) full_source.append(SUBGROUP_HELPER_HEADER); + if (DriverDetails::HasBug(DriverDetails::BUG_INVERTED_IS_HELPER)) + { + full_source.append("#define gl_HelperInvocation !gl_HelperInvocation " + "// Work around broken AMD Metal driver\n"); + } + if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_SUBGROUP_OPS_WITH_DISCARD)) + full_source.append("#define BROKEN_SUBGROUP_WITH_DISCARD 1\n"); full_source.append(source); std::optional code; diff --git a/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp b/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp index ab9b015cec..86826f7280 100644 --- a/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp +++ b/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp @@ -7,6 +7,7 @@ #include #include "VideoBackends/Vulkan/VulkanContext.h" +#include "VideoCommon/DriverDetails.h" #include "VideoCommon/Spirv.h" namespace Vulkan::ShaderCompiler @@ -98,6 +99,13 @@ static std::string GetShaderCode(std::string_view source, std::string_view heade full_source_code.append(header); if (g_vulkan_context->SupportsShaderSubgroupOperations()) full_source_code.append(SUBGROUP_HELPER_HEADER, subgroup_helper_header_length); + if (DriverDetails::HasBug(DriverDetails::BUG_INVERTED_IS_HELPER)) + { + full_source_code.append("#define gl_HelperInvocation !gl_HelperInvocation " + "// Work around broken AMD Metal driver\n"); + } + if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_SUBGROUP_OPS_WITH_DISCARD)) + full_source_code.append("#define BROKEN_SUBGROUP_WITH_DISCARD 1\n"); full_source_code.append(source); } diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index 7e53a02d7a..318f8f9103 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -1000,8 +1000,7 @@ void VulkanContext::PopulateShaderSubgroupSupport() VK_SUBGROUP_FEATURE_BALLOT_BIT | VK_SUBGROUP_FEATURE_SHUFFLE_BIT; m_supports_shader_subgroup_operations = (subgroup_properties.supportedOperations & required_operations) == required_operations && - subgroup_properties.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT && - !DriverDetails::HasBug(DriverDetails::BUG_BROKEN_SUBGROUP_OPS); + subgroup_properties.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT; } bool VulkanContext::SupportsExclusiveFullscreen(const WindowSystemInfo& wsi, VkSurfaceKHR surface) diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index e217c9d530..351a673414 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -130,14 +130,14 @@ constexpr BugInfo m_known_bugs[] = { -1.0, -1.0, true}, {API_VULKAN, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKEN_VECTOR_BITWISE_AND, -1.0, -1.0, true}, - {API_VULKAN, OS_OSX, VENDOR_ATI, DRIVER_PORTABILITY, Family::UNKNOWN, BUG_BROKEN_SUBGROUP_OPS, + {API_VULKAN, OS_OSX, VENDOR_ATI, DRIVER_PORTABILITY, Family::UNKNOWN, BUG_INVERTED_IS_HELPER, -1.0, -1.0, true}, - {API_VULKAN, OS_OSX, VENDOR_INTEL, DRIVER_PORTABILITY, Family::UNKNOWN, BUG_BROKEN_SUBGROUP_OPS, - -1.0, -1.0, true}, - {API_METAL, OS_OSX, VENDOR_ATI, DRIVER_APPLE, Family::UNKNOWN, BUG_BROKEN_SUBGROUP_OPS, -1.0, - -1.0, true}, - {API_METAL, OS_OSX, VENDOR_INTEL, DRIVER_APPLE, Family::UNKNOWN, BUG_BROKEN_SUBGROUP_OPS, -1.0, + {API_METAL, OS_OSX, VENDOR_ATI, DRIVER_APPLE, Family::UNKNOWN, BUG_INVERTED_IS_HELPER, -1.0, -1.0, true}, + {API_VULKAN, OS_OSX, VENDOR_INTEL, DRIVER_PORTABILITY, Family::UNKNOWN, + BUG_BROKEN_SUBGROUP_OPS_WITH_DISCARD, -1.0, -1.0, true}, + {API_METAL, OS_OSX, VENDOR_INTEL, DRIVER_APPLE, Family::UNKNOWN, + BUG_BROKEN_SUBGROUP_OPS_WITH_DISCARD, -1.0, -1.0, true}, {API_OPENGL, OS_ANDROID, VENDOR_ALL, DRIVER_ALL, Family::UNKNOWN, BUG_BROKEN_MULTITHREADED_SHADER_PRECOMPILATION, -1.0, -1.0, true}, {API_VULKAN, OS_ANDROID, VENDOR_ALL, DRIVER_ALL, Family::UNKNOWN, diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index bc5daa8c31..64ff4b89af 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -299,14 +299,23 @@ enum Bug // BUG: Accessing gl_SubgroupInvocationID causes the Metal shader compiler to crash. // Affected devices: AMD (older macOS) - // BUG: gl_HelperInvocation always returns true, even for non-helper invocations - // Affected devices: AMD (newer macOS) + // Started version: ??? + // Ended version: ??? + // (Workaround currently disabled, will put it back when someone hits the issue and we can + // find out what devices and OSes it actually affects) + // BUG: Using subgroupMax in a shader that can discard results in garbage data // (For some reason, this only happens at 4x+ IR on Metal, but 2x+ IR on MoltenVK) // Affected devices: Intel (macOS) // Started version: -1 // Ended version: -1 - BUG_BROKEN_SUBGROUP_OPS, + BUG_BROKEN_SUBGROUP_OPS_WITH_DISCARD, + + // BUG: gl_HelperInvocation is actually !gl_HelperInvocation + // Affected devices: AMD (macOS) + // Started version: -1 + // Ended version: -1 + BUG_INVERTED_IS_HELPER, // BUG: Multi-threaded shader pre-compilation sometimes crashes // Used primarily in Videoconfig.cpp's GetNumAutoShaderPreCompilerThreads() diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index fff2374531..aa364c7e0f 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -485,7 +485,7 @@ void UpdateBoundingBox(float2 rawpos) {{ int2 pos_tl = pos & ~1; // round down to even int2 pos_br = pos | 1; // round up to odd -#ifdef SUPPORTS_SUBGROUP_REDUCTION +#if defined(SUPPORTS_SUBGROUP_REDUCTION) && !defined(BROKEN_SUBGROUP_WITH_DISCARD) if (!IS_HELPER_INVOCATION) {{ SUBGROUP_MIN(pos_tl);