From 34a23d48db5c1cdf4c0008bb316bce25b88d9a17 Mon Sep 17 00:00:00 2001 From: "Skyth (Asilkan)" <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Mon, 3 Mar 2025 03:00:26 +0300 Subject: [PATCH] Force triangle strip workaround for AMD GPUs. (#659) --- UnleashedRecomp/gpu/video.cpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 79c6c93..3919877 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -285,7 +285,7 @@ static bool g_vulkan = false; static constexpr bool g_vulkan = true; #endif -static bool g_mesaTriangleStripWorkaround = false; +static bool g_triangleStripWorkaround = false; static constexpr bool g_hardwareResolve = true; static constexpr bool g_hardwareDepthResolve = true; @@ -1702,13 +1702,9 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver) g_vulkan = (interfaceFunction == CreateVulkanInterfaceWrapper); #endif - - if (interfaceFunction == CreateVulkanInterfaceWrapper) - { - // Enable triangle strip workaround if we are on the Mesa RADV driver, as it currently has a bug where - // restart indices cause triangles to be culled incorrectly. Converting them to degenerate triangles fixes it. - g_mesaTriangleStripWorkaround = deviceDescription.name.find(" (RADV ") != std::string::npos; - } + // Enable triangle strip workaround if we are on AMD, as there is a bug where + // restart indices cause triangles to be culled incorrectly. Converting them to degenerate triangles fixes it. + g_triangleStripWorkaround = (deviceDescription.vendor == RenderDeviceVendor::AMD); break; } @@ -2329,7 +2325,7 @@ static void DrawProfiler() ImGui::Text("Present Wait: %s", g_capabilities.presentWait ? "Supported" : "Unsupported"); ImGui::Text("Triangle Fan: %s", g_capabilities.triangleFan ? "Supported" : "Unsupported"); ImGui::Text("Dynamic Depth Bias: %s", g_capabilities.dynamicDepthBias ? "Supported" : "Unsupported"); - ImGui::Text("Triangle Strip Workaround: %s", g_mesaTriangleStripWorkaround ? "Enabled" : "Disabled"); + ImGui::Text("Triangle Strip Workaround: %s", g_triangleStripWorkaround ? "Enabled" : "Disabled"); ImGui::NewLine(); ImGui::Text("API: %s", g_vulkan ? "Vulkan" : "D3D12"); @@ -7428,8 +7424,8 @@ bool FxShadowMapMidAsmHook(PPCRegister& r4, PPCRegister& r5, PPCRegister& r6, PP } } -// There is a driver bug on Mesa where restart indices cause incorrect culling and prevent some triangles from being rendered. -// Restart indices can be converted to degenerate triangles as a workaround until this issue gets fixed. +// There is a bug on AMD where restart indices cause incorrect culling and prevent some triangles from being rendered. +// This seems to happen on both Windows AMD drivers and Mesa. Converting restart indices to degenerate triangles fixes it. static void ConvertToDegenerateTriangles(uint16_t* indices, uint32_t indexCount, uint16_t*& newIndices, uint32_t& newIndexCount) { newIndices = reinterpret_cast(g_userHeap.Alloc(indexCount * sizeof(uint16_t) * 3)); @@ -7482,7 +7478,7 @@ PPC_FUNC(sub_82E44AF8) uint16_t* newIndicesToFree = nullptr; auto databaseData = reinterpret_cast(base + ctx.r3.u32); - if (g_mesaTriangleStripWorkaround && !databaseData->IsMadeOne()) + if (g_triangleStripWorkaround && !databaseData->IsMadeOne()) { auto meshResource = reinterpret_cast(base + ctx.r4.u32); @@ -7545,7 +7541,7 @@ PPC_FUNC(sub_82E3AFC8) uint16_t* newIndices = nullptr; auto databaseData = reinterpret_cast(base + ctx.r3.u32); - if (g_mesaTriangleStripWorkaround && !databaseData->IsMadeOne()) + if (g_triangleStripWorkaround && !databaseData->IsMadeOne()) { auto lightAndIndexBufferResource = reinterpret_cast(base + ctx.r4.u32); @@ -7584,7 +7580,7 @@ PPC_FUNC(sub_82E3B1C0) uint16_t* newIndices = nullptr; auto databaseData = reinterpret_cast(base + ctx.r3.u32); - if (g_mesaTriangleStripWorkaround && !databaseData->IsMadeOne()) + if (g_triangleStripWorkaround && !databaseData->IsMadeOne()) { auto lightAndIndexBufferResource = reinterpret_cast(base + ctx.r4.u32);