From 62e8d25cd10c86b567209f154a4e841381f16fbb Mon Sep 17 00:00:00 2001 From: Jonathan Hamilton Date: Mon, 19 Jun 2017 18:46:17 -0700 Subject: [PATCH] Add Bug to Disable "LoadOp" clear renderpass in vulkan This optimisation doesn't work on PowerVR's Vulkan implementation. We (incorrectly) disallow Framebuffer objects to be used with a different load or store op than that which they were created with, despite the spec allowing such. This fixes the windwaker intro "smearing" --- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 6 ++++++ Source/Core/VideoCommon/DriverDetails.cpp | 5 ++++- Source/Core/VideoCommon/DriverDetails.h | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 5f79897842..88a9157b24 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -376,6 +376,12 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha // If we're not in a render pass (start of the frame), we can use a clear render pass // to discard the data, rather than loading and then clearing. bool use_clear_render_pass = (color_enable && alpha_enable && z_enable); + if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_CLEAR_LOADOP_RENDERPASS)) + { + // This path cannot be used if the driver implementation doesn't guarantee pixels with no drawn + // geomerty in "this" renderpass won't be cleared + use_clear_render_pass = false; + } if (StateTracker::GetInstance()->InRenderPass()) { // Prefer not to end a render pass just to do a clear. diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index 421fe637b1..b53383f878 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -103,7 +103,10 @@ static BugInfo m_known_bugs[] = { {API_OPENGL, OS_LINUX, VENDOR_MESA, DRIVER_NOUVEAU, Family::UNKNOWN, BUG_SHARED_CONTEXT_SHADER_COMPILATION, -1.0, -1.0, true}, {API_VULKAN, OS_ALL, VENDOR_NVIDIA, DRIVER_NVIDIA, Family::UNKNOWN, - BUG_BROKEN_MSAA_VKCMDCLEARATTACHMENTS, -1.0, -1.0, true}}; + BUG_BROKEN_MSAA_VKCMDCLEARATTACHMENTS, -1.0, -1.0, true}, + {API_VULKAN, OS_ALL, VENDOR_IMGTEC, DRIVER_IMGTEC, Family::UNKNOWN, + BUG_BROKEN_CLEAR_LOADOP_RENDERPASS, -1.0, -1.0, true}, +}; static std::map m_bugs; diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index a57071ef68..22de90c763 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -259,6 +259,13 @@ enum Bug // Ended version: -1 // Seems to only occur when the top of the clear rect is non-zero. BUG_BROKEN_MSAA_VKCMDCLEARATTACHMENTS, + // BUG: Some vulkan implementations don't like the 'clear' loadop renderpass. + // For example, the ImgTec VK driver fails if you try to use a framebuffer with a different + // load/store op than that which it was created with, despite the spec saying they should be + // compatible. + // Started Version: 1.7 + // Ended Version: 1.10 + BUG_BROKEN_CLEAR_LOADOP_RENDERPASS, }; // Initializes our internal vendor, device family, and driver version