From 66ca49d3b84c0b2fec60b244b081dfac1008c8d6 Mon Sep 17 00:00:00 2001 From: donkopunchstania Date: Wed, 15 Apr 2009 03:55:38 +0000 Subject: [PATCH] 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 --- Source/Core/VideoCommon/Src/BPStructs.cpp | 4 +- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 199 ++++++------------ .../VideoCommon/Src/PixelShaderManager.cpp | 128 ++++------- .../Core/VideoCommon/Src/PixelShaderManager.h | 4 +- 4 files changed, 114 insertions(+), 221 deletions(-) diff --git a/Source/Core/VideoCommon/Src/BPStructs.cpp b/Source/Core/VideoCommon/Src/BPStructs.cpp index e1a0eef25b..ca3e59194e 100644 --- a/Source/Core/VideoCommon/Src/BPStructs.cpp +++ b/Source/Core/VideoCommon/Src/BPStructs.cpp @@ -99,8 +99,9 @@ void BPWritten(const Bypass& bp) PixelShaderManager::SetIndMatrixChanged((bp.address - BPMEM_IND_MTXA) / 3); break; case BPMEM_RAS1_SS0: // Index Texture Coordinate Scale 0 + PixelShaderManager::SetIndTexScaleChanged(0x03); case BPMEM_RAS1_SS1: // Index Texture Coordinate Scale 1 - PixelShaderManager::SetIndTexScaleChanged(); + PixelShaderManager::SetIndTexScaleChanged(0x0c); break; case BPMEM_SCISSORTL: // Scissor Rectable Top, Left case BPMEM_SCISSORBR: // Scissor Rectable Bottom, Right @@ -408,6 +409,7 @@ void BPWritten(const Bypass& bp) case BPMEM_SU_TSIZE+12: case BPMEM_SU_SSIZE+14: case BPMEM_SU_TSIZE+14: + PixelShaderManager::SetTexCoordChanged((bp.address - BPMEM_SU_SSIZE) >> 1); break; // ------------------------ // BPMEM_TX_SETMODE0 - (Texture lookup and filtering mode) LOD/BIAS Clamp, MaxAnsio, LODBIAS, DiagLoad, Min Filter, Mag Filter, Wrap T, S diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 1c33e9792a..a77eb0ad62 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -131,7 +131,7 @@ void GetPixelShaderId(PIXELSHADERUID &uid, u32 s_texturemask, u32 zbufrender, u3 // tevtemp is set according to swapmodetables and 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 bool WriteAlphaTest(char *&p, bool HLSL); 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 *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 *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 @@ -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" "float4 alphabump=0;\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 for(u32 i = 0; i < bpmem.genMode.numindstages; ++i) { if (nIndirectStagesUsed & (1<> 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]); + 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); } - SetPSConstant4fv(C_INDTEXSCALE, f); - - if (bpmem.genMode.numindstages > 2) + 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_bIndTexScaleChanged = false; + s_nIndTexScaleChanged = 0; } if (s_nIndTexMtxChanged) { @@ -183,16 +155,17 @@ void PixelShaderManager::SetConstants() // 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 * 256.0f); + 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 * 256.0f); + 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, @@ -217,36 +190,23 @@ void PixelShaderManager::SetConstants() 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<= 0) { - TCoordInfo& tc = bpmem.texcoords[maptocoord[texid]]; - fdims[0] = (float)(lastTexDims[texid]&0xffff); - fdims[1] = (float)((lastTexDims[texid]>>16)&0xfff); - fdims[2] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[texid]&0xffff); - 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; - } + TCoordInfo& tc = bpmem.texcoords[texid]; + fdims[0] = (float)(lastTexDims[texid]&0xffff); + fdims[1] = (float)((lastTexDims[texid]>>16)&0xfff); + fdims[2] = (float)(tc.s.scale_minus_1+1); + fdims[3] = (float)(tc.t.scale_minus_1+1); } else { - if (maptocoord[texid] >= 0) { - TCoordInfo& tc = bpmem.texcoords[maptocoord[texid]]; - fdims[0] = (float)(tc.s.scale_minus_1+1)/(float)(lastTexDims[texid]&0xffff); - fdims[1] = (float)(tc.t.scale_minus_1+1)/(float)((lastTexDims[texid]>>16)&0xfff); - fdims[2] = 1.0f/(float)(tc.s.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); - } + 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]); @@ -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) @@ -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? - if (s_nTexDimsChanged) - s_nTexDimsChanged |= 1 << texmapid; - - SetIndTexScaleChanged(); + s_nTexDimsChanged |= 1 << texmapid; } void PixelShaderManager::SetFogColorChanged() diff --git a/Source/Core/VideoCommon/Src/PixelShaderManager.h b/Source/Core/VideoCommon/Src/PixelShaderManager.h index 94100a78bd..c9452afe6b 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderManager.h +++ b/Source/Core/VideoCommon/Src/PixelShaderManager.h @@ -44,9 +44,9 @@ public: static void SetIndMatrixChanged(int matrixidx); static void SetTevKSelChanged(int id); static void SetZTextureTypeChanged(); - static void SetIndTexScaleChanged(); + static void SetIndTexScaleChanged(u8 stagemask); static void SetTexturesUsed(u32 nonpow2tex); - static void SetTexDimsChanged(int texmapid); + static void SetTexCoordChanged(u8 texmapid); static void SetFogColorChanged(); static void SetFogParamChanged(); static void SetColorMatrix(const float* pmatrix, const float* pfConstAdd);