VideoCommon: refactor PixelShaderManager setters

The old way was to use a dirty flag per setter. Now we just update the const buffer per setter directly.
The old optimization isn't needed any more as the setters don't call the backend any more.

The follow parts are rewritten:

Alpha

ZTextureType

zbias

FogParam

FogColor

Color

TexDim

IndMatrix

MaterialColor

FogRangeAdjust

Lights
This commit is contained in:
degasus 2013-10-07 21:57:18 +02:00
parent 15ed0ea9cf
commit cc6c454898
6 changed files with 157 additions and 358 deletions

View File

@ -168,11 +168,15 @@ void BPWritten(const BPCmd& bp)
case BPMEM_IND_MTXA+6:
case BPMEM_IND_MTXB+6:
case BPMEM_IND_MTXC+6:
if(bp.changes)
PixelShaderManager::SetIndMatrixChanged((bp.address - BPMEM_IND_MTXA) / 3);
break;
case BPMEM_RAS1_SS0: // Index Texture Coordinate Scale 0
if(bp.changes)
PixelShaderManager::SetIndTexScaleChanged(0x03);
break;
case BPMEM_RAS1_SS1: // Index Texture Coordinate Scale 1
if(bp.changes)
PixelShaderManager::SetIndTexScaleChanged(0x0c);
break;
// ----------------
@ -220,6 +224,7 @@ void BPWritten(const BPCmd& bp)
case BPMEM_CONSTANTALPHA: // Set Destination Alpha
{
PRIM_LOG("constalpha: alp=%d, en=%d", bpmem.dstalpha.alpha, bpmem.dstalpha.enable);
if(bp.changes & 0xFF)
PixelShaderManager::SetDestAlpha(bpmem.dstalpha);
if(bp.changes & 0x100)
SetBlendMode();
@ -341,28 +346,31 @@ void BPWritten(const BPCmd& bp)
case BPMEM_FOGRANGE+3:
case BPMEM_FOGRANGE+4:
case BPMEM_FOGRANGE+5:
if (!GetConfig(CONFIG_DISABLEFOG))
if (!GetConfig(CONFIG_DISABLEFOG) && bp.changes)
PixelShaderManager::SetFogRangeAdjustChanged();
break;
case BPMEM_FOGPARAM0:
case BPMEM_FOGBMAGNITUDE:
case BPMEM_FOGBEXPONENT:
case BPMEM_FOGPARAM3:
if (!GetConfig(CONFIG_DISABLEFOG))
if (!GetConfig(CONFIG_DISABLEFOG) && bp.changes)
PixelShaderManager::SetFogParamChanged();
break;
case BPMEM_FOGCOLOR: // Fog Color
if (!GetConfig(CONFIG_DISABLEFOG))
if (!GetConfig(CONFIG_DISABLEFOG) && bp.changes)
PixelShaderManager::SetFogColorChanged();
break;
case BPMEM_ALPHACOMPARE: // Compare Alpha Values
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alpha_test.ref0,
bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1, bpmem.alpha_test.logic);
if(bp.changes & 0xFFFF)
PixelShaderManager::SetAlpha(bpmem.alpha_test);
if(bp.changes)
g_renderer->SetColorMask();
break;
case BPMEM_BIAS: // BIAS
PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias);
if(bp.changes)
PixelShaderManager::SetZTextureBias(bpmem.ztex1.bias);
break;
case BPMEM_ZTEX2: // Z Texture type
@ -573,6 +581,7 @@ void BPWritten(const BPCmd& bp)
case BPMEM_SU_TSIZE+12:
case BPMEM_SU_SSIZE+14:
case BPMEM_SU_TSIZE+14:
if(bp.changes)
PixelShaderManager::SetTexCoordChanged((bp.address - BPMEM_SU_SSIZE) >> 1);
break;
// ------------------------

View File

@ -11,80 +11,22 @@
#include "VideoConfig.h"
#include "RenderBase.h"
static int s_nColorsChanged[2]; // 0 - regular colors, 1 - k colors
static int s_nIndTexMtxChanged;
static bool s_bAlphaChanged;
static bool s_bZBiasChanged;
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 lastRGBAfull[2][4][4];
static u8 s_nTexDimsChanged;
static u8 s_nIndTexScaleChanged;
static u32 lastAlpha;
static u32 lastTexDims[8]; // width | height << 16 | wrap_s << 28 | wrap_t << 30
static u32 lastZBias;
static int nMaterialsChanged;
PixelShaderConstants PixelShaderManager::constants;
bool PixelShaderManager::dirty;
inline void SetPSConstant4f(unsigned int const_number, float f1, float f2, float f3, float f4)
{
float4* c = (float4*) &PixelShaderManager::constants;
c[const_number][0] = f1;
c[const_number][1] = f2;
c[const_number][2] = f3;
c[const_number][3] = f4;
PixelShaderManager::dirty = true;
}
inline void SetPSConstant4fv(unsigned int const_number, const float *f)
{
float4* c = (float4*) &PixelShaderManager::constants;
c[const_number][0] = f[0];
c[const_number][1] = f[1];
c[const_number][2] = f[2];
c[const_number][3] = f[3];
PixelShaderManager::dirty = true;
}
inline void SetMultiPSConstant4fv(unsigned int const_number, unsigned int count, const float *f)
{
float4* c = (float4*) &PixelShaderManager::constants;
for(u32 i=0; i<count; i++)
{
c[const_number+i][0] = f[0 + 4*i];
c[const_number+i][1] = f[1 + 4*i];
c[const_number+i][2] = f[2 + 4*i];
c[const_number+i][3] = f[3 + 4*i];
}
PixelShaderManager::dirty = true;
}
void PixelShaderManager::Init()
{
lastAlpha = 0;
memset(lastTexDims, 0, sizeof(lastTexDims));
lastZBias = 0;
memset(lastRGBAfull, 0, sizeof(lastRGBAfull));
memset(&constants, 0, sizeof(constants));
Dirty();
}
void PixelShaderManager::Dirty()
{
s_nColorsChanged[0] = s_nColorsChanged[1] = 15;
s_nTexDimsChanged = 0xFF;
s_nIndTexScaleChanged = 0xFF;
s_nIndTexMtxChanged = 15;
s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true;
s_bFogRangeAdjustChanged = s_bFogColorChanged = s_bFogParamChanged = true;
s_bFogRangeAdjustChanged = true;
nLightsChanged[0] = 0; nLightsChanged[1] = 0x80;
nMaterialsChanged = 15;
dirty = true;
}
@ -95,166 +37,10 @@ void PixelShaderManager::Shutdown()
void PixelShaderManager::SetConstants(u32 components)
{
for (int i = 0; i < 2; ++i)
{
if (s_nColorsChanged[i])
{
int baseind = i ? C_KCOLORS : C_COLORS;
for (int j = 0; j < 4; ++j)
{
if ((s_nColorsChanged[i] & (1 << j)))
{
SetPSConstant4fv(baseind+j, &lastRGBAfull[i][j][0]);
s_nColorsChanged[i] &= ~(1<<j);
}
}
}
}
if (s_nTexDimsChanged)
{
for (int i = 0; i < 8; ++i)
{
if ((s_nTexDimsChanged & (1<<i)))
{
SetPSTextureDims(i);
s_nTexDimsChanged &= ~(1<<i);
}
}
}
if (s_bAlphaChanged)
{
SetPSConstant4f(C_ALPHA, (lastAlpha&0xff)/255.0f, ((lastAlpha>>8)&0xff)/255.0f, 0, ((lastAlpha>>16)&0xff)/255.0f);
s_bAlphaChanged = false;
}
if (s_bZTextureTypeChanged)
{
float ftemp[4];
switch (bpmem.ztex2.type)
{
case 0:
// 8 bits
ftemp[0] = 0; ftemp[1] = 0; ftemp[2] = 0; ftemp[3] = 255.0f/16777215.0f;
break;
case 1:
// 16 bits
ftemp[0] = 255.0f/16777215.0f; ftemp[1] = 0; ftemp[2] = 0; ftemp[3] = 65280.0f/16777215.0f;
break;
case 2:
// 24 bits
ftemp[0] = 16711680.0f/16777215.0f; ftemp[1] = 65280.0f/16777215.0f; ftemp[2] = 255.0f/16777215.0f; ftemp[3] = 0;
break;
}
SetPSConstant4fv(C_ZBIAS, ftemp);
s_bZTextureTypeChanged = false;
}
if (s_bZBiasChanged || s_bDepthRangeChanged)
{
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
// [0] = width/2
// [1] = height/2
// [2] = 16777215 * (farz - nearz)
// [3] = xorig + width/2 + 342
// [4] = yorig + height/2 + 342
// [5] = 16777215 * farz
//ERROR_LOG("pixel=%x,%x, bias=%x\n", bpmem.zcontrol.pixel_format, bpmem.ztex2.type, lastZBias);
SetPSConstant4f(C_ZBIAS+1, xfregs.viewport.farZ / 16777216.0f, xfregs.viewport.zRange / 16777216.0f, 0, (float)(lastZBias)/16777215.0f);
s_bZBiasChanged = s_bDepthRangeChanged = false;
}
// indirect incoming texture scales
if (s_nIndTexScaleChanged)
{
// set as two sets of vec4s, each containing S and T of two ind stages.
float f[8];
if (s_nIndTexScaleChanged & 0x03)
{
for (u32 i = 0; i < 2; ++i)
{
f[2 * i] = bpmem.texscale[0].getScaleS(i & 1);
f[2 * i + 1] = bpmem.texscale[0].getScaleT(i & 1);
PRIM_LOG("tex indscale%d: %f %f\n", i, f[2 * i], f[2 * i + 1]);
}
SetPSConstant4fv(C_INDTEXSCALE, f);
}
if (s_nIndTexScaleChanged & 0x0c)
{
for (u32 i = 2; i < 4; ++i)
{
f[2 * i] = bpmem.texscale[1].getScaleS(i & 1);
f[2 * i + 1] = bpmem.texscale[1].getScaleT(i & 1);
PRIM_LOG("tex indscale%d: %f %f\n", i, f[2 * i], f[2 * i + 1]);
}
SetPSConstant4fv(C_INDTEXSCALE+1, &f[4]);
}
s_nIndTexScaleChanged = 0;
}
if (s_nIndTexMtxChanged)
{
for (int i = 0; i < 3; ++i)
{
if (s_nIndTexMtxChanged & (1 << i))
{
int scale = ((u32)bpmem.indmtx[i].col0.s0 << 0) |
((u32)bpmem.indmtx[i].col1.s1 << 2) |
((u32)bpmem.indmtx[i].col2.s2 << 4);
float fscale = powf(2.0f, (float)(scale - 17)) / 1024.0f;
// xyz - static matrix
// TODO w - dynamic matrix scale / 256...... somehow / 4 works better
// rev 2972 - now using / 256.... verify that this works
SetPSConstant4f(C_INDTEXMTX + 2 * i,
bpmem.indmtx[i].col0.ma * fscale,
bpmem.indmtx[i].col1.mc * fscale,
bpmem.indmtx[i].col2.me * fscale,
fscale * 4.0f);
SetPSConstant4f(C_INDTEXMTX + 2 * i + 1,
bpmem.indmtx[i].col0.mb * fscale,
bpmem.indmtx[i].col1.md * fscale,
bpmem.indmtx[i].col2.mf * fscale,
fscale * 4.0f);
PRIM_LOG("indmtx%d: scale=%f, mat=(%f %f %f; %f %f %f)\n",
i, 1024.0f*fscale,
bpmem.indmtx[i].col0.ma * fscale, bpmem.indmtx[i].col1.mc * fscale, bpmem.indmtx[i].col2.me * fscale,
bpmem.indmtx[i].col0.mb * fscale, bpmem.indmtx[i].col1.md * fscale, bpmem.indmtx[i].col2.mf * fscale);
s_nIndTexMtxChanged &= ~(1 << i);
}
}
}
if (s_bFogColorChanged)
{
SetPSConstant4f(C_FOG, bpmem.fog.color.r / 255.0f, bpmem.fog.color.g / 255.0f, bpmem.fog.color.b / 255.0f, 0);
s_bFogColorChanged = false;
}
if (s_bFogParamChanged)
{
if(!g_ActiveConfig.bDisableFog)
{
//downscale magnitude to 0.24 bits
float b = (float)bpmem.fog.b_magnitude / 0xFFFFFF;
float b_shf = (float)(1 << bpmem.fog.b_shift);
SetPSConstant4f(C_FOG + 1, bpmem.fog.a.GetA(), b, bpmem.fog.c_proj_fsel.GetC(), b_shf);
}
else
SetPSConstant4f(C_FOG + 1, 0.0, 1.0, 0.0, 1.0);
s_bFogParamChanged = false;
}
if (s_bFogRangeAdjustChanged)
{
// set by two components, so keep changed flag here
// TODO: try to split both registers and move this logic to the shader
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;
@ -267,12 +53,17 @@ void PixelShaderManager::SetConstants(u32 components)
// they always seems to be larger than 256 so my theory is :
// 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
SetPSConstant4f(C_FOG + 2, ScreenSpaceCenter, (float)Renderer::EFBToScaledX((int)(2.0f * xfregs.viewport.wd)), bpmem.fogRange.K[4].HI / 256.0f,0.0f);
constants.fog[2][0] = ScreenSpaceCenter;
constants.fog[2][1] = Renderer::EFBToScaledX((int)(2.0f * xfregs.viewport.wd));
constants.fog[2][2] = bpmem.fogRange.K[4].HI / 256.0f;
}
else
{
SetPSConstant4f(C_FOG + 2, 0.0f, 1.0f, 1.0f, 0.0f); // Need to update these values for older hardware that fails to divide by zero in shaders.
constants.fog[2][0] = 0;
constants.fog[2][1] = 1;
constants.fog[2][2] = 1;
}
dirty = true;
s_bFogRangeAdjustChanged = false;
}
@ -289,12 +80,10 @@ void PixelShaderManager::SetConstants(u32 components)
for (int i = istart; i < iend; ++i)
{
u32 color = *(const u32*)(xfmemptr + 3);
float NormalizationCoef = 1 / 255.0f;
SetPSConstant4f(C_PLIGHTS + 5 * i,
((color >> 24) & 0xFF) * NormalizationCoef,
((color >> 16) & 0xFF) * NormalizationCoef,
((color >> 8) & 0xFF) * NormalizationCoef,
((color) & 0xFF) * NormalizationCoef);
constants.plights[5*i][0] = ((color >> 24) & 0xFF) / 255.0f;
constants.plights[5*i][1] = ((color >> 16) & 0xFF) / 255.0f;
constants.plights[5*i][2] = ((color >> 8) & 0xFF) / 255.0f;
constants.plights[5*i][3] = ((color) & 0xFF) / 255.0f;
xfmemptr += 4;
for (int j = 0; j < 4; ++j, xfmemptr += 3)
@ -303,174 +92,180 @@ void PixelShaderManager::SetConstants(u32 components)
fabs(xfmemptr[0]) < 0.00001f &&
fabs(xfmemptr[1]) < 0.00001f &&
fabs(xfmemptr[2]) < 0.00001f)
{
// dist attenuation, make sure not equal to 0!!!
SetPSConstant4f(C_PLIGHTS+5*i+j+1, 0.00001f, xfmemptr[1], xfmemptr[2], 0);
}
constants.plights[5*i+j+1][0] = 0.00001f;
else
{
SetPSConstant4fv(C_PLIGHTS+5*i+j+1, xfmemptr);
}
constants.plights[5*i+j+1][0] = xfmemptr[0];
constants.plights[5*i+j+1][1] = xfmemptr[1];
constants.plights[5*i+j+1][2] = xfmemptr[2];
}
}
dirty = true;
nLightsChanged[0] = nLightsChanged[1] = -1;
}
if (nMaterialsChanged)
{
float GC_ALIGNED16(material[4]);
float NormalizationCoef = 1 / 255.0f;
for (int i = 0; i < 2; ++i)
{
if (nMaterialsChanged & (1 << i))
{
u32 data = *(xfregs.ambColor + i);
material[0] = ((data >> 24) & 0xFF) * NormalizationCoef;
material[1] = ((data >> 16) & 0xFF) * NormalizationCoef;
material[2] = ((data >> 8) & 0xFF) * NormalizationCoef;
material[3] = ( data & 0xFF) * NormalizationCoef;
SetPSConstant4fv(C_PMATERIALS + i, material);
}
}
for (int i = 0; i < 2; ++i)
{
if (nMaterialsChanged & (1 << (i + 2)))
{
u32 data = *(xfregs.matColor + i);
material[0] = ((data >> 24) & 0xFF) * NormalizationCoef;
material[1] = ((data >> 16) & 0xFF) * NormalizationCoef;
material[2] = ((data >> 8) & 0xFF) * NormalizationCoef;
material[3] = ( data & 0xFF) * NormalizationCoef;
SetPSConstant4fv(C_PMATERIALS + i + 2, material);
}
}
nMaterialsChanged = 0;
}
}
}
void PixelShaderManager::SetPSTextureDims(int texid)
{
// texdims.xy are reciprocals of the real texture dimensions
// texdims.zw are the scaled dimensions
float fdims[4];
TCoordInfo& tc = bpmem.texcoords[texid];
fdims[0] = 1.0f / (float)(lastTexDims[texid] & 0xffff);
fdims[1] = 1.0f / (float)((lastTexDims[texid] >> 16) & 0xfff);
fdims[2] = (float)(tc.s.scale_minus_1 + 1);
fdims[3] = (float)(tc.t.scale_minus_1 + 1);
PRIM_LOG("texdims%d: %f %f %f %f\n", texid, fdims[0], fdims[1], fdims[2], fdims[3]);
SetPSConstant4fv(C_TEXDIMS + texid, fdims);
}
// This one is high in profiles (0.5%).
// TODO: Move conversion out, only store the raw color value
// and update it when the shader constant is set, only.
// TODO: Conversion should be checked in the context of tev_fixes..
void PixelShaderManager::SetColorChanged(int type, int num, bool high)
{
float *pf = &lastRGBAfull[type][num][0];
float4* c = type ? constants.kcolors : constants.colors;
if (!high)
{
int r = bpmem.tevregs[num].low.a;
int a = bpmem.tevregs[num].low.b;
pf[0] = (float)r * (1.0f / 255.0f);
pf[3] = (float)a * (1.0f / 255.0f);
c[num][0] = bpmem.tevregs[num].low.a / 255.0f;
c[num][3] = bpmem.tevregs[num].low.b / 255.0f;
}
else
{
int b = bpmem.tevregs[num].high.a;
int g = bpmem.tevregs[num].high.b;
pf[1] = (float)g * (1.0f / 255.0f);
pf[2] = (float)b * (1.0f / 255.0f);
c[num][2] = bpmem.tevregs[num].high.a / 255.0f;
c[num][1] = bpmem.tevregs[num].high.b / 255.0f;
}
dirty = true;
s_nColorsChanged[type] |= 1 << num;
PRIM_LOG("pixel %scolor%d: %f %f %f %f\n", type?"k":"", num, pf[0], pf[1], pf[2], pf[3]);
PRIM_LOG("pixel %scolor%d: %f %f %f %f\n", type?"k":"", num, c[num][0], c[num][1], c[num][2], c[num][3]);
}
void PixelShaderManager::SetAlpha(const AlphaTest& alpha)
{
if ((alpha.hex & 0xffff) != lastAlpha)
{
lastAlpha = (lastAlpha & ~0xffff) | (alpha.hex & 0xffff);
s_bAlphaChanged = true;
}
constants.alpha[0] = alpha.ref0 / 255.0f;
constants.alpha[1] = alpha.ref1 / 255.0f;
dirty = true;
}
void PixelShaderManager::SetDestAlpha(const ConstantAlpha& alpha)
{
if (alpha.alpha != (lastAlpha >> 16))
{
lastAlpha = (lastAlpha & ~0xff0000) | ((alpha.hex & 0xff) << 16);
s_bAlphaChanged = true;
}
constants.alpha[3] = alpha.alpha;
dirty = true;
}
void PixelShaderManager::SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt)
{
u32 wh = width | (height << 16) | (wraps << 28) | (wrapt << 30);
if (lastTexDims[texmapid] != wh)
{
lastTexDims[texmapid] = wh;
s_nTexDimsChanged |= 1 << texmapid;
}
// TODO: move this check out to callee. There we could just call this function on texture changes
// or better, use textureSize() in glsl
if(constants.texdims[texmapid][0] != 1.0f/width || constants.texdims[texmapid][1] != 1.0f/height)
dirty = true;
constants.texdims[texmapid][0] = 1.0f/width;
constants.texdims[texmapid][1] = 1.0f/height;
}
void PixelShaderManager::SetZTextureBias(u32 bias)
{
if (lastZBias != bias)
{
s_bZBiasChanged = true;
lastZBias = bias;
}
constants.zbias[1][3] = bias/16777215.0f;
dirty = true;
}
void PixelShaderManager::SetViewportChanged()
{
s_bDepthRangeChanged = true;
constants.zbias[1][0] = xfregs.viewport.farZ / 16777216.0f;
constants.zbias[1][1] = xfregs.viewport.zRange / 16777216.0f;
dirty = true;
s_bFogRangeAdjustChanged = true; // TODO: Shouldn't be necessary with an accurate fog range adjust implementation
}
void PixelShaderManager::SetIndTexScaleChanged(u8 stagemask)
{
s_nIndTexScaleChanged |= stagemask;
bool high_stage = stagemask == 0x0c;
constants.indtexscale[high_stage][0] = bpmem.texscale[high_stage].getScaleS(0);
constants.indtexscale[high_stage][1] = bpmem.texscale[high_stage].getScaleT(0);
constants.indtexscale[high_stage][2] = bpmem.texscale[high_stage].getScaleS(1);
constants.indtexscale[high_stage][3] = bpmem.texscale[high_stage].getScaleT(1);
dirty = true;
}
void PixelShaderManager::SetIndMatrixChanged(int matrixidx)
{
s_nIndTexMtxChanged |= 1 << matrixidx;
int scale = ((u32)bpmem.indmtx[matrixidx].col0.s0 << 0) |
((u32)bpmem.indmtx[matrixidx].col1.s1 << 2) |
((u32)bpmem.indmtx[matrixidx].col2.s2 << 4);
float fscale = powf(2.0f, (float)(scale - 17)) / 1024.0f;
// xyz - static matrix
// TODO w - dynamic matrix scale / 256...... somehow / 4 works better
// rev 2972 - now using / 256.... verify that this works
constants.indtexmts[2*matrixidx][0] = bpmem.indmtx[matrixidx].col0.ma * fscale;
constants.indtexmts[2*matrixidx][1] = bpmem.indmtx[matrixidx].col1.mc * fscale;
constants.indtexmts[2*matrixidx][2] = bpmem.indmtx[matrixidx].col2.me * fscale;
constants.indtexmts[2*matrixidx][3] = fscale * 4.0f;
constants.indtexmts[2*matrixidx+1][0] = bpmem.indmtx[matrixidx].col0.mb * fscale;
constants.indtexmts[2*matrixidx+1][1] = bpmem.indmtx[matrixidx].col1.md * fscale;
constants.indtexmts[2*matrixidx+1][2] = bpmem.indmtx[matrixidx].col2.mf * fscale;
constants.indtexmts[2*matrixidx+1][3] = fscale * 4.0f;
dirty = true;
PRIM_LOG("indmtx%d: scale=%f, mat=(%f %f %f; %f %f %f)\n",
matrixidx, 1024.0f*fscale,
bpmem.indmtx[matrixidx].col0.ma * fscale, bpmem.indmtx[matrixidx].col1.mc * fscale, bpmem.indmtx[matrixidx].col2.me * fscale,
bpmem.indmtx[matrixidx].col0.mb * fscale, bpmem.indmtx[matrixidx].col1.md * fscale, bpmem.indmtx[matrixidx].col2.mf * fscale);
}
void PixelShaderManager::SetZTextureTypeChanged()
{
s_bZTextureTypeChanged = true;
switch (bpmem.ztex2.type)
{
case TEV_ZTEX_TYPE_U8:
constants.zbias[0][0] = 0;
constants.zbias[0][1] = 0;
constants.zbias[0][2] = 0;
constants.zbias[0][3] = 255.0f/16777215.0f;
break;
case TEV_ZTEX_TYPE_U16:
constants.zbias[0][0] = 255.0f/16777215.0f;
constants.zbias[0][1] = 0;
constants.zbias[0][2] = 0;
constants.zbias[0][3] = 65280.0f/16777215.0f;
break;
case TEV_ZTEX_TYPE_U24:
constants.zbias[0][0] = 16711680.0f/16777215.0f;
constants.zbias[0][1] = 65280.0f/16777215.0f;
constants.zbias[0][2] = 255.0f/16777215.0f;
constants.zbias[0][3] = 0;
break;
default:
break;
}
dirty = true;
}
void PixelShaderManager::SetTexCoordChanged(u8 texmapid)
{
s_nTexDimsChanged |= 1 << texmapid;
TCoordInfo& tc = bpmem.texcoords[texmapid];
constants.texdims[texmapid][2] = tc.s.scale_minus_1 + 1;
constants.texdims[texmapid][3] = tc.t.scale_minus_1 + 1;
dirty = true;
}
void PixelShaderManager::SetFogColorChanged()
{
s_bFogColorChanged = true;
constants.fog[0][0] = bpmem.fog.color.r / 255.0f;
constants.fog[0][1] = bpmem.fog.color.g / 255.0f;
constants.fog[0][2] = bpmem.fog.color.b / 255.0f;
dirty = true;
}
void PixelShaderManager::SetFogParamChanged()
{
s_bFogParamChanged = true;
if(!g_ActiveConfig.bDisableFog)
{
constants.fog[1][0] = bpmem.fog.a.GetA();
constants.fog[1][1] = (float)bpmem.fog.b_magnitude / 0xFFFFFF;
constants.fog[1][2] = bpmem.fog.c_proj_fsel.GetC();
constants.fog[1][3] = 1 << bpmem.fog.b_shift;
}
else
{
constants.fog[1][0] = 0;
constants.fog[1][1] = 1;
constants.fog[1][2] = 0;
constants.fog[1][3] = 1;
}
dirty = true;
}
void PixelShaderManager::SetFogRangeAdjustChanged()
@ -478,12 +273,6 @@ void PixelShaderManager::SetFogRangeAdjustChanged()
s_bFogRangeAdjustChanged = true;
}
void PixelShaderManager::SetColorMatrix(const float* pmatrix)
{
SetMultiPSConstant4fv(C_COLORMATRIX,7,pmatrix);
s_nColorsChanged[0] = s_nColorsChanged[1] = 15;
}
void PixelShaderManager::InvalidateXFRange(int start, int end)
{
if (start < XFMEM_LIGHTS_END && end > XFMEM_LIGHTS)
@ -504,17 +293,20 @@ void PixelShaderManager::InvalidateXFRange(int start, int end)
}
}
void PixelShaderManager::SetMaterialColorChanged(int index)
void PixelShaderManager::SetMaterialColorChanged(int index, u32 color)
{
nMaterialsChanged |= (1 << index);
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
constants.pmaterials[index][0] = ((color >> 24) & 0xFF) / 255.0f;
constants.pmaterials[index][1] = ((color >> 16) & 0xFF) / 255.0f;
constants.pmaterials[index][2] = ((color >> 8) & 0xFF) / 255.0f;
constants.pmaterials[index][3] = ( color & 0xFF) / 255.0f;
dirty = true;
}
}
void PixelShaderManager::DoState(PointerWrap &p)
{
p.Do(lastRGBAfull);
p.Do(lastAlpha);
p.Do(lastTexDims);
p.Do(lastZBias);
p.Do(constants);
p.Do(dirty);

View File

@ -17,7 +17,6 @@ class PointerWrap;
// The non-API dependent parts.
class PixelShaderManager
{
static void SetPSTextureDims(int texid);
public:
static void Init();
static void Dirty();
@ -41,9 +40,8 @@ public:
static void SetFogColorChanged();
static void SetFogParamChanged();
static void SetFogRangeAdjustChanged();
static void SetColorMatrix(const float* pmatrix);
static void InvalidateXFRange(int start, int end);
static void SetMaterialColorChanged(int index);
static void SetMaterialColorChanged(int index, u32 color);
static PixelShaderConstants constants;
static bool dirty;

View File

@ -643,7 +643,7 @@ void VertexShaderManager::SetProjectionChanged()
bProjectionChanged = true;
}
void VertexShaderManager::SetMaterialColorChanged(int index)
void VertexShaderManager::SetMaterialColorChanged(int index, u32 color)
{
nMaterialsChanged |= (1 << index);
}

View File

@ -31,7 +31,7 @@ public:
static void SetTexMatrixChangedB(u32 value);
static void SetViewportChanged();
static void SetProjectionChanged();
static void SetMaterialColorChanged(int index);
static void SetMaterialColorChanged(int index, u32 color);
static void TranslateView(float x, float y, float z = 0.0f);
static void RotateView(float x, float y);

View File

@ -60,8 +60,8 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
if (xfregs.ambColor[chan] != newValue)
{
VertexManager::Flush();
VertexShaderManager::SetMaterialColorChanged(chan);
PixelShaderManager::SetMaterialColorChanged(chan);
VertexShaderManager::SetMaterialColorChanged(chan, newValue);
PixelShaderManager::SetMaterialColorChanged(chan, newValue);
}
break;
}
@ -73,8 +73,8 @@ void XFRegWritten(int transferSize, u32 baseAddress, u32 *pData)
if (xfregs.matColor[chan] != newValue)
{
VertexManager::Flush();
VertexShaderManager::SetMaterialColorChanged(chan + 2);
PixelShaderManager::SetMaterialColorChanged(chan + 2);
VertexShaderManager::SetMaterialColorChanged(chan + 2, newValue);
PixelShaderManager::SetMaterialColorChanged(chan + 2, newValue);
}
break;
}