diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index cde3291767fc..3a37ba24d8be 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -142,26 +142,6 @@ GPU_GLES::~GPU_GLES() { delete textureCacheGL_; } -static constexpr int MakeIntelSimpleVer(int v1, int v2, int v3) { - return (v1 << 16) | (v2 << 8) | v3; -} - -static bool HasIntelDualSrcBug(int versions[4]) { - // Intel uses a confusing set of at least 3 version numbering schemes. This is the one given to OpenGL. - switch (MakeIntelSimpleVer(versions[0], versions[1], versions[2])) { - case MakeIntelSimpleVer(9, 17, 10): - case MakeIntelSimpleVer(9, 18, 10): - return false; - case MakeIntelSimpleVer(10, 18, 10): - return versions[3] < 4061; - case MakeIntelSimpleVer(10, 18, 14): - return versions[3] < 4080; - default: - // Older than above didn't support dual src anyway, newer should have the fix. - return false; - } -} - // Take the raw GL extension and versioning data and turn into feature flags. void GPU_GLES::CheckGPUFeatures() { u32 features = 0; @@ -170,21 +150,7 @@ void GPU_GLES::CheckGPUFeatures() { features |= GPU_SUPPORTS_VS_RANGE_CULLING; if (gl_extensions.ARB_blend_func_extended || gl_extensions.EXT_blend_func_extended) { - if (!gl_extensions.VersionGEThan(3, 0, 0)) { - // Don't use this extension on sub 3.0 OpenGL versions as it does not seem reliable - } else if (gl_extensions.gpuVendor == GPU_VENDOR_INTEL) { - // Also on Intel, see https://github.com/hrydgard/ppsspp/issues/10117 - // TODO: Remove entirely sometime reasonably far in driver years after 2015. - const std::string ver = draw_->GetInfoString(Draw::InfoField::APIVERSION); - int versions[4]{}; - if (sscanf(ver.c_str(), "Build %d.%d.%d.%d", &versions[0], &versions[1], &versions[2], &versions[3]) == 4) { - if (!HasIntelDualSrcBug(versions)) { - features |= GPU_SUPPORTS_DUALSOURCE_BLEND; - } - } else { - features |= GPU_SUPPORTS_DUALSOURCE_BLEND; - } - } else { + if (!g_Config.bVendorBugChecksEnabled || !draw_->GetBugs().Has(Draw::Bugs::DUAL_SOURCE_BLENDING_BROKEN)) { features |= GPU_SUPPORTS_DUALSOURCE_BLEND; } } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 48d287e571c1..286195898b2c 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -224,23 +224,9 @@ void GPU_Vulkan::CheckGPUFeatures() { features |= GPU_SUPPORTS_DEPTH_CLAMP; } if (vulkan_->GetFeaturesEnabled().dualSrcBlend) { - switch (vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).vendorID) { - // We thought we had a bug here on nVidia but turns out we accidentally #ifdef-ed out crucial - // code on Android. - case VULKAN_VENDOR_INTEL: - // Workaround for Intel driver bug. TODO: Re-enable after some driver version - break; - case VULKAN_VENDOR_AMD: - // See issue #10074, and also #10065 (AMD) and #10109 for the choice of the driver version to check for - if (vulkan_->GetPhysicalDeviceProperties(vulkan_->GetCurrentPhysicalDevice()).driverVersion >= 0x00407000) - features |= GPU_SUPPORTS_DUALSOURCE_BLEND; - break; - default: + if (!g_Config.bVendorBugChecksEnabled || !draw_->GetBugs().Has(Draw::Bugs::DUAL_SOURCE_BLENDING_BROKEN)) { features |= GPU_SUPPORTS_DUALSOURCE_BLEND; - break; } - if (!g_Config.bVendorBugChecksEnabled) - features |= GPU_SUPPORTS_DUALSOURCE_BLEND; } if (vulkan_->GetFeaturesEnabled().logicOp) { features |= GPU_SUPPORTS_LOGIC_OP; diff --git a/ext/native/thin3d/thin3d.h b/ext/native/thin3d/thin3d.h index 07b19c08e8b5..8e8f5eb81de4 100644 --- a/ext/native/thin3d/thin3d.h +++ b/ext/native/thin3d/thin3d.h @@ -326,6 +326,7 @@ class Bugs { enum : uint32_t { NO_DEPTH_CANNOT_DISCARD_STENCIL = 0, + DUAL_SOURCE_BLENDING_BROKEN = 1, }; protected: diff --git a/ext/native/thin3d/thin3d_gl.cpp b/ext/native/thin3d/thin3d_gl.cpp index 114253db787f..e3668b8b9756 100644 --- a/ext/native/thin3d/thin3d_gl.cpp +++ b/ext/native/thin3d/thin3d_gl.cpp @@ -503,6 +503,26 @@ class OpenGLContext : public DrawContext { FrameData frameData_[GLRenderManager::MAX_INFLIGHT_FRAMES]; }; +static constexpr int MakeIntelSimpleVer(int v1, int v2, int v3) { + return (v1 << 16) | (v2 << 8) | v3; +} + +static bool HasIntelDualSrcBug(int versions[4]) { + // Intel uses a confusing set of at least 3 version numbering schemes. This is the one given to OpenGL. + switch (MakeIntelSimpleVer(versions[0], versions[1], versions[2])) { + case MakeIntelSimpleVer(9, 17, 10): + case MakeIntelSimpleVer(9, 18, 10): + return false; + case MakeIntelSimpleVer(10, 18, 10): + return versions[3] < 4061; + case MakeIntelSimpleVer(10, 18, 14): + return versions[3] < 4080; + default: + // Older than above didn't support dual src anyway, newer should have the fix. + return false; + } +} + OpenGLContext::OpenGLContext() { // TODO: Detect more caps if (gl_extensions.IsGLES) { @@ -533,6 +553,21 @@ OpenGLContext::OpenGLContext() { for (int i = 0; i < GLRenderManager::MAX_INFLIGHT_FRAMES; i++) { frameData_[i].push = renderManager_.CreatePushBuffer(i, GL_ARRAY_BUFFER, 64 * 1024); } + + if (!gl_extensions.VersionGEThan(3, 0, 0)) { + // Don't use this extension on sub 3.0 OpenGL versions as it does not seem reliable. + bugs_.Infest(Bugs::DUAL_SOURCE_BLENDING_BROKEN); + } else if (caps_.vendor == GPUVendor::VENDOR_INTEL) { + // Also on Intel, see https://github.com/hrydgard/ppsspp/issues/10117 + // TODO: Remove entirely sometime reasonably far in driver years after 2015. + const std::string ver = GetInfoString(Draw::InfoField::APIVERSION); + int versions[4]{}; + if (sscanf(ver.c_str(), "Build %d.%d.%d.%d", &versions[0], &versions[1], &versions[2], &versions[3]) == 4) { + if (HasIntelDualSrcBug(versions)) { + bugs_.Infest(Bugs::DUAL_SOURCE_BLENDING_BROKEN); + } + } + } } OpenGLContext::~OpenGLContext() { diff --git a/ext/native/thin3d/thin3d_vulkan.cpp b/ext/native/thin3d/thin3d_vulkan.cpp index 1a6ba3e216b5..eaa6b0ad5259 100644 --- a/ext/native/thin3d/thin3d_vulkan.cpp +++ b/ext/native/thin3d/thin3d_vulkan.cpp @@ -780,6 +780,14 @@ VKContext::VKContext(VulkanContext *vulkan, bool splitSubmit) if (deviceProps.deviceID >= 0x05000000 && deviceProps.deviceID < 0x06000000) { bugs_.Infest(Bugs::NO_DEPTH_CANNOT_DISCARD_STENCIL); } + } else if (caps_.vendor == GPUVendor::VENDOR_AMD) { + // See issue #10074, and also #10065 (AMD) and #10109 for the choice of the driver version to check for. + if (deviceProps.driverVersion < 0x00407000) { + bugs_.Infest(Bugs::DUAL_SOURCE_BLENDING_BROKEN); + } + } else if (caps_.vendor == GPUVendor::VENDOR_INTEL) { + // Workaround for Intel driver bug. TODO: Re-enable after some driver version + bugs_.Infest(Bugs::DUAL_SOURCE_BLENDING_BROKEN); } device_ = vulkan->GetDevice();