PixelShaderGen: Treat UV coordinates like S17.7 integers (they're still stored as float, though).

This commit is contained in:
Tony Wasserka 2013-11-02 11:42:30 +01:00
parent 3e6efdb53e
commit 3a6389992e
2 changed files with 17 additions and 12 deletions

View File

@ -528,9 +528,9 @@ void Tev::Indirect(unsigned int stageNum, s32 s, s32 t)
return; return;
} }
s64 indtevtrans[2] = { 0,0 }; s32 indtevtrans[2] = { 0,0 };
// matrix multiply // matrix multiply - results might overflow, but we don't care since we only use the lower 24 bits of the result.
int indmtxid = indirect.mid & 3; int indmtxid = indirect.mid & 3;
if (indmtxid) if (indmtxid)
{ {

View File

@ -408,6 +408,10 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
} }
} }
// UV coordinates are stored in 17.7 format.. TODO: Use an integer for this!
for (int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
out.Write("uv%d.xy = uv%d.xy * 128.0;\n", i, i);
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{ {
out.Write("\tfloat3 _norm0 = normalize(Normal.xyz);\n\n"); out.Write("\tfloat3 _norm0 = normalize(Normal.xyz);\n\n");
@ -471,7 +475,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
if (texcoord < numTexgen) if (texcoord < numTexgen)
{ {
out.SetConstantsUsed(C_INDTEXSCALE+i/2,C_INDTEXSCALE+i/2); out.SetConstantsUsed(C_INDTEXSCALE+i/2,C_INDTEXSCALE+i/2);
out.Write("\ttempcoord = uv%d.xy * " I_INDTEXSCALE"[%d].%s;\n", texcoord, i/2, (i&1)?"zw":"xy"); out.Write("\ttempcoord = uv%d.xy / 128.0 * " I_INDTEXSCALE"[%d].%s;\n", texcoord, i/2, (i&1)?"zw":"xy");
} }
else else
out.Write("\ttempcoord = float2(0.0, 0.0);\n"); out.Write("\ttempcoord = float2(0.0, 0.0);\n");
@ -709,6 +713,7 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
out.Write("int2 indtevtrans%d = int2(idot(" I_INDTEXMTX"[%d].xyz, iindtevcrd%d), idot(" I_INDTEXMTX"[%d].xyz, iindtevcrd%d)) >> 3;\n", n, mtxidx, n, mtxidx+1, n); out.Write("int2 indtevtrans%d = int2(idot(" I_INDTEXMTX"[%d].xyz, iindtevcrd%d), idot(" I_INDTEXMTX"[%d].xyz, iindtevcrd%d)) >> 3;\n", n, mtxidx, n, mtxidx+1, n);
// TODO: should use a shader uid branch for this..
out.Write("if (" I_INDTEXMTX"[%d].w >= 0) indtevtrans%d = indtevtrans%d >> " I_INDTEXMTX"[%d].w;\n", mtxidx, n, n, mtxidx); out.Write("if (" I_INDTEXMTX"[%d].w >= 0) indtevtrans%d = indtevtrans%d >> " I_INDTEXMTX"[%d].w;\n", mtxidx, n, n, mtxidx);
out.Write("else indtevtrans%d = indtevtrans%d << (-" I_INDTEXMTX"[%d].w);\n", n, n, mtxidx); out.Write("else indtevtrans%d = indtevtrans%d << (-" I_INDTEXMTX"[%d].w);\n", n, n, mtxidx);
} }
@ -717,7 +722,7 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
_assert_(bpmem.tevind[n].mid >= 5); _assert_(bpmem.tevind[n].mid >= 5);
int mtxidx = 2*(bpmem.tevind[n].mid-5); int mtxidx = 2*(bpmem.tevind[n].mid-5);
out.SetConstantsUsed(C_INDTEXMTX+mtxidx, C_INDTEXMTX+mtxidx); out.SetConstantsUsed(C_INDTEXMTX+mtxidx, C_INDTEXMTX+mtxidx);
out.Write("int2 indtevtrans%d = int2(int2(round(uv%d.xy*255.0)) * iindtevcrd%d.xx) >> 8;\n", n, texcoord, n); out.Write("int2 indtevtrans%d = int2(int2(round(uv%d.xy)) * iindtevcrd%d.xx) >> 8;\n", n, texcoord, n);
out.Write("if (" I_INDTEXMTX"[%d].w >= 0) indtevtrans%d = indtevtrans%d >> " I_INDTEXMTX"[%d].w;\n", mtxidx, n, n, mtxidx); out.Write("if (" I_INDTEXMTX"[%d].w >= 0) indtevtrans%d = indtevtrans%d >> " I_INDTEXMTX"[%d].w;\n", mtxidx, n, n, mtxidx);
out.Write("else indtevtrans%d = indtevtrans%d << (-" I_INDTEXMTX"[%d].w);\n", n, n, mtxidx); out.Write("else indtevtrans%d = indtevtrans%d << (-" I_INDTEXMTX"[%d].w);\n", n, n, mtxidx);
@ -727,7 +732,7 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
_assert_(bpmem.tevind[n].mid >= 9); _assert_(bpmem.tevind[n].mid >= 9);
int mtxidx = 2*(bpmem.tevind[n].mid-9); int mtxidx = 2*(bpmem.tevind[n].mid-9);
out.SetConstantsUsed(C_INDTEXMTX+mtxidx, C_INDTEXMTX+mtxidx); out.SetConstantsUsed(C_INDTEXMTX+mtxidx, C_INDTEXMTX+mtxidx);
out.Write("int2 indtevtrans%d = int2(int2(round(uv%d.xy*255.0)) * iindtevcrd%d.yy) >> 8;\n", n, texcoord, n); out.Write("int2 indtevtrans%d = int2(int2(round(uv%d.xy)) * iindtevcrd%d.yy) >> 8;\n", n, texcoord, n);
out.Write("if (" I_INDTEXMTX"[%d].w >= 0) indtevtrans%d = indtevtrans%d >> " I_INDTEXMTX"[%d].w;\n", mtxidx, n, n, mtxidx); out.Write("if (" I_INDTEXMTX"[%d].w >= 0) indtevtrans%d = indtevtrans%d >> " I_INDTEXMTX"[%d].w;\n", mtxidx, n, n, mtxidx);
out.Write("else indtevtrans%d = indtevtrans%d << (-" I_INDTEXMTX"[%d].w);\n", n, n, mtxidx); out.Write("else indtevtrans%d = indtevtrans%d << (-" I_INDTEXMTX"[%d].w);\n", n, n, mtxidx);
@ -745,23 +750,23 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
// --------- // ---------
// Wrapping // Wrapping
// --------- // ---------
const char *tevIndWrapStart[] = {"0", "(256<<7)", "(128<<7)", "(64<<7)", "(32<<7)", "(16<<7)", "1" }; const char *tevIndWrapStart[] = {"0", "(256<<7)", "(128<<7)", "(64<<7)", "(32<<7)", "(16<<7)", "1" }; // TODO: Should the last one be 1 or (1<<7)?
// wrap S // wrap S
if (bpmem.tevind[n].sw == ITW_OFF) if (bpmem.tevind[n].sw == ITW_OFF)
out.Write("wrappedcoord.x = int(round(uv%d.x*256.0));\n", texcoord); out.Write("wrappedcoord.x = int(round(uv%d.x));\n", texcoord);
else if (bpmem.tevind[n].sw == ITW_0) else if (bpmem.tevind[n].sw == ITW_0)
out.Write("wrappedcoord.x = 0;\n"); out.Write("wrappedcoord.x = 0;\n");
else else
out.Write("wrappedcoord.x = int(round(uv%d.x*256.0)) %% %s;\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw]); out.Write("wrappedcoord.x = int(round(uv%d.x)) %% %s;\n", texcoord, tevIndWrapStart[bpmem.tevind[n].sw]);
// wrap T // wrap T
if (bpmem.tevind[n].tw == ITW_OFF) if (bpmem.tevind[n].tw == ITW_OFF)
out.Write("wrappedcoord.y = int(round(uv%d.y*256.0));\n", texcoord); out.Write("wrappedcoord.y = int(round(uv%d.y));\n", texcoord);
else if (bpmem.tevind[n].tw == ITW_0) else if (bpmem.tevind[n].tw == ITW_0)
out.Write("wrappedcoord.y = 0;\n"); out.Write("wrappedcoord.y = 0;\n");
else else
out.Write("wrappedcoord.y = int(round(uv%d.y*256.0)) %% %s;\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw]); out.Write("wrappedcoord.y = int(round(uv%d.y)) %% %s;\n", texcoord, tevIndWrapStart[bpmem.tevind[n].tw]);
if (bpmem.tevind[n].fb_addprev) // add previous tevcoord if (bpmem.tevind[n].fb_addprev) // add previous tevcoord
out.Write("tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n); out.Write("tevcoord.xy += wrappedcoord + indtevtrans%d;\n", n);
@ -805,7 +810,7 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
{ {
// calc tevcord // calc tevcord
if (bHasTexCoord) if (bHasTexCoord)
out.Write("tevcoord.xy = int2(round(uv%d.xy*256.0));\n", texcoord); out.Write("tevcoord.xy = int2(round(uv%d.xy));\n", texcoord);
else else
out.Write("tevcoord.xy = int2(0, 0);\n"); out.Write("tevcoord.xy = int2(0, 0);\n");
} }
@ -823,7 +828,7 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
uid_data.SetTevindrefTexmap(i, texmap); uid_data.SetTevindrefTexmap(i, texmap);
out.Write("itextemp = "); out.Write("itextemp = ");
SampleTexture<T>(out, "(float2(tevcoord.xy)/256.0)", texswap, texmap, ApiType); SampleTexture<T>(out, "(float2(tevcoord.xy)/128.0)", texswap, texmap, ApiType);
} }
else else
{ {