From 665f03ff6251c5d5ffebd5068daea9435f77cf2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 17 Jul 2024 12:37:20 +0200 Subject: [PATCH] Add provoking vertex to caps, flip the flag around --- Common/GPU/D3D11/thin3d_d3d11.cpp | 2 ++ Common/GPU/D3D9/thin3d_d3d9.cpp | 2 ++ Common/GPU/OpenGL/thin3d_gl.cpp | 3 +++ Common/GPU/Vulkan/thin3d_vulkan.cpp | 3 +++ Common/GPU/thin3d.h | 2 +- GPU/Common/SoftwareTransformCommon.cpp | 2 +- GPU/Common/SoftwareTransformCommon.h | 2 +- GPU/D3D11/DrawEngineD3D11.cpp | 2 +- GPU/Directx9/DrawEngineDX9.cpp | 2 +- GPU/GLES/DrawEngineGLES.cpp | 2 +- GPU/Vulkan/DrawEngineVulkan.cpp | 4 ++-- 11 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Common/GPU/D3D11/thin3d_d3d11.cpp b/Common/GPU/D3D11/thin3d_d3d11.cpp index 380daffb51..6ac9b4e593 100644 --- a/Common/GPU/D3D11/thin3d_d3d11.cpp +++ b/Common/GPU/D3D11/thin3d_d3d11.cpp @@ -281,6 +281,8 @@ D3D11DrawContext::D3D11DrawContext(ID3D11Device *device, ID3D11DeviceContext *de caps_.blendMinMaxSupported = true; caps_.multiSampleLevelsMask = 1; // More could be supported with some work. + caps_.provokingVertexLast = false; // D3D has it first, unfortunately. (and no way to change it). + caps_.presentInstantModeChange = true; caps_.presentMaxInterval = 4; caps_.presentModesSupported = PresentMode::FIFO | PresentMode::IMMEDIATE; diff --git a/Common/GPU/D3D9/thin3d_d3d9.cpp b/Common/GPU/D3D9/thin3d_d3d9.cpp index 0e12092ee0..97f0919e16 100644 --- a/Common/GPU/D3D9/thin3d_d3d9.cpp +++ b/Common/GPU/D3D9/thin3d_d3d9.cpp @@ -786,6 +786,8 @@ D3D9Context::D3D9Context(IDirect3D9 *d3d, IDirect3D9Ex *d3dEx, int adapterId, ID caps_.presentMaxInterval = 1; caps_.presentModesSupported = PresentMode::FIFO; + caps_.provokingVertexLast = false; // D3D has it first, unfortunately (and no way to change it). + if ((caps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) != 0 && caps.MaxAnisotropy > 1) { caps_.anisoSupported = true; } diff --git a/Common/GPU/OpenGL/thin3d_gl.cpp b/Common/GPU/OpenGL/thin3d_gl.cpp index bd615d6b64..e8ff1d4d9c 100644 --- a/Common/GPU/OpenGL/thin3d_gl.cpp +++ b/Common/GPU/OpenGL/thin3d_gl.cpp @@ -598,6 +598,9 @@ OpenGLContext::OpenGLContext(bool canChangeSwapInterval) : renderManager_(frameT // GLES has no support for logic framebuffer operations. There doesn't even seem to exist any such extensions. caps_.logicOpSupported = !gl_extensions.IsGLES; + // Always the case in GL (which is what we want for PSP flat shade). + caps_.provokingVertexLast = true; + // Interesting potential hack for emulating GL_DEPTH_CLAMP (use a separate varying, force depth in fragment shader): // This will induce a performance penalty on many architectures though so a blanket enable of this // is probably not a good idea. diff --git a/Common/GPU/Vulkan/thin3d_vulkan.cpp b/Common/GPU/Vulkan/thin3d_vulkan.cpp index d03ab9eaff..9c9eec4367 100644 --- a/Common/GPU/Vulkan/thin3d_vulkan.cpp +++ b/Common/GPU/Vulkan/thin3d_vulkan.cpp @@ -913,6 +913,9 @@ VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread) caps_.sampleRateShadingSupported = vulkan->GetDeviceFeatures().enabled.standard.sampleRateShading != 0; caps_.textureSwizzleSupported = true; + // Note that it must also be enabled on the pipelines (which we do). + caps_.provokingVertexLast = vulkan->GetDeviceFeatures().enabled.provokingVertex.provokingVertexLast; + // Present mode stuff caps_.presentMaxInterval = 1; caps_.presentInstantModeChange = false; // TODO: Fix this with some work in VulkanContext diff --git a/Common/GPU/thin3d.h b/Common/GPU/thin3d.h index dc7ba23b24..b1a9f94487 100644 --- a/Common/GPU/thin3d.h +++ b/Common/GPU/thin3d.h @@ -612,7 +612,7 @@ struct DeviceCaps { bool setMaxFrameLatencySupported; bool textureSwizzleSupported; bool requiresHalfPixelOffset; - + bool provokingVertexLast; // GL behavior, what the PSP does bool verySlowShaderCompiler; // From the other backends, we can detect if D3D9 support is known bad (like on Xe) and disable it. diff --git a/GPU/Common/SoftwareTransformCommon.cpp b/GPU/Common/SoftwareTransformCommon.cpp index fd117de69a..0a062898ac 100644 --- a/GPU/Common/SoftwareTransformCommon.cpp +++ b/GPU/Common/SoftwareTransformCommon.cpp @@ -203,7 +203,7 @@ void SoftwareTransform::Transform(int prim, u32 vertType, const DecVtxFormat &de } int provokeIndOffset = 0; - if (params_.provokeFlatFirst) { + if (!params_.provokingVertexLast) { provokeIndOffset = ColorIndexOffset(prim, gstate.getShadeMode(), gstate.isModeClear()); } diff --git a/GPU/Common/SoftwareTransformCommon.h b/GPU/Common/SoftwareTransformCommon.h index 78717cdfa3..db001d1282 100644 --- a/GPU/Common/SoftwareTransformCommon.h +++ b/GPU/Common/SoftwareTransformCommon.h @@ -57,9 +57,9 @@ struct SoftwareTransformParams { TextureCacheCommon *texCache; bool allowClear; bool allowSeparateAlphaClear; - bool provokeFlatFirst; bool flippedY; bool usesHalfZ; + bool provokingVertexLast; }; class SoftwareTransform { diff --git a/GPU/D3D11/DrawEngineD3D11.cpp b/GPU/D3D11/DrawEngineD3D11.cpp index f415745d70..e1145b514a 100644 --- a/GPU/D3D11/DrawEngineD3D11.cpp +++ b/GPU/D3D11/DrawEngineD3D11.cpp @@ -382,7 +382,7 @@ void DrawEngineD3D11::DoFlush() { params.texCache = textureCache_; params.allowClear = true; params.allowSeparateAlphaClear = false; // D3D11 doesn't support separate alpha clears - params.provokeFlatFirst = true; + params.provokingVertexLast = false; params.flippedY = false; params.usesHalfZ = true; diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index 4d16fd6701..f39969d88a 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -334,7 +334,7 @@ void DrawEngineDX9::DoFlush() { params.texCache = textureCache_; params.allowClear = true; params.allowSeparateAlphaClear = false; - params.provokeFlatFirst = true; + params.provokingVertexLast = false; params.flippedY = false; params.usesHalfZ = true; diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index d6da9070de..74be51f0a7 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -356,7 +356,7 @@ void DrawEngineGLES::DoFlush() { params.texCache = textureCache_; params.allowClear = true; // Clear in OpenGL respects scissor rects, so we'll use it. params.allowSeparateAlphaClear = true; - params.provokeFlatFirst = false; + params.provokingVertexLast = true; params.flippedY = framebufferManager_->UseBufferedRendering(); params.usesHalfZ = false; diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index befe01da89..9cb6d752ba 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -407,9 +407,9 @@ void DrawEngineVulkan::DoFlush() { params.allowSeparateAlphaClear = false; if (renderManager->GetVulkanContext()->GetDeviceFeatures().enabled.provokingVertex.provokingVertexLast) { // We can get the OpenGL behavior, no need for workarounds. - params.provokeFlatFirst = false; + params.provokingVertexLast = true; } else { - params.provokeFlatFirst = true; + params.provokingVertexLast = false; } params.flippedY = true; params.usesHalfZ = true;