From 065919f599b86da9464a9f6a792e56ca87661540 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Mon, 16 Dec 2013 13:08:09 +0100 Subject: [PATCH] PixelShaderGen: Perform some of the fog calculations with integers. --- Source/Core/VideoCommon/ConstantManager.h | 3 +- Source/Core/VideoCommon/PixelShaderGen.cpp | 22 +++++++++------ Source/Core/VideoCommon/PixelShaderGen.h | 8 ++++-- .../Core/VideoCommon/PixelShaderManager.cpp | 28 +++++++++---------- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/Source/Core/VideoCommon/ConstantManager.h b/Source/Core/VideoCommon/ConstantManager.h index 1f42b20299..da3d19962f 100644 --- a/Source/Core/VideoCommon/ConstantManager.h +++ b/Source/Core/VideoCommon/ConstantManager.h @@ -19,7 +19,8 @@ struct PixelShaderConstants float4 indtexscale[2]; int4 indtexmtx[6]; int4 fogcolor; - float4 fog[2]; + int4 fogi[1]; + float4 fogf[2]; // For pixel lighting int4 plight_colors[8]; diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index e8820e0b9d..899f01143a 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -291,7 +291,8 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T DeclareUniform(out, ApiType, C_INDTEXSCALE, "float4", I_INDTEXSCALE"[2]"); DeclareUniform(out, ApiType, C_INDTEXMTX, "int4", I_INDTEXMTX"[6]"); DeclareUniform(out, ApiType, C_FOGCOLOR, "int4", I_FOGCOLOR); - DeclareUniform(out, ApiType, C_FOG, "float4", I_FOG"[2]"); + DeclareUniform(out, ApiType, C_FOGI, "int4", I_FOGI"[1]"); + DeclareUniform(out, ApiType, C_FOGF, "float4", I_FOGF"[2]"); // For pixel lighting - TODO: Should only be defined when per pixel lighting is enabled! DeclareUniform(out, ApiType, C_PLIGHT_COLORS, "int4", I_PLIGHT_COLORS"[8]"); @@ -1049,33 +1050,36 @@ static inline void WriteFog(T& out, pixel_shader_uid_data& uid_data) uid_data.fog_proj = bpmem.fog.c_proj_fsel.proj; out.SetConstantsUsed(C_FOGCOLOR, C_FOGCOLOR); - out.SetConstantsUsed(C_FOG, C_FOG); + out.SetConstantsUsed(C_FOGI, C_FOGI); + out.SetConstantsUsed(C_FOGF, C_FOGF+1); if (bpmem.fog.c_proj_fsel.proj == 0) { // perspective // ze = A/(B - (Zs >> B_SHF) - out.Write("\tfloat ze = " I_FOG"[0].x / (" I_FOG"[0].y - (float(zCoord) / 16777215.0 / " I_FOG"[0].w));\n"); + // TODO: Verify that we want to drop lower bits here! (currently taken over from software renderer) + out.Write("\tfloat ze = (" I_FOGF"[1].x * 16777215.0) / float(" I_FOGI"[0].y - (zCoord >> " I_FOGI"[0].w));\n"); } else { // orthographic // ze = a*Zs (here, no B_SHF) - out.Write("\tfloat ze = " I_FOG"[0].x * float(zCoord) / 16777215.0;\n"); + out.Write("\tfloat ze = " I_FOGF"[1].x * float(zCoord) / 16777215.0;\n"); } // x_adjust = sqrt((x-center)^2 + k^2)/k // ze *= x_adjust - // this is completely theoretical as the real hardware seems to use a table intead of calculating the values. + // TODO Instead of this theoretical calculation, we should use the + // coefficient table given in the fog range BP registers! uid_data.fog_RangeBaseEnabled = bpmem.fogRange.Base.Enabled; if (bpmem.fogRange.Base.Enabled) { - out.SetConstantsUsed(C_FOG+1, C_FOG+1); - out.Write("\tfloat x_adjust = (2.0 * (clipPos.x / " I_FOG"[1].y)) - 1.0 - " I_FOG"[1].x;\n"); - out.Write("\tx_adjust = sqrt(x_adjust * x_adjust + " I_FOG"[1].z * " I_FOG"[1].z) / " I_FOG"[1].z;\n"); + out.SetConstantsUsed(C_FOGF, C_FOGF); + out.Write("\tfloat x_adjust = (2.0 * (clipPos.x / " I_FOGF"[0].y)) - 1.0 - " I_FOGF"[0].x;\n"); + out.Write("\tx_adjust = sqrt(x_adjust * x_adjust + " I_FOGF"[0].z * " I_FOGF"[0].z) / " I_FOGF"[0].z;\n"); out.Write("\tze *= x_adjust;\n"); } - out.Write("\tfloat fog = clamp(ze - " I_FOG"[0].z, 0.0, 1.0);\n"); + out.Write("\tfloat fog = clamp(ze - " I_FOGF"[1].z, 0.0, 1.0);\n"); if (bpmem.fog.c_proj_fsel.fsel > 3) { diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index 972101cd1c..135e4928f1 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -17,7 +17,8 @@ #define I_INDTEXSCALE "cindscale" #define I_INDTEXMTX "cindmtx" #define I_FOGCOLOR "cfogcolor" -#define I_FOG "cfog" +#define I_FOGI "cfogi" +#define I_FOGF "cfogf" #define I_PLIGHT_COLORS "cPLightColors" #define I_PLIGHTS "cPLights" #define I_PMATERIALS "cPmtrl" @@ -32,9 +33,10 @@ #define C_INDTEXSCALE (C_ZBIAS + 2) //19 #define C_INDTEXMTX (C_INDTEXSCALE + 2) //21 #define C_FOGCOLOR (C_INDTEXMTX + 6) //27 -#define C_FOG (C_FOGCOLOR + 1) //28 +#define C_FOGI (C_FOGCOLOR + 1) //28 +#define C_FOGF (C_FOGI + 1) //29 -#define C_PLIGHT_COLORS (C_FOG + 2) +#define C_PLIGHT_COLORS (C_FOGF + 2) #define C_PLIGHTS (C_PLIGHT_COLORS + 8) #define C_PMATERIALS (C_PLIGHTS + 32) #define C_PENVCONST_END (C_PMATERIALS + 4) diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp index 79ff607b82..91d74edf4a 100644 --- a/Source/Core/VideoCommon/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/PixelShaderManager.cpp @@ -85,15 +85,15 @@ void PixelShaderManager::SetConstants() // they are the coefficients from the center to the border of the screen // so to simplify I use the hi coefficient as K in the shader taking 256 as the scale // TODO: Shouldn't this be EFBToScaledXf? - constants.fog[1][0] = ScreenSpaceCenter; - constants.fog[1][1] = (float)Renderer::EFBToScaledX((int)(2.0f * xfregs.viewport.wd)); - constants.fog[1][2] = bpmem.fogRange.K[4].HI / 256.0f; + constants.fogf[0][0] = ScreenSpaceCenter; + constants.fogf[0][1] = (float)Renderer::EFBToScaledX((int)(2.0f * xfregs.viewport.wd)); + constants.fogf[0][2] = bpmem.fogRange.K[4].HI / 256.0f; } else { - constants.fog[1][0] = 0; - constants.fog[1][1] = 1; - constants.fog[1][2] = 1; + constants.fogf[0][0] = 0; + constants.fogf[0][1] = 1; + constants.fogf[0][2] = 1; } dirty = true; @@ -282,17 +282,17 @@ void PixelShaderManager::SetFogParamChanged() { if (!g_ActiveConfig.bDisableFog) { - constants.fog[0][0] = bpmem.fog.a.GetA(); - constants.fog[0][1] = (float)bpmem.fog.b_magnitude / 0xFFFFFF; - constants.fog[0][2] = bpmem.fog.c_proj_fsel.GetC(); - constants.fog[0][3] = (float)(1 << bpmem.fog.b_shift); + constants.fogf[1][0] = bpmem.fog.a.GetA(); + constants.fogi[0][1] = bpmem.fog.b_magnitude; + constants.fogf[1][2] = bpmem.fog.c_proj_fsel.GetC(); + constants.fogi[0][3] = bpmem.fog.b_shift; } else { - constants.fog[0][0] = 0; - constants.fog[0][1] = 1; - constants.fog[0][2] = 0; - constants.fog[0][3] = 1; + constants.fogf[1][0] = 0.f; + constants.fogi[0][1] = 1; + constants.fogf[1][2] = 0.f; + constants.fogi[0][3] = 1; } dirty = true; }