diff --git a/Source/Core/Common/Src/LinearDiskCache.h b/Source/Core/Common/Src/LinearDiskCache.h index 76a304f57c..f467646ccc 100644 --- a/Source/Core/Common/Src/LinearDiskCache.h +++ b/Source/Core/Common/Src/LinearDiskCache.h @@ -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: diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h index abafe201d2..422b515dcc 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.h +++ b/Source/Core/VideoCommon/Src/BPMemory.h @@ -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 diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index 9a8e5af10c..17ca146653 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -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: diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 8c3805df9a..f5f9c84f46 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -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"); + } diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.h b/Source/Core/VideoCommon/Src/PixelShaderGen.h index e2d8ca847e..10c39ad34e 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.h +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.h @@ -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) diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp index fb484ca0c0..96ba2cb3f2 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.cpp @@ -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); diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.h b/Source/Core/VideoCommon/Src/PixelShaderManager.h index de46341441..f3428eda6f 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.h +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.h @@ -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); + }; diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index 5a573369cd..0b29874178 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -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; } diff --git a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp index 285d9a4335..a61c8688a3 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/PixelShaderCache.cpp @@ -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) {