revised how texture scaling is handled. it now works correctly when adding output together from indirect stages which use power 2 and non power 2 textures and it is simpler.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2972 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
946491c8ea
commit
66ca49d3b8
|
@ -99,8 +99,9 @@ void BPWritten(const Bypass& bp)
|
||||||
PixelShaderManager::SetIndMatrixChanged((bp.address - BPMEM_IND_MTXA) / 3);
|
PixelShaderManager::SetIndMatrixChanged((bp.address - BPMEM_IND_MTXA) / 3);
|
||||||
break;
|
break;
|
||||||
case BPMEM_RAS1_SS0: // Index Texture Coordinate Scale 0
|
case BPMEM_RAS1_SS0: // Index Texture Coordinate Scale 0
|
||||||
|
PixelShaderManager::SetIndTexScaleChanged(0x03);
|
||||||
case BPMEM_RAS1_SS1: // Index Texture Coordinate Scale 1
|
case BPMEM_RAS1_SS1: // Index Texture Coordinate Scale 1
|
||||||
PixelShaderManager::SetIndTexScaleChanged();
|
PixelShaderManager::SetIndTexScaleChanged(0x0c);
|
||||||
break;
|
break;
|
||||||
case BPMEM_SCISSORTL: // Scissor Rectable Top, Left
|
case BPMEM_SCISSORTL: // Scissor Rectable Top, Left
|
||||||
case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right
|
case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right
|
||||||
|
@ -408,6 +409,7 @@ void BPWritten(const Bypass& bp)
|
||||||
case BPMEM_SU_TSIZE+12:
|
case BPMEM_SU_TSIZE+12:
|
||||||
case BPMEM_SU_SSIZE+14:
|
case BPMEM_SU_SSIZE+14:
|
||||||
case BPMEM_SU_TSIZE+14:
|
case BPMEM_SU_TSIZE+14:
|
||||||
|
PixelShaderManager::SetTexCoordChanged((bp.address - BPMEM_SU_SSIZE) >> 1);
|
||||||
break;
|
break;
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// BPMEM_TX_SETMODE0 - (Texture lookup and filtering mode) LOD/BIAS Clamp, MaxAnsio, LODBIAS, DiagLoad, Min Filter, Mag Filter, Wrap T, S
|
// BPMEM_TX_SETMODE0 - (Texture lookup and filtering mode) LOD/BIAS Clamp, MaxAnsio, LODBIAS, DiagLoad, Min Filter, Mag Filter, Wrap T, S
|
||||||
|
|
|
@ -131,7 +131,7 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 zbufrender, u3
|
||||||
// tevtemp is set according to swapmodetables and
|
// tevtemp is set according to swapmodetables and
|
||||||
|
|
||||||
static void WriteStage(char *&p, int n, u32 texture_mask);
|
static void WriteStage(char *&p, int n, u32 texture_mask);
|
||||||
static void WrapNonPow2Tex(char* &p, const char* var, int texmap, u32 texture_mask);
|
static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, u32 texture_mask);
|
||||||
static void WriteAlphaCompare(char *&p, int num, int comp);
|
static void WriteAlphaCompare(char *&p, int num, int comp);
|
||||||
static bool WriteAlphaTest(char *&p, bool HLSL);
|
static bool WriteAlphaTest(char *&p, bool HLSL);
|
||||||
static void WriteFog(char *&p, bool bOutputZ);
|
static void WriteFog(char *&p, bool bOutputZ);
|
||||||
|
@ -347,7 +347,7 @@ static const char *tevIndAlphaScale[] = {"", "*32","*16","*8"};
|
||||||
static const char *tevIndBiasField[] = {"", "x", "y", "xy", "z", "xz", "yz", "xyz"}; // indexed by bias
|
static const char *tevIndBiasField[] = {"", "x", "y", "xy", "z", "xz", "yz", "xyz"}; // indexed by bias
|
||||||
static const char *tevIndBiasAdd[] = {"-128.0f", "1.0f", "1.0f", "1.0f" }; // indexed by fmt
|
static const char *tevIndBiasAdd[] = {"-128.0f", "1.0f", "1.0f", "1.0f" }; // indexed by fmt
|
||||||
static const char *tevIndWrapStart[] = {"0", "256", "128", "64", "32", "16", "0.001" };
|
static const char *tevIndWrapStart[] = {"0", "256", "128", "64", "32", "16", "0.001" };
|
||||||
static const char *tevIndFmtScale[] = {"255.0f", "31.0f", "15.0f", "8.0f" };
|
static const char *tevIndFmtScale[] = {"255.0f", "31.0f", "15.0f", "7.0f" };
|
||||||
|
|
||||||
#define WRITE p+=sprintf
|
#define WRITE p+=sprintf
|
||||||
|
|
||||||
|
@ -463,14 +463,20 @@ const char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool
|
||||||
"float3 comp16 = float3(1,255,0), comp24 = float3(1,255,255*255);\n"
|
"float3 comp16 = float3(1,255,0), comp24 = float3(1,255,255*255);\n"
|
||||||
"float4 alphabump=0;\n"
|
"float4 alphabump=0;\n"
|
||||||
"float3 tevcoord;\n"
|
"float3 tevcoord;\n"
|
||||||
"float2 wrappedcoord, tempcoord;\n");
|
"float2 wrappedcoord, tempcoord;\n\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < numTexgen; ++i) {
|
||||||
|
// optional perspective divides
|
||||||
|
if (xfregs.texcoords[i].texmtxinfo.projection == XF_TEXPROJ_STQ)
|
||||||
|
WRITE(p, "uv%d.xy = uv%d.xy/uv%d.z;\n", i, i, i);
|
||||||
|
|
||||||
|
// scale texture coordinates
|
||||||
|
WRITE(p, "uv%d.xy = uv%d.xy * "I_TEXDIMS"[%d].zw;\n", i, i, i);
|
||||||
|
}
|
||||||
|
|
||||||
// indirect texture map lookup
|
// indirect texture map lookup
|
||||||
for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
|
for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
|
||||||
if (nIndirectStagesUsed & (1<<i)) {
|
if (nIndirectStagesUsed & (1<<i)) {
|
||||||
// perform indirect texture map lookup
|
|
||||||
// note that we have to scale by the regular texture map's coordinates since this is a texRECT call
|
|
||||||
// (and we have to match with the game's texscale calls)
|
|
||||||
int texcoord = bpmem.tevindref.getTexCoord(i);
|
int texcoord = bpmem.tevindref.getTexCoord(i);
|
||||||
|
|
||||||
if (texcoord < numTexgen) {
|
if (texcoord < numTexgen) {
|
||||||
|
@ -480,13 +486,9 @@ const char *GeneratePixelShader(u32 texture_mask, bool has_zbuffer_target, bool
|
||||||
WRITE(p, "tempcoord=float2(0.0f,0.0f);\n");
|
WRITE(p, "tempcoord=float2(0.0f,0.0f);\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture_mask & (1<<bpmem.tevindref.getTexMap(i))) {
|
char buffer[32];
|
||||||
WrapNonPow2Tex(p, "tempcoord", bpmem.tevindref.getTexMap(i), texture_mask);
|
sprintf(buffer, "float3 indtex%d", i);
|
||||||
WRITE(p, "float3 indtex%d=texRECT(samp%d,tempcoord.xy).abg;\n", i, bpmem.tevindref.getTexMap(i));
|
SampleTexture(p, buffer, "tempcoord", "abg", bpmem.tevindref.getTexMap(i), texture_mask);
|
||||||
}
|
|
||||||
else {
|
|
||||||
WRITE(p, "float3 indtex%d=tex2D(samp%d,tempcoord).abg;\n", i, bpmem.tevindref.getTexMap(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +570,6 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
|
||||||
|
|
||||||
|
|
||||||
int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1);
|
int texcoord = bpmem.tevorders[n/2].getTexCoord(n&1);
|
||||||
int texfun = xfregs.texcoords[texcoord].texmtxinfo.projection;
|
|
||||||
bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens;
|
bool bHasTexCoord = (u32)texcoord < bpmem.genMode.numtexgens;
|
||||||
bool bHasIndStage = bpmem.tevind[n].IsActive() && bpmem.tevind[n].bt < bpmem.genMode.numindstages;
|
bool bHasIndStage = bpmem.tevind[n].IsActive() && bpmem.tevind[n].bt < bpmem.genMode.numindstages;
|
||||||
|
|
||||||
|
@ -579,8 +580,6 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
|
||||||
|
|
||||||
if (bHasIndStage) {
|
if (bHasIndStage) {
|
||||||
// perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords
|
// perform the indirect op on the incoming regular coordinates using indtex%d as the offset coords
|
||||||
int texmap = bpmem.tevorders[n/2].getEnable(n&1) ? bpmem.tevorders[n/2].getTexMap(n&1) : bpmem.tevindref.getTexMap(bpmem.tevind[n].bt);
|
|
||||||
|
|
||||||
if (bpmem.tevind[n].bs != ITBA_OFF) {
|
if (bpmem.tevind[n].bs != ITBA_OFF) {
|
||||||
// write the bump alpha
|
// write the bump alpha
|
||||||
|
|
||||||
|
@ -601,9 +600,10 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// format
|
||||||
|
WRITE(p, "float3 indtevcrd%d = indtex%d * %s;\n", n, bpmem.tevind[n].bt, tevIndFmtScale[bpmem.tevind[n].fmt]);
|
||||||
|
|
||||||
// bias
|
// bias
|
||||||
WRITE(p, "float3 indtevcrd%d = indtex%d;\n", n, bpmem.tevind[n].bt);
|
|
||||||
WRITE(p, "indtevcrd%d.xyz *= %s;\n", n, tevIndFmtScale[bpmem.tevind[n].fmt]);
|
|
||||||
if (bpmem.tevind[n].bias != ITB_NONE )
|
if (bpmem.tevind[n].bias != ITB_NONE )
|
||||||
WRITE(p, "indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]);
|
WRITE(p, "indtevcrd%d.%s += %s;\n", n, tevIndBiasField[bpmem.tevind[n].bias], tevIndBiasAdd[bpmem.tevind[n].fmt]);
|
||||||
|
|
||||||
|
@ -623,91 +623,43 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
|
||||||
WRITE(p, "float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n);
|
WRITE(p, "float2 indtevtrans%d = "I_INDTEXMTX"[%d].ww * uv%d.xy * indtevcrd%d.yy;\n", n, mtxidx, texcoord, n);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: I removed a superfluous argument, please check that the resulting expression is correct. (mthuurne 2008-08-27)
|
WRITE(p, "float2 indtevtrans%d = 0;\n", n);
|
||||||
WRITE(p, "float2 indtevtrans%d = 0;\n", n); //, n
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO: I removed a superfluous argument, please check that the resulting expression is correct. (mthuurne 2008-08-27)
|
WRITE(p, "float2 indtevtrans%d = 0;\n", n);
|
||||||
WRITE(p, "float2 indtevtrans%d = 0;\n", n); //, n
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// wrapping
|
// wrapping
|
||||||
if (!bpmem.tevorders[n/2].getEnable(n&1) || (texture_mask & (1<<texmap))) {
|
|
||||||
// non pow2
|
|
||||||
|
|
||||||
if (bpmem.tevind[n].sw != ITW_OFF || bpmem.tevind[n].tw != ITW_OFF) {
|
// wrap S
|
||||||
if (bpmem.tevind[n].tw == ITW_0) {
|
if (bpmem.tevind[n].sw == ITW_OFF) {
|
||||||
if (bpmem.tevind[n].sw == ITW_0) {
|
WRITE(p, "wrappedcoord.x = uv%d.x;\n", texcoord);
|
||||||
// zero out completely
|
}
|
||||||
WRITE(p, "wrappedcoord = float2(0.0f,0.0f);\n");
|
else if (bpmem.tevind[n].sw == ITW_0) {
|
||||||
}
|
WRITE(p, "wrappedcoord.x = 0.0f;\n");
|
||||||
else {
|
|
||||||
WRITE(p, "wrappedcoord.x = fmod( (uv%d.x+%s)*"I_TEXDIMS"[%d].x*"I_TEXDIMS"[%d].z, %s);\n"
|
|
||||||
"wrappedcoord.y = 0;\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw], texmap, texmap, tevIndWrapStart[bpmem.tevind[n].sw]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (bpmem.tevind[n].sw == ITW_0) {
|
|
||||||
WRITE(p, "wrappedcoord.y = fmod( (uv%d.y+%s)*"I_TEXDIMS"[%d].y*"I_TEXDIMS"[%d].w, %s);\n"
|
|
||||||
"wrappedcoord.x = 0;\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw], texmap, texmap, tevIndWrapStart[bpmem.tevind[n].tw]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
WRITE(p, "wrappedcoord = fmod( (uv%d.xy+float2(%s,%s))*"I_TEXDIMS"[%d].xy*"I_TEXDIMS"[%d].zw, float2(%s,%s));\n", texcoord,
|
|
||||||
tevIndWrapStart[bpmem.tevind[n].sw], tevIndWrapStart[bpmem.tevind[n].tw],texmap,texmap,
|
|
||||||
tevIndWrapStart[bpmem.tevind[n].sw], tevIndWrapStart[bpmem.tevind[n].tw]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
WRITE(p, "wrappedcoord = uv%d.xy*"I_TEXDIMS"[%d].xy;\n", texcoord, texmap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// pow of 2
|
WRITE(p, "wrappedcoord.x = fmod( uv%d.x, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw]);
|
||||||
WRITE(p, "indtevtrans%d.xy *= "I_TEXDIMS"[%d].xy * "I_TEXDIMS"[%d].zw;\n", n, texmap, texmap);
|
}
|
||||||
|
|
||||||
// mult by bitdepth / tex dimensions
|
// wrap T
|
||||||
if (bpmem.tevind[n].sw != ITW_OFF || bpmem.tevind[n].tw != ITW_OFF) {
|
if (bpmem.tevind[n].tw == ITW_OFF) {
|
||||||
if (bpmem.tevind[n].tw == ITW_0) {
|
WRITE(p, "wrappedcoord.y = uv%d.y;\n", texcoord);
|
||||||
if (bpmem.tevind[n].sw == ITW_0) {
|
}
|
||||||
// zero out completely
|
else if (bpmem.tevind[n].tw == ITW_0) {
|
||||||
WRITE(p, "wrappedcoord = float2(0.0f,0.0f);\n");
|
WRITE(p, "wrappedcoord.y = 0.0f;\n");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WRITE(p, "wrappedcoord.x = "I_TEXDIMS"[%d].x * fmod( uv%d.x+%s, "I_TEXDIMS"[%d].z*%s);\n"
|
WRITE(p, "wrappedcoord.y = fmod( uv%d.y, %s );\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw]);
|
||||||
"wrappedcoord.y = 0;\n", texmap, texcoord, tevIndWrapStart[bpmem.tevind[n].sw], texmap, tevIndWrapStart[bpmem.tevind[n].sw]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (bpmem.tevind[n].sw == ITW_0) {
|
|
||||||
WRITE(p, "wrappedcoord.y = "I_TEXDIMS"[%d].y * fmod( uv%d.y+%s, "I_TEXDIMS"[%d].w*%s);\n"
|
|
||||||
"wrappedcoord.x = 0;\n", texmap, texcoord, tevIndWrapStart[bpmem.tevind[n].tw], texmap, tevIndWrapStart[bpmem.tevind[n].tw]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// have to add an offset or else might get negative values!
|
|
||||||
WRITE(p, "wrappedcoord = "I_TEXDIMS"[%d].xy * fmod( uv%d.xy+float2(%s,%s), "I_TEXDIMS"[%d].zw*float2(%s,%s));\n", texmap, texcoord,
|
|
||||||
tevIndWrapStart[bpmem.tevind[n].sw], tevIndWrapStart[bpmem.tevind[n].tw], texmap,
|
|
||||||
tevIndWrapStart[bpmem.tevind[n].sw], tevIndWrapStart[bpmem.tevind[n].tw]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
WRITE(p, "wrappedcoord = uv%d.xy;\n", texcoord);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bpmem.tevind[n].fb_addprev) {
|
if (bpmem.tevind[n].fb_addprev) {
|
||||||
// add previous tevcoord
|
// add previous tevcoord
|
||||||
|
WRITE(p, "tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n);
|
||||||
if (texfun == XF_TEXPROJ_STQ) {
|
|
||||||
WRITE(p, "tevcoord.xy += wrappedcoord/uv%d.z + indtevtrans%d;\n", texcoord, n);
|
|
||||||
//WRITE(p, "tevcoord.z += uv%d.z;\n", texcoord);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
WRITE(p, "tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WRITE(p, "tevcoord.xy = wrappedcoord/uv%d.z + indtevtrans%d;\n", texcoord, n);
|
WRITE(p, "tevcoord.xy = wrappedcoord + indtevtrans%d;\n", n);
|
||||||
//if (texfun == XF_TEXPROJ_STQ )
|
|
||||||
// WRITE(p, "tevcoord.z = uv%d.z;\n", texcoord);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,43 +669,14 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
|
||||||
int texmap = bpmem.tevorders[n/2].getTexMap(n&1);
|
int texmap = bpmem.tevorders[n/2].getTexMap(n&1);
|
||||||
if(!bHasIndStage) {
|
if(!bHasIndStage) {
|
||||||
// calc tevcord
|
// calc tevcord
|
||||||
//tevcoord.xy = texdim[1].xy * uv1.xy / uv1.z;
|
|
||||||
if(bHasTexCoord) {
|
if(bHasTexCoord) {
|
||||||
if (texture_mask & (1<<texmap)) {
|
WRITE(p, "tevcoord.xy = uv%d.xy;\n", texcoord);
|
||||||
// nonpow2
|
|
||||||
if (texfun == XF_TEXPROJ_STQ )
|
|
||||||
WRITE(p, "tevcoord.xy = uv%d.xy / uv%d.z;\n", texcoord, texcoord);
|
|
||||||
else
|
|
||||||
WRITE(p, "tevcoord.xy = uv%d.xy;\n", texcoord);
|
|
||||||
WrapNonPow2Tex(p, "tevcoord", texmap, texture_mask);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (texfun == XF_TEXPROJ_STQ )
|
|
||||||
WRITE(p, "tevcoord.xy = "I_TEXDIMS"[%d].xy * uv%d.xy / uv%d.z;\n", texmap, texcoord , texcoord );
|
|
||||||
else
|
|
||||||
WRITE(p, "tevcoord.xy = "I_TEXDIMS"[%d].xy * uv%d.xy;\n", texmap, texcoord);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// donkopunchstania - check that this is correct when there are no tex gens
|
|
||||||
WRITE(p, "tevcoord.xy = float2(0.0f,0.0f);\n");
|
WRITE(p, "tevcoord.xy = float2(0.0f,0.0f);\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (texture_mask & (1<<texmap)) {
|
|
||||||
// if non pow 2, have to manually repeat
|
|
||||||
//WrapNonPow2Tex(p, "tevcoord", texmap);
|
|
||||||
bool bwraps = !!(texture_mask & (0x100<<texmap));
|
|
||||||
bool bwrapt = !!(texture_mask & (0x10000<<texmap));
|
|
||||||
|
|
||||||
if (bwraps || bwrapt) {
|
|
||||||
const char* field = bwraps ? (bwrapt ? "xy" : "x") : "y";
|
|
||||||
WRITE(p, "tevcoord.%s = fmod(tevcoord.%s+32*"I_TEXDIMS"[%d].%s,"I_TEXDIMS"[%d].%s);\n", field, field, texmap, field, texmap, field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texture_mask & (1<<texmap) )
|
SampleTexture(p, "textemp", "tevcoord", texswap, texmap, texture_mask);
|
||||||
WRITE(p, "textemp=texRECT(samp%d,tevcoord.xy).%s;\n", texmap, texswap);
|
|
||||||
else
|
|
||||||
WRITE(p, "textemp=tex2D(samp%d,tevcoord.xy).%s;\n", texmap, texswap);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
WRITE(p, "textemp=float4(1,1,1,1);\n");
|
WRITE(p, "textemp=float4(1,1,1,1);\n");
|
||||||
|
@ -860,24 +783,36 @@ static void WriteStage(char *&p, int n, u32 texture_mask)
|
||||||
WRITE(p, "\n");
|
WRITE(p, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void WrapNonPow2Tex(char* &p, const char* var, int texmap, u32 texture_mask)
|
void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, u32 texture_mask)
|
||||||
{
|
{
|
||||||
_assert_(texture_mask & (1<<texmap));
|
if (texture_mask & (1<<texmap)) {
|
||||||
bool bwraps = !!(texture_mask & (0x100<<texmap));
|
// non pow 2
|
||||||
bool bwrapt = !!(texture_mask & (0x10000<<texmap));
|
bool bwraps = (texture_mask & (0x100<<texmap)) ? true : false;
|
||||||
|
bool bwrapt = (texture_mask & (0x10000<<texmap)) ? true : false;
|
||||||
if (bwraps || bwrapt) {
|
|
||||||
const char* field = bwraps ? (bwrapt ? "xy" : "x") : "y";
|
|
||||||
const char* wrapfield = bwraps ? (bwrapt ? "zw" : "z") : "w";
|
|
||||||
WRITE(p, "%s.%s = "I_TEXDIMS"[%d].%s*frac(%s.%s*"I_TEXDIMS"[%d].%s+32);\n", var, field, texmap, field, var, field, texmap, wrapfield);
|
|
||||||
|
|
||||||
if (!bwraps )
|
if (bwraps || bwrapt) {
|
||||||
WRITE(p, "%s.x *= "I_TEXDIMS"[%d].x * "I_TEXDIMS"[%d].z;\n", var, texmap, texmap);
|
if (bwraps) {
|
||||||
if (!bwrapt )
|
WRITE(p, "tempcoord.x = fmod(%s.x, "I_TEXDIMS"[%d].x);\n", texcoords, texmap);
|
||||||
WRITE(p, "%s.y *= "I_TEXDIMS"[%d].y * "I_TEXDIMS"[%d].w;\n", var, texmap, texmap);
|
}
|
||||||
|
else {
|
||||||
|
WRITE(p, "tempcoord.x = %s.x;\n", texcoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bwrapt) {
|
||||||
|
WRITE(p, "tempcoord.y = fmod(%s.y, "I_TEXDIMS"[%d].y);\n", texcoords, texmap);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WRITE(p, "tempcoord.y = %s.y;\n", texcoords);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE(p, "%s=texRECT(samp%d,tempcoord.xy).%s;\n", destination, texmap, texswap);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WRITE(p, "%s=texRECT(samp%d,%s.xy).%s;\n", destination, texmap, texcoords, texswap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WRITE(p, "%s.xy *= "I_TEXDIMS"[%d].xy * "I_TEXDIMS"[%d].zw;\n", var, texmap, texmap);
|
WRITE(p, "%s=tex2D(samp%d,%s.xy * "I_TEXDIMS"[%d].xy).%s;\n", destination, texmap, texcoords, texmap, texswap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ static int s_nColorsChanged[2]; // 0 - regular colors, 1 - k colors
|
||||||
static int s_nIndTexMtxChanged = 0;
|
static int s_nIndTexMtxChanged = 0;
|
||||||
static bool s_bAlphaChanged;
|
static bool s_bAlphaChanged;
|
||||||
static bool s_bZBiasChanged;
|
static bool s_bZBiasChanged;
|
||||||
static bool s_bIndTexScaleChanged;
|
|
||||||
static bool s_bZTextureTypeChanged;
|
static bool s_bZTextureTypeChanged;
|
||||||
static bool s_bDepthRangeChanged;
|
static bool s_bDepthRangeChanged;
|
||||||
static bool s_bFogColorChanged;
|
static bool s_bFogColorChanged;
|
||||||
|
@ -37,8 +36,9 @@ static bool s_bFogParamChanged;
|
||||||
static float lastDepthRange[2] = {0}; // 0 = far z, 1 = far - near
|
static float lastDepthRange[2] = {0}; // 0 = far z, 1 = far - near
|
||||||
static float lastRGBAfull[2][4][4];
|
static float lastRGBAfull[2][4][4];
|
||||||
static u8 s_nTexDimsChanged;
|
static u8 s_nTexDimsChanged;
|
||||||
|
static u8 s_nIndTexScaleChanged;
|
||||||
static u32 lastAlpha = 0;
|
static u32 lastAlpha = 0;
|
||||||
static u32 lastTexDims[8]={0};
|
static u32 lastTexDims[8]={0}; // width | height << 16 | wrap_s << 28 | wrap_t << 30
|
||||||
static u32 lastZBias = 0;
|
static u32 lastZBias = 0;
|
||||||
|
|
||||||
// lower byte describes if a texture is nonpow2 or pow2
|
// lower byte describes if a texture is nonpow2 or pow2
|
||||||
|
@ -46,19 +46,14 @@ static u32 lastZBias = 0;
|
||||||
// next byte is for t channel
|
// next byte is for t channel
|
||||||
static u32 s_texturemask = 0;
|
static u32 s_texturemask = 0;
|
||||||
|
|
||||||
static int maptocoord[8]; // indexed by texture map, holds the texcoord associated with the map
|
|
||||||
static u32 maptocoord_mask = 0;
|
|
||||||
|
|
||||||
void PixelShaderManager::Init()
|
void PixelShaderManager::Init()
|
||||||
{
|
{
|
||||||
s_nColorsChanged[0] = s_nColorsChanged[1] = 0;
|
s_nColorsChanged[0] = s_nColorsChanged[1] = 0;
|
||||||
s_nTexDimsChanged = 0;
|
s_nTexDimsChanged = 0;
|
||||||
|
s_nIndTexScaleChanged = 0;
|
||||||
s_nIndTexMtxChanged = 15;
|
s_nIndTexMtxChanged = 15;
|
||||||
s_bAlphaChanged = s_bZBiasChanged = s_bIndTexScaleChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true;
|
s_bAlphaChanged = s_bZBiasChanged = s_bZTextureTypeChanged = s_bDepthRangeChanged = true;
|
||||||
s_bFogColorChanged = s_bFogParamChanged = true;
|
s_bFogColorChanged = s_bFogParamChanged = true;
|
||||||
for (int i = 0; i < 8; ++i)
|
|
||||||
maptocoord[i] = -1;
|
|
||||||
maptocoord_mask = 0;
|
|
||||||
memset(lastRGBAfull, 0, sizeof(lastRGBAfull));
|
memset(lastRGBAfull, 0, sizeof(lastRGBAfull));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,29 +76,6 @@ void PixelShaderManager::SetConstants()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 newmask = 0;
|
|
||||||
for (u32 i = 0; i < (u32)bpmem.genMode.numtevstages+1; ++i) {
|
|
||||||
if (bpmem.tevorders[i/2].getEnable(i&1)) {
|
|
||||||
int texmap = bpmem.tevorders[i/2].getTexMap(i&1);
|
|
||||||
maptocoord[texmap] = bpmem.tevorders[i/2].getTexCoord(i&1);
|
|
||||||
newmask |= 1 << texmap;
|
|
||||||
SetTexDimsChanged(texmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maptocoord_mask != newmask) {
|
|
||||||
//u32 changes = maptocoord_mask ^ newmask;
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
|
||||||
if (newmask & (1 << i)) {
|
|
||||||
SetTexDimsChanged(i);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
maptocoord[i] = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
maptocoord_mask = newmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_nTexDimsChanged) {
|
if (s_nTexDimsChanged) {
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
if (s_nTexDimsChanged & (1<<i)) {
|
if (s_nTexDimsChanged & (1<<i)) {
|
||||||
|
@ -147,30 +119,30 @@ void PixelShaderManager::SetConstants()
|
||||||
s_bZBiasChanged = s_bDepthRangeChanged = false;
|
s_bZBiasChanged = s_bDepthRangeChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// indirect incoming texture scales, update all!
|
// indirect incoming texture scales
|
||||||
if (s_bIndTexScaleChanged) {
|
if (s_nIndTexScaleChanged) {
|
||||||
// set as two sets of vec4s, each containing S and T of two ind stages.
|
// set as two sets of vec4s, each containing S and T of two ind stages.
|
||||||
float f[8];
|
float f[8];
|
||||||
|
|
||||||
for (u32 i = 0; i < bpmem.genMode.numindstages; ++i) {
|
if (s_nIndTexScaleChanged & 0x03) {
|
||||||
int srctexmap = bpmem.tevindref.getTexMap(i);
|
for (u32 i = 0; i < 2; ++i) {
|
||||||
int texcoord = bpmem.tevindref.getTexCoord(i);
|
f[2*i] = bpmem.texscale[0].getScaleS(i&1);
|
||||||
TCoordInfo& tc = bpmem.texcoords[texcoord];
|
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]);
|
||||||
f[2*i] = bpmem.texscale[i/2].getScaleS(i&1) *
|
}
|
||||||
(float)(tc.s.scale_minus_1+1) / (float)(lastTexDims[srctexmap] & 0xffff);
|
SetPSConstant4fv(C_INDTEXSCALE, f);
|
||||||
f[2*i+1] = bpmem.texscale[i/2].getScaleT(i&1) *
|
|
||||||
(float)(tc.t.scale_minus_1+1) / (float)((lastTexDims[srctexmap] >> 16) & 0xfff);
|
|
||||||
// Yes, the above should really be 0xfff. The top 4 bits are used for other stuff.
|
|
||||||
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) {
|
||||||
if (bpmem.genMode.numindstages > 2)
|
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]);
|
SetPSConstant4fv(C_INDTEXSCALE+1, &f[4]);
|
||||||
|
}
|
||||||
|
|
||||||
s_bIndTexScaleChanged = false;
|
s_nIndTexScaleChanged = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_nIndTexMtxChanged) {
|
if (s_nIndTexMtxChanged) {
|
||||||
|
@ -183,16 +155,17 @@ void PixelShaderManager::SetConstants()
|
||||||
|
|
||||||
// xyz - static matrix
|
// xyz - static matrix
|
||||||
//TODO w - dynamic matrix scale / 256...... somehow / 4 works better
|
//TODO w - dynamic matrix scale / 256...... somehow / 4 works better
|
||||||
|
// rev 2972 - now using / 256.... verify that this works
|
||||||
SetPSConstant4f(C_INDTEXMTX+2*i,
|
SetPSConstant4f(C_INDTEXMTX+2*i,
|
||||||
bpmem.indmtx[i].col0.ma * fscale,
|
bpmem.indmtx[i].col0.ma * fscale,
|
||||||
bpmem.indmtx[i].col1.mc * fscale,
|
bpmem.indmtx[i].col1.mc * fscale,
|
||||||
bpmem.indmtx[i].col2.me * fscale,
|
bpmem.indmtx[i].col2.me * fscale,
|
||||||
fscale * 256.0f);
|
fscale * 4.0f);
|
||||||
SetPSConstant4f(C_INDTEXMTX+2*i+1,
|
SetPSConstant4f(C_INDTEXMTX+2*i+1,
|
||||||
bpmem.indmtx[i].col0.mb * fscale,
|
bpmem.indmtx[i].col0.mb * fscale,
|
||||||
bpmem.indmtx[i].col1.md * fscale,
|
bpmem.indmtx[i].col1.md * fscale,
|
||||||
bpmem.indmtx[i].col2.mf * fscale,
|
bpmem.indmtx[i].col2.mf * fscale,
|
||||||
fscale * 256.0f);
|
fscale * 4.0f);
|
||||||
|
|
||||||
PRIM_LOG("indmtx%d: scale=%f, mat=(%f %f %f; %f %f %f)\n", i,
|
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,
|
1024.0f*fscale, bpmem.indmtx[i].col0.ma * fscale, bpmem.indmtx[i].col1.mc * fscale, bpmem.indmtx[i].col2.me * fscale,
|
||||||
|
@ -217,36 +190,23 @@ void PixelShaderManager::SetConstants()
|
||||||
|
|
||||||
void PixelShaderManager::SetPSTextureDims(int texid)
|
void PixelShaderManager::SetPSTextureDims(int texid)
|
||||||
{
|
{
|
||||||
float fdims[4];
|
// non pow 2 textures - texdims.xy are the real texture dimensions used for wrapping
|
||||||
|
// pow 2 textures - texdims.xy are reciprocals of the real texture dimensions
|
||||||
|
// both - texdims.zw are the scaled dimensions
|
||||||
|
float fdims[4];
|
||||||
if (s_texturemask & (1<<texid)) {
|
if (s_texturemask & (1<<texid)) {
|
||||||
if (maptocoord[texid] >= 0) {
|
TCoordInfo& tc = bpmem.texcoords[texid];
|
||||||
TCoordInfo& tc = bpmem.texcoords[maptocoord[texid]];
|
fdims[0] = (float)(lastTexDims[texid]&0xffff);
|
||||||
fdims[0] = (float)(lastTexDims[texid]&0xffff);
|
fdims[1] = (float)((lastTexDims[texid]>>16)&0xfff);
|
||||||
fdims[1] = (float)((lastTexDims[texid]>>16)&0xfff);
|
fdims[2] = (float)(tc.s.scale_minus_1+1);
|
||||||
fdims[2] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[texid]&0xffff);
|
fdims[3] = (float)(tc.t.scale_minus_1+1);
|
||||||
fdims[3] = (float)(tc.t.scale_minus_1+1)/(float)((lastTexDims[texid]>>16)&0xfff);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fdims[0] = (float)(lastTexDims[texid]&0xffff);
|
|
||||||
fdims[1] = (float)((lastTexDims[texid]>>16)&0xfff);
|
|
||||||
fdims[2] = 1.0f;
|
|
||||||
fdims[3] = 1.0f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (maptocoord[texid] >= 0) {
|
TCoordInfo& tc = bpmem.texcoords[texid];
|
||||||
TCoordInfo& tc = bpmem.texcoords[maptocoord[texid]];
|
fdims[0] = 1.0f/(float)(lastTexDims[texid]&0xffff);
|
||||||
fdims[0] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[texid]&0xffff);
|
fdims[1] = 1.0f/(float)((lastTexDims[texid]>>16)&0xfff);
|
||||||
fdims[1] = (float)(tc.t.scale_minus_1+1)/(float)((lastTexDims[texid]>>16)&0xfff);
|
fdims[2] = (float)(tc.s.scale_minus_1+1);
|
||||||
fdims[2] = 1.0f/(float)(tc.s.scale_minus_1+1);
|
fdims[3] = (float)(tc.t.scale_minus_1+1);
|
||||||
fdims[3] = 1.0f/(float)(tc.t.scale_minus_1+1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fdims[0] = 1.0f;
|
|
||||||
fdims[1] = 1.0f;
|
|
||||||
fdims[2] = 1.0f/(float)(lastTexDims[texid]&0xffff);
|
|
||||||
fdims[3] = 1.0f/(float)((lastTexDims[texid]>>16)&0xfff);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIM_LOG("texdims%d: %f %f %f %f\n", texid, fdims[0], fdims[1], fdims[2], fdims[3]);
|
PRIM_LOG("texdims%d: %f %f %f %f\n", texid, fdims[0], fdims[1], fdims[2], fdims[3]);
|
||||||
|
@ -319,9 +279,9 @@ void PixelShaderManager::SetViewport(float* viewport)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetIndTexScaleChanged()
|
void PixelShaderManager::SetIndTexScaleChanged(u8 stagemask)
|
||||||
{
|
{
|
||||||
s_bIndTexScaleChanged = true;
|
s_nIndTexScaleChanged |= stagemask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetIndMatrixChanged(int matrixidx)
|
void PixelShaderManager::SetIndMatrixChanged(int matrixidx)
|
||||||
|
@ -347,13 +307,9 @@ void PixelShaderManager::SetTexturesUsed(u32 nonpow2tex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetTexDimsChanged(int texmapid)
|
void PixelShaderManager::SetTexCoordChanged(u8 texmapid)
|
||||||
{
|
{
|
||||||
// this check was previously implicit, but should it be here?
|
s_nTexDimsChanged |= 1 << texmapid;
|
||||||
if (s_nTexDimsChanged)
|
|
||||||
s_nTexDimsChanged |= 1 << texmapid;
|
|
||||||
|
|
||||||
SetIndTexScaleChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelShaderManager::SetFogColorChanged()
|
void PixelShaderManager::SetFogColorChanged()
|
||||||
|
|
|
@ -44,9 +44,9 @@ public:
|
||||||
static void SetIndMatrixChanged(int matrixidx);
|
static void SetIndMatrixChanged(int matrixidx);
|
||||||
static void SetTevKSelChanged(int id);
|
static void SetTevKSelChanged(int id);
|
||||||
static void SetZTextureTypeChanged();
|
static void SetZTextureTypeChanged();
|
||||||
static void SetIndTexScaleChanged();
|
static void SetIndTexScaleChanged(u8 stagemask);
|
||||||
static void SetTexturesUsed(u32 nonpow2tex);
|
static void SetTexturesUsed(u32 nonpow2tex);
|
||||||
static void SetTexDimsChanged(int texmapid);
|
static void SetTexCoordChanged(u8 texmapid);
|
||||||
static void SetFogColorChanged();
|
static void SetFogColorChanged();
|
||||||
static void SetFogParamChanged();
|
static void SetFogParamChanged();
|
||||||
static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);
|
static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);
|
||||||
|
|
Loading…
Reference in New Issue