From cc2227fbc3fdb22d19036a7721b30b099190b716 Mon Sep 17 00:00:00 2001 From: Yuriy O'Donnell Date: Sat, 25 Oct 2014 00:26:28 +0200 Subject: [PATCH 1/4] D3D: Replaced shader-based depth range remap with viewport This fixes UI rendering in some games mentioned in https://code.google.com/p/dolphin-emu/issues/detail?id=7785 --- Source/Core/VideoBackends/D3D/Render.cpp | 4 ++-- Source/Core/VideoCommon/VertexShaderGen.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 0441e63d7b..6705364189 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -487,8 +487,8 @@ void Renderer::SetViewport() // Some games set invalid values for z-min and z-max so fix them to the max and min allowed and let the shaders do this work D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, Wd, Ht, - 0.f, // (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f; - 1.f); // xfmem.viewport.farZ / 16777216.0f; + (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f, + xfmem.viewport.farZ / 16777216.0f); D3D::context->RSSetViewports(1, &vp); } diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 24c6f39f46..c0faf21000 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -405,7 +405,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ //if not early z culling will improve speed if (api_type == API_D3D) { - out.Write("o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); + out.Write("o.pos.z = o.pos.w + o.pos.z;\n"); } else // OGL { From 1fe3d07cbdeda459527199bb9837f5f6ce9a2f5b Mon Sep 17 00:00:00 2001 From: Yuriy O'Donnell Date: Sat, 25 Oct 2014 02:46:13 +0200 Subject: [PATCH 2/4] D3D: Removed somewhat mysterious comment It would be good to know which games exactly exhibited the issue. --- Source/Core/VideoBackends/D3D/Render.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 6705364189..31ab07ddaa 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -485,7 +485,6 @@ void Renderer::SetViewport() Wd = (X + Wd <= GetTargetWidth()) ? Wd : (GetTargetWidth() - X); Ht = (Y + Ht <= GetTargetHeight()) ? Ht : (GetTargetHeight() - Y); - // Some games set invalid values for z-min and z-max so fix them to the max and min allowed and let the shaders do this work D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, Wd, Ht, (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f, xfmem.viewport.farZ / 16777216.0f); From a886d8a8ee97ced9b8d4868d604d08b54886b06a Mon Sep 17 00:00:00 2001 From: Yuriy O'Donnell Date: Sat, 25 Oct 2014 02:59:02 +0200 Subject: [PATCH 3/4] Renamed DEPTHPARAMS to PIXELCENTERCORRECTION This shader constant was previously used for depth remapping in D3D and for pixel center correction. Now it only serves one purpose and the new name makes it clear. --- Source/Core/VideoCommon/ConstantManager.h | 2 +- Source/Core/VideoCommon/ShaderGenCommon.h | 4 ++-- Source/Core/VideoCommon/VertexShaderGen.cpp | 2 +- Source/Core/VideoCommon/VertexShaderManager.cpp | 6 ++---- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Source/Core/VideoCommon/ConstantManager.h b/Source/Core/VideoCommon/ConstantManager.h index 116088d76e..93c228bc98 100644 --- a/Source/Core/VideoCommon/ConstantManager.h +++ b/Source/Core/VideoCommon/ConstantManager.h @@ -42,7 +42,7 @@ struct VertexShaderConstants float4 transformmatrices[64]; float4 normalmatrices[32]; float4 posttransformmatrices[64]; - float4 depthparams; + float4 pixelcentercorrection; float4 stereoparams; }; diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 330b9f8ced..4d22048ee6 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -238,7 +238,7 @@ private: #define I_TRANSFORMMATRICES "ctrmtx" #define I_NORMALMATRICES "cnmtx" #define I_POSTTRANSFORMMATRICES "cpostmtx" -#define I_DEPTHPARAMS "cDepth" // farZ, zRange +#define I_PIXELCENTERCORRECTION "cpixelcenter" #define I_STEREOPARAMS "cstereo" static const char s_shader_uniforms[] = @@ -250,5 +250,5 @@ static const char s_shader_uniforms[] = "\tfloat4 " I_TRANSFORMMATRICES"[64];\n" "\tfloat4 " I_NORMALMATRICES"[32];\n" "\tfloat4 " I_POSTTRANSFORMMATRICES"[64];\n" - "\tfloat4 " I_DEPTHPARAMS";\n" + "\tfloat4 " I_PIXELCENTERCORRECTION";\n" "\tfloat4 " I_STEREOPARAMS";\n"; diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index c0faf21000..26d6942372 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -430,7 +430,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ // which in turn can be critical if it happens for clear quads. // Hence, we compensate for this pixel center difference so that primitives // get rasterized correctly. - out.Write("o.pos.xy = o.pos.xy - " I_DEPTHPARAMS".zw;\n"); + out.Write("o.pos.xy = o.pos.xy - " I_PIXELCENTERCORRECTION".xy;\n"); if (api_type == API_OPENGL) { diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 8de50c5436..2d496cb50c 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -359,8 +359,6 @@ void VertexShaderManager::SetConstants() if (bViewportChanged) { bViewportChanged = false; - constants.depthparams[0] = xfmem.viewport.farZ / 16777216.0f; - constants.depthparams[1] = xfmem.viewport.zRange / 16777216.0f; // The console GPU places the pixel center at 7/12 unless antialiasing // is enabled, while D3D and OpenGL place it at 0.5. See the comment @@ -370,8 +368,8 @@ void VertexShaderManager::SetConstants() const float pixel_center_correction = 7.0f / 12.0f - 0.5f; const float pixel_size_x = 2.f / Renderer::EFBToScaledXf(2.f * xfmem.viewport.wd); const float pixel_size_y = 2.f / Renderer::EFBToScaledXf(2.f * xfmem.viewport.ht); - constants.depthparams[2] = pixel_center_correction * pixel_size_x; - constants.depthparams[3] = pixel_center_correction * pixel_size_y; + constants.pixelcentercorrection[0] = pixel_center_correction * pixel_size_x; + constants.pixelcentercorrection[1] = pixel_center_correction * pixel_size_y; dirty = true; // This is so implementation-dependent that we can't have it here. g_renderer->SetViewport(); From 36b886cb802c44eb02482b17ce483ba76ccb25ee Mon Sep 17 00:00:00 2001 From: Yuriy O'Donnell Date: Wed, 5 Nov 2014 02:41:08 +0100 Subject: [PATCH 4/4] D3D: Viewport min and max depth is now clamped to [0..1] range --- Source/Core/VideoBackends/D3D/Render.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 31ab07ddaa..5db7b8b4ec 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -486,8 +486,8 @@ void Renderer::SetViewport() Ht = (Y + Ht <= GetTargetHeight()) ? Ht : (GetTargetHeight() - Y); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(X, Y, Wd, Ht, - (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f, - xfmem.viewport.farZ / 16777216.0f); + std::max(0.0f, std::min(1.0f, (xfmem.viewport.farZ - xfmem.viewport.zRange) / 16777216.0f)), + std::max(0.0f, std::min(1.0f, xfmem.viewport.farZ / 16777216.0f))); D3D::context->RSSetViewports(1, &vp); }