PixelShaderGen: Perform some of the fog calculations with integers.

This commit is contained in:
Tony Wasserka 2013-12-16 13:08:09 +01:00
parent 605b687af8
commit 065919f599
4 changed files with 34 additions and 27 deletions

View File

@ -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];

View File

@ -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)
{

View File

@ -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)

View File

@ -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;
}