initial implementation of fog range adjust, I don't think is correct or work right but is a start.

some tweaks and fixes.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6957 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado 2011-01-29 04:31:56 +00:00
parent 64af8abcae
commit 4c58c7ea03
9 changed files with 94 additions and 37 deletions

View File

@ -26,7 +26,7 @@
// shader cache for every revision, graphics-related or not, which is simply annoying.
enum
{
LINEAR_DISKCACHE_VER = 6917
LINEAR_DISKCACHE_VER = 6957
};
// On disk format:

View File

@ -678,6 +678,33 @@ union FogParam3
u32 hex;
};
union FogRangeKElement
{
struct
{
u32 HI : 12;
u32 LO : 12;
u32 regid : 8;
};
u32 HEX;
};
struct FogRangeParams
{
union RangeBase
{
struct
{
u32 Center : 10;
u32 Enabled : 1;
u32 unused : 13;
u32 regid : 8;
};
u32 hex;
};
RangeBase Base;
FogRangeKElement K[5];
};
// final eq: ze = A/(B_MAG - (Zs>>B_SHF));
struct FogParams
{
@ -902,10 +929,7 @@ struct BPMemory
FourTexUnits tex[2]; //80-bf
TevStageCombiner combiners[16]; //0xC0-0xDF
TevReg tevregs[4]; //0xE0
u32 fogRangeAdj; //0xE8
u32 unknown15[3]; //0xe9,0xea,0xeb - fog related
u32 tev_range_adj_c; //0xec - screenx center for range adjustment, range adjustment enable
u32 tev_range_adj_k; //0xed - specifies range adjustment function = sqrt(x*x+k*k)/k
FogRangeParams fogRange;
FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2
AlphaFunc alphaFunc; //0xF3
ZTex1 ztex1; //0xf4,0xf5

View File

@ -320,6 +320,9 @@ void BPWritten(const BPCmd& bp)
case BPMEM_FOGRANGE+3:
case BPMEM_FOGRANGE+4:
case BPMEM_FOGRANGE+5:
if (!GetConfig(CONFIG_DISABLEFOG))
PixelShaderManager::SetFogRangeAdjustChanged();
break;
case BPMEM_FOGPARAM0:
case BPMEM_FOGBMAGNITUDE:
case BPMEM_FOGBEXPONENT:

View File

@ -61,7 +61,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode)
uid->values[2] = (u32)bpmem.fog.c_proj_fsel.fsel |
((u32)bpmem.fog.c_proj_fsel.proj << 3) |
((u32)enableZTexture << 4);
((u32)enableZTexture << 4) | ((u32)bpmem.fogRange.Base.Enabled << 5);
if(g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
@ -504,7 +504,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, "uniform float4 "I_ZBIAS"[2] : register(c%d);\n", C_ZBIAS);
WRITE(p, "uniform float4 "I_INDTEXSCALE"[2] : register(c%d);\n", C_INDTEXSCALE);
WRITE(p, "uniform float4 "I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX);
WRITE(p, "uniform float4 "I_FOG"[2] : register(c%d);\n", C_FOG);
WRITE(p, "uniform float4 "I_FOG"[3] : register(c%d);\n", C_FOG);
if(g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
@ -521,7 +521,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "",
DepthTextureEnable ? "\n out float depth : DEPTH," : "",
ApiType == API_OPENGL ? "WPOS" : "POSITION");
ApiType == API_OPENGL ? "WPOS" : "VPOS");
}
else
{
@ -792,7 +792,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
}
// emulation of unisgned 8 overflow when casting if needed
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
if (!WriteAlphaTest(p, ApiType, dstAlphaMode))
{
@ -997,7 +997,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
if(bCRas || bARas)
{
WRITE(p, "rastemp = %s.%s;\n", tevRasTable[bpmem.tevorders[n / 2].getColorChan(n & 1)], rasswap);
WRITE(p, "crastemp = frac(4.0f + rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
WRITE(p, "crastemp = frac(rastemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
}
@ -1030,7 +1030,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
WRITE(p, "konsttemp = float4(%s, %s);\n", tevKSelTableC[kc], tevKSelTableA[ka]);
if(kc > 7 || ka > 7)
{
WRITE(p, "ckonsttemp = frac(4.0f + konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
WRITE(p, "ckonsttemp = frac(konsttemp * (255.0f/256.0f)) * (256.0f/255.0f);\n");
}
else
{
@ -1050,7 +1050,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
{
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
{
WRITE(p, "cprev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
WRITE(p, "cprev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[0].AlphaNeedOverflowControl = false;
RegisterStates[0].ColorNeedOverflowControl = false;
}
@ -1073,7 +1073,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
{
if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl)
{
WRITE(p, "cc0 = frac(4.0f + c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
WRITE(p, "cc0 = frac(c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[1].AlphaNeedOverflowControl = false;
RegisterStates[1].ColorNeedOverflowControl = false;
}
@ -1096,7 +1096,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
{
if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl)
{
WRITE(p, "cc1 = frac(4.0f + c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
WRITE(p, "cc1 = frac(c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[2].AlphaNeedOverflowControl = false;
RegisterStates[2].ColorNeedOverflowControl = false;
}
@ -1119,7 +1119,7 @@ static void WriteStage(char *&p, int n, API_TYPE ApiType)
{
if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl)
{
WRITE(p, "cc2 = frac(4.0f + c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
WRITE(p, "cc2 = frac(c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[3].AlphaNeedOverflowControl = false;
RegisterStates[3].ColorNeedOverflowControl = false;
}
@ -1340,10 +1340,15 @@ static void WriteFog(char *&p)
WRITE (p, " float ze = "I_FOG"[1].x * zCoord;\n");
}
// stuff to do!
// here, where we'll have to add/handle x range adjustment (if related BP register it's enabled)
// x_adjust = sqrt((x-center)^2 + k^2)/k
// ze *= x_adjust
//this is complitly teorical as the real hard seems to use a table intead of calculate the values.
if(bpmem.fogRange.Base.Enabled)
{
WRITE (p, " float x_adjust = (2.0f * (clipPos.x / "I_FOG"[2].y)) - 1.0f - "I_FOG"[2].x;\n");
WRITE (p, " x_adjust = sqrt(x_adjust * x_adjust + "I_FOG"[2].z * "I_FOG"[2].z) / "I_FOG"[2].z;\n");
WRITE (p, " ze *= x_adjust;\n");
}
WRITE (p, " float fog = saturate(ze - "I_FOG"[1].z);\n");
@ -1359,4 +1364,5 @@ static void WriteFog(char *&p)
WRITE(p, " prev.rgb = lerp(prev.rgb,"I_FOG"[0].rgb,fog);\n");
}

View File

@ -41,7 +41,7 @@
#define C_INDTEXMTX (C_INDTEXSCALE + 2) //21
#define C_FOG (C_INDTEXMTX + 6) //27
#define C_PLIGHTS (C_FOG + 2)
#define C_PLIGHTS (C_FOG + 3)
#define C_PMATERIALS (C_PLIGHTS + 40)
#define C_PENVCONST_END (C_PMATERIALS + 4)
#define PIXELSHADERUID_MAX_VALUES (5 + 32 + 6 + 11 + 2)

View File

@ -22,6 +22,7 @@
#include "PixelShaderManager.h"
#include "VideoCommon.h"
#include "VideoConfig.h"
#include "RenderBase.h"
static float GC_ALIGNED16(s_fMaterials[16]);
static int s_nColorsChanged[2]; // 0 - regular colors, 1 - k colors
static int s_nIndTexMtxChanged;
@ -31,6 +32,7 @@ static bool s_bZTextureTypeChanged;
static bool s_bDepthRangeChanged;
static bool s_bFogColorChanged;
static bool s_bFogParamChanged;
static bool s_bFogRangeAdjustChanged;
static int nLightsChanged[2]; // min,max
static float lastDepthRange[2]; // 0 = far z, 1 = far - near
static float lastRGBAfull[2][4][4];
@ -57,7 +59,7 @@ void PixelShaderManager::Dirty()
s_nIndTexScaleChanged = 0xFF;
s_nIndTexMtxChanged = 15;
s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true;
s_bFogColorChanged = s_bFogParamChanged = true;
s_bFogRangeAdjustChanged = s_bFogColorChanged = s_bFogParamChanged = true;
nLightsChanged[0] = 0; nLightsChanged[1] = 0x80;
nMaterialsChanged = 15;
}
@ -214,6 +216,25 @@ void PixelShaderManager::SetConstants()
s_bFogParamChanged = false;
}
if (s_bFogRangeAdjustChanged)
{
if(!g_ActiveConfig.bDisableFog && bpmem.fogRange.Base.Enabled == 1)
{
//bpmem.fogRange.Base.Center : center of the viewport in x axis. observation: bpmem.fogRange.Base.Center = realcenter + 342;
int center = ((u32)bpmem.fogRange.Base.Center) - 342;
// normalice center to make calculations easy
float ScreenSpaceCenter = center / (2.0f * xfregs.rawViewport[0]);
ScreenSpaceCenter = (ScreenSpaceCenter * 2.0f) - 1.0f;
//bpmem.fogRange.K seems to be a table of precalculated coeficients for the adjust factor
//observations: bpmem.fogRange.K[0].LO apears to be the lowest value and bpmem.fogRange.K[4].HI the largest
// they always seems to be larger than 256 so my teory is :
// they are the coeficients from the center to th e border of the screen
// so to simplify i use the hi coeficient as K in the shader taking 256 as the scale
SetPSConstant4f(C_FOG + 2, ScreenSpaceCenter, (float)Renderer::EFBToScaledX((int)(2.0f * xfregs.rawViewport[0])), bpmem.fogRange.K[4].HI / 256.0f,0.0f);
}
s_bFogRangeAdjustChanged = false;
}
if (g_ActiveConfig.bEnablePixelLigting && g_ActiveConfig.backend_info.bSupportsPixelLighting && nLightsChanged[0] >= 0) // config check added because the code in here was crashing for me inside SetPSConstant4f
{
// lights don't have a 1 to 1 mapping, the color component needs to be converted to 4 floats
@ -394,6 +415,11 @@ void PixelShaderManager::SetFogParamChanged()
s_bFogParamChanged = true;
}
void PixelShaderManager::SetFogRangeAdjustChanged()
{
s_bFogRangeAdjustChanged = true;
}
void PixelShaderManager::SetColorMatrix(const float* pmatrix)
{
SetMultiPSConstant4fv(C_COLORMATRIX,7,pmatrix);

View File

@ -51,9 +51,11 @@ public:
static void SetTexCoordChanged(u8 texmapid);
static void SetFogColorChanged();
static void SetFogParamChanged();
static void SetFogRangeAdjustChanged();
static void SetColorMatrix(const float* pmatrix);
static void InvalidateXFRange(int start, int end);
static void SetMaterialColor(int index, u32 data);
};

View File

@ -157,14 +157,10 @@ inline u32 RGBA8ToRGBA6ToRGBA8(u32 src)
inline u32 RGBA8ToRGB565ToRGBA8(u32 src)
{
u32 color = src;
u32 dstr5 = (color & 0xFF0000) >> 19;
u32 dstg6 = (color & 0xFF00) >> 10;
u32 dstb5 = (color & 0xFF) >> 3;
u32 dstr8 = (dstr5 << 3) | (dstr5 >> 2);
u32 dstg8 = (dstg6 << 2) | (dstg6 >> 4);
u32 dstb8 = (dstb5 << 3) | (dstb5 >> 2);
color = 0xFF000000 | (dstr8 << 16) | (dstg8 << 8) | dstb8;
u32 color = (src & 0xF8FCF8);
color |= (color >> 5) & 0x070007;
color |= (color >> 6) & 0x000300;
color |= 0xFF000000;
return color;
}

View File

@ -216,16 +216,16 @@ unsigned int ps_constant_offset_table[] = {
68, 72, // C_ZBIAS, 8
76, 80, // C_INDTEXSCALE, 8
84, 88, 92, 96, 100, 104, // C_INDTEXMTX, 24
108, 112, // C_FOG, 8
116, 120, 124, 128, 132, // C_PLIGHTS0, 20
136, 140, 144, 148, 152, // C_PLIGHTS1, 20
156, 160, 164, 168, 172, // C_PLIGHTS2, 20
176, 180, 184, 188, 192, // C_PLIGHTS3, 20
196, 200, 204, 208, 212, // C_PLIGHTS4, 20
216, 220, 224, 228, 232, // C_PLIGHTS5, 20
236, 240, 244, 248, 252, // C_PLIGHTS6, 20
256, 260, 264, 268, 272, // C_PLIGHTS7, 20
276, 280, 284, 288, // C_PMATERIALS, 16
108, 112, 116, // C_FOG, 12
120, 124, 128, 132, 136, // C_PLIGHTS0, 20
140, 144, 148, 152, 156, // C_PLIGHTS1, 20
160, 164, 168, 172, 176, // C_PLIGHTS2, 20
180, 184, 188, 192, 196, // C_PLIGHTS3, 20
200, 204, 208, 212, 216, // C_PLIGHTS4, 20
220, 224, 228, 232, 236, // C_PLIGHTS5, 20
240, 244, 248, 252, 256, // C_PLIGHTS6, 20
260, 264, 268, 272, 276, // C_PLIGHTS7, 20
280, 284, 288, 292 // C_PMATERIALS, 16
};
void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{