From a40741798c8c97ce353565ab05f0277e0d13e5d2 Mon Sep 17 00:00:00 2001 From: neobrain Date: Sun, 21 Jul 2013 17:43:08 -0700 Subject: [PATCH 01/14] Add accessors for several lighting related values. --- GPU/GPUState.h | 77 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index a8d7b52af4..f2bfde48b1 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -78,41 +78,41 @@ struct GPUgstate patchfacing, pad04_a, - worldmtxnum, //0x3A - worldmtxdata, //0x3B - viewmtxnum, //0x3C - viewmtxdata, - projmtxnum, - projmtxdata, - texmtxnum, - texmtxdata, + worldmtxnum, // 0x3A + worldmtxdata, // 0x3B + viewmtxnum, // 0x3C + viewmtxdata, // 0x3D + projmtxnum, // 0x3E + projmtxdata, // 0x3F + texmtxnum, // 0x40 + texmtxdata, // 0x41 - viewportx1, - viewporty1, - viewportz1, - viewportx2, - viewporty2, - viewportz2, - texscaleu, - texscalev, - texoffsetu, - texoffsetv, - offsetx, - offsety, + viewportx1, // 0x42 + viewporty1, // 0x43 + viewportz1, // 0x44 + viewportx2, // 0x45 + viewporty2, // 0x46 + viewportz2, // 0x47 + texscaleu, // 0x48 + texscalev, // 0x49 + texoffsetu, // 0x4A + texoffsetv, // 0x4B + offsetx, // 0x4C + offsety, // 0x4D pad111[2], - shademodel, - reversenormals, + shademodel, // 0x50 + reversenormals, // 0x51 pad222, - materialupdate, - materialemissive, - materialambient, - materialdiffuse, - materialspecular, - materialalpha, + materialupdate, // 0x53 + materialemissive, // 0x54 + materialambient, // 0x55 + materialdiffuse, // 0x56 + materialspecular, // 0x57 + materialalpha, // 0x58 pad333[2], - materialspecularcoef, - ambientcolor, - ambientalpha, + materialspecularcoef, // 0x5B + ambientcolor, // 0x5C + ambientalpha, // 0x5D lmode, ltype[4], lpos[12], @@ -213,8 +213,23 @@ struct GPUgstate bool isAlphaTestEnabled() const { return alphaTestEnable & 1; } bool isColorTestEnabled() const { return colorTestEnable & 1; } bool isLightingEnabled() const { return lightingEnable & 1; } + bool isUsingSecondaryColor() const { return lmode & 1; } bool isTextureMapEnabled() const { return textureMapEnable & 1; } + unsigned int getAmbientR() const { return ambientcolor&0xFF; } + unsigned int getAmbientG() const { return (ambientcolor>>8)&0xFF; } + unsigned int getAmbientB() const { return (ambientcolor>>16)&0xFF; } + unsigned int getAmbientA() const { return ambientalpha&0xFF; } + + unsigned int getMaterialAmbientR() const { return materialambient&0xFF; } + unsigned int getMaterialAmbientG() const { return (materialambient>>8)&0xFF; } + unsigned int getMaterialAmbientB() const { return (materialambient>>16)&0xFF; } + unsigned int getMaterialAmbientA() const { return materialalpha&0xFF; } + + unsigned int getMaterialEmissiveR() const { return materialemissive&0xFF; } + unsigned int getMaterialEmissiveG() const { return (materialemissive>>8)&0xFF; } + unsigned int getMaterialEmissiveB() const { return (materialemissive>>16)&0xFF; } + // UV gen int getUVGenMode() const { return texmapmode & 3;} // 2 bits int getUVProjMode() const { return (texmapmode >> 8) & 3;} // 2 bits From abca8f6c875c16f10794b90b68c4a862ed2023f6 Mon Sep 17 00:00:00 2001 From: neobrain Date: Sun, 21 Jul 2013 17:56:58 -0700 Subject: [PATCH 02/14] Add some more GE state accessors for light/etc. --- GPU/GPUState.h | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index f2bfde48b1..69c9225804 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -113,14 +113,14 @@ struct GPUgstate materialspecularcoef, // 0x5B ambientcolor, // 0x5C ambientalpha, // 0x5D - lmode, - ltype[4], - lpos[12], - ldir[12], - latt[12], - lconv[4], - lcutoff[4], - lcolor[12], + lmode, // 0x5E + ltype[4], // 0x5F-0x62 + lpos[12], // 0x63-0x6E + ldir[12], // 0x6F-0x7A + latt[12], // 0x7B-0x86 + lconv[4], // 0x87-0x8A + lcutoff[4], // 0x8B-0x8E + lcolor[12], // 0x8E-0x99 cullmode, fbptr, fbwidth, @@ -212,10 +212,17 @@ struct GPUgstate bool isDitherEnabled() const { return ditherEnable & 1; } bool isAlphaTestEnabled() const { return alphaTestEnable & 1; } bool isColorTestEnabled() const { return colorTestEnable & 1; } - bool isLightingEnabled() const { return lightingEnable & 1; } - bool isUsingSecondaryColor() const { return lmode & 1; } bool isTextureMapEnabled() const { return textureMapEnable & 1; } + bool isLightingEnabled() const { return lightingEnable & 1; } + bool isLightChanEnabled(int chan) const { return lightEnable[chan] & 1;} + bool isUsingPoweredDiffuseLight(int chan) const { return (ltype[chan] & 0x3) == 0x2; } + bool isUsingSpecularLight(int chan) const { return (ltype[chan] & 0x3) == 0x1 || (ltype[chan] & 0x3) == 0x2; } + bool isUsingSecondaryColor() const { return lmode & 1; } + bool isDirectionalLight(int chan) const { return ((ltype[chan] & 0x30)>>8) == 0; } + bool isPointLight(int chan) const { return ((ltype[chan] & 0x30)>>8) == 1; } + bool isSpotLight(int chan) const { return ((ltype[chan] & 0x30)>>8) == 2; } + unsigned int getAmbientR() const { return ambientcolor&0xFF; } unsigned int getAmbientG() const { return (ambientcolor>>8)&0xFF; } unsigned int getAmbientB() const { return (ambientcolor>>16)&0xFF; } @@ -226,10 +233,18 @@ struct GPUgstate unsigned int getMaterialAmbientB() const { return (materialambient>>16)&0xFF; } unsigned int getMaterialAmbientA() const { return materialalpha&0xFF; } + unsigned int getMaterialDiffuseR() const { return materialdiffuse&0xFF; } + unsigned int getMaterialDiffuseG() const { return (materialdiffuse>>8)&0xFF; } + unsigned int getMaterialDiffuseB() const { return (materialdiffuse>>16)&0xFF; } + unsigned int getMaterialEmissiveR() const { return materialemissive&0xFF; } unsigned int getMaterialEmissiveG() const { return (materialemissive>>8)&0xFF; } unsigned int getMaterialEmissiveB() const { return (materialemissive>>16)&0xFF; } + unsigned int getDiffuseColorR(int chan) const { return lcolor[1+chan*3]&0xFF; } + unsigned int getDiffuseColorG(int chan) const { return (lcolor[1+chan*3]>>8)&0xFF; } + unsigned int getDiffuseColorB(int chan) const { return (lcolor[1+chan*3]>>16)&0xFF; } + // UV gen int getUVGenMode() const { return texmapmode & 3;} // 2 bits int getUVProjMode() const { return (texmapmode >> 8) & 3;} // 2 bits From 4c74cafa51851810bd410ca94721cca4a0f8fd36 Mon Sep 17 00:00:00 2001 From: neobrain Date: Sun, 21 Jul 2013 18:29:27 -0700 Subject: [PATCH 03/14] Add some more lighting related accessors. --- GPU/GPUState.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 69c9225804..167b2d955f 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -241,10 +241,22 @@ struct GPUgstate unsigned int getMaterialEmissiveG() const { return (materialemissive>>8)&0xFF; } unsigned int getMaterialEmissiveB() const { return (materialemissive>>16)&0xFF; } + unsigned int getMaterialSpecularR() const { return materialspecular&0xFF; } + unsigned int getMaterialSpecularG() const { return (materialspecular>>8)&0xFF; } + unsigned int getMaterialSpecularB() const { return (materialspecular>>16)&0xFF; } + + unsigned int getLightAmbientColorR(int chan) const { return lcolor[chan*3]&0xFF; } + unsigned int getLightAmbientColorG(int chan) const { return (lcolor[chan*3]>>8)&0xFF; } + unsigned int getLightAmbientColorB(int chan) const { return (lcolor[chan*3]>>16)&0xFF; } + unsigned int getDiffuseColorR(int chan) const { return lcolor[1+chan*3]&0xFF; } unsigned int getDiffuseColorG(int chan) const { return (lcolor[1+chan*3]>>8)&0xFF; } unsigned int getDiffuseColorB(int chan) const { return (lcolor[1+chan*3]>>16)&0xFF; } + unsigned int getSpecularColorR(int chan) const { return lcolor[2+chan*3]&0xFF; } + unsigned int getSpecularColorG(int chan) const { return (lcolor[2+chan*3]>>8)&0xFF; } + unsigned int getSpecularColorB(int chan) const { return (lcolor[2+chan*3]>>16)&0xFF; } + // UV gen int getUVGenMode() const { return texmapmode & 3;} // 2 bits int getUVProjMode() const { return (texmapmode >> 8) & 3;} // 2 bits From 01824e44ae7b89f69dcad2197a95aefe6b1ed4bc Mon Sep 17 00:00:00 2001 From: neobrain Date: Sun, 21 Jul 2013 18:35:31 -0700 Subject: [PATCH 04/14] Add some texture-related GE accessors. --- GPU/GPUState.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 167b2d955f..8e9cf16087 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -212,8 +212,17 @@ struct GPUgstate bool isDitherEnabled() const { return ditherEnable & 1; } bool isAlphaTestEnabled() const { return alphaTestEnable & 1; } bool isColorTestEnabled() const { return colorTestEnable & 1; } - bool isTextureMapEnabled() const { return textureMapEnable & 1; } + // Texturing + bool isTextureMapEnabled() const { return textureMapEnable & 1; } + int getTextureFunction() const { return texfunc & 0x7; } + bool isColorDoublingEnabled() const { return (texfunc & 0x10000) != 0; } + + int getTextureEnvColR() const { return texenvcolor&0xFF; } + int getTextureEnvColG() const { return (texenvcolor>>8)&0xFF; } + int getTextureEnvColB() const { return (texenvcolor>>16)&0xFF; } + + // Lighting bool isLightingEnabled() const { return lightingEnable & 1; } bool isLightChanEnabled(int chan) const { return lightEnable[chan] & 1;} bool isUsingPoweredDiffuseLight(int chan) const { return (ltype[chan] & 0x3) == 0x2; } From a70220a1d5bdf9910045181a3b01b84156c3e898 Mon Sep 17 00:00:00 2001 From: neobrain Date: Sun, 21 Jul 2013 18:40:19 -0700 Subject: [PATCH 05/14] Add clut GE state accessors. --- GPU/GPUState.h | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 8e9cf16087..c8d9ecc982 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -120,27 +120,27 @@ struct GPUgstate latt[12], // 0x7B-0x86 lconv[4], // 0x87-0x8A lcutoff[4], // 0x8B-0x8E - lcolor[12], // 0x8E-0x99 - cullmode, - fbptr, - fbwidth, - zbptr, - zbwidth, - texaddr[8], - texbufwidth[8], - clutaddr, - clutaddrupper, - transfersrc, - transfersrcw, - transferdst, - transferdstw, + lcolor[12], // 0x8F-0x9A + cullmode, // 0x9B + fbptr, // 0x9C + fbwidth, // 0x9D + zbptr, // 0x9E + zbwidth, // 0x9F + texaddr[8], // 0xA0-0xA7 + texbufwidth[8], // 0xA8-0xAF + clutaddr, // 0xB0 + clutaddrupper, // 0xB1 + transfersrc, // 0xB2 + transfersrcw, // 0xB3 + transferdst, // 0xB4 + transferdstw, // 0xB5 padxxx[2], - texsize[8], - texmapmode, - texshade, - texmode, - texformat, - loadclut, + texsize[8], // 0xB8-BF + texmapmode, // 0xC0 + texshade, // 0xC1 + texmode, // 0xC2 + texformat, // 0xC3 + loadclut, // 0xC4 clutformat, texfilter, texwrap, @@ -222,6 +222,10 @@ struct GPUgstate int getTextureEnvColG() const { return (texenvcolor>>8)&0xFF; } int getTextureEnvColB() const { return (texenvcolor>>16)&0xFF; } + int getClutIndexShift() const { return (clutformat >> 2) & 0x1F; } + int getClutIndexMask() const { return (clutformat >> 8) & 0xFF; } + int getClutIndexStartPos() const { return ((clutformat >> 16) & 0x1F) << 4; } + // Lighting bool isLightingEnabled() const { return lightingEnable & 1; } bool isLightChanEnabled(int chan) const { return lightEnable[chan] & 1;} From cc180fa2044c52b992a829e32c8df881d8e90baa Mon Sep 17 00:00:00 2001 From: Florent Castelli Date: Sun, 21 Jul 2013 18:44:04 -0700 Subject: [PATCH 06/14] Add type safe getter for texture and clut format fields. --- GPU/GLES/TextureCache.cpp | 8 ++++---- GPU/GPUState.h | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 695dff455f..3933b92c19 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -206,9 +206,9 @@ static u32 GetClutAddr() { } static u32 GetClutIndex(u32 index) { - const u32 clutBase = (gstate.clutformat & 0x1f0000) >> 12; - const u32 clutMask = (gstate.clutformat >> 8) & 0xff; - const u8 clutShift = (gstate.clutformat >> 2) & 0x1f; + const u32 clutBase = gstate.getClutIndexStartPos(); + const u32 clutMask = gstate.getClutIndexMask(); + const u8 clutShift = gstate.getClutIndexShift(); return ((index >> clutShift) & clutMask) | clutBase; } @@ -831,7 +831,7 @@ void TextureCache::LoadClut() { } void TextureCache::UpdateCurrentClut() { - const GEPaletteFormat clutFormat = (GEPaletteFormat)(gstate.clutformat & 3); + const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); const u32 clutBase = (gstate.clutformat & 0x1f0000) >> 12; const u32 clutBaseBytes = clutBase * (clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16)); // Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier. diff --git a/GPU/GPUState.h b/GPU/GPUState.h index c8d9ecc982..30347bce7e 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -217,11 +217,13 @@ struct GPUgstate bool isTextureMapEnabled() const { return textureMapEnable & 1; } int getTextureFunction() const { return texfunc & 0x7; } bool isColorDoublingEnabled() const { return (texfunc & 0x10000) != 0; } + GETextureFormat getTextureFormat() const { return static_cast(texformat & 0xF); } int getTextureEnvColR() const { return texenvcolor&0xFF; } int getTextureEnvColG() const { return (texenvcolor>>8)&0xFF; } int getTextureEnvColB() const { return (texenvcolor>>16)&0xFF; } + GEPaletteFormat getClutPaletteFormat() { return static_cast(clutformat & 3); } int getClutIndexShift() const { return (clutformat >> 2) & 0x1F; } int getClutIndexMask() const { return (clutformat >> 8) & 0xFF; } int getClutIndexStartPos() const { return ((clutformat >> 16) & 0x1F) << 4; } From e6e7dd66d09dd56460032414179b160d6815418f Mon Sep 17 00:00:00 2001 From: neobrain Date: Sun, 21 Jul 2013 18:48:14 -0700 Subject: [PATCH 07/14] Implement some stencil test GE state accessors. --- GPU/GPUState.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 30347bce7e..415d1f7255 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -207,12 +207,19 @@ struct GPUgstate bool isDepthWriteEnabled() const { return !(zmsk & 1); } int getDepthTestFunc() const { return ztestfunc & 0x7; } bool isFogEnabled() const { return fogEnable & 1; } - bool isStencilTestEnabled() const { return stencilTestEnable & 1; } bool isAlphaBlendEnabled() const { return alphaBlendEnable & 1; } bool isDitherEnabled() const { return ditherEnable & 1; } bool isAlphaTestEnabled() const { return alphaTestEnable & 1; } bool isColorTestEnabled() const { return colorTestEnable & 1; } + bool isStencilTestEnabled() const { return stencilTestEnable & 1; } + int getStencilTestFunction() const { return stenciltest & 0x7; } + int getStencilTestRef() const { return (stenciltest>>8) & 0xFF; } + int getStencilTestMask() const { return (stenciltest>>16) & 0xFF; } + int getStencilOpSFail() const { return stencilop & 0x7; } + int getStencilOpZFail() const { return (stencilop>>8) & 0x7; } + int getStencilOpZPass() const { return (stencilop>>16) & 0x7; } + // Texturing bool isTextureMapEnabled() const { return textureMapEnable & 1; } int getTextureFunction() const { return texfunc & 0x7; } From 3ca0c5397f4bbae2c7b664e4e4806e1105102364 Mon Sep 17 00:00:00 2001 From: neobrain Date: Sun, 21 Jul 2013 18:59:18 -0700 Subject: [PATCH 08/14] Add logic op/color masking GE state accessors. --- GPU/GPUState.h | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 415d1f7255..69532d432d 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -141,21 +141,21 @@ struct GPUgstate texmode, // 0xC2 texformat, // 0xC3 loadclut, // 0xC4 - clutformat, - texfilter, - texwrap, - texlevel, - texfunc, - texenvcolor, - texflush, - texsync, - fog1, - fog2, - fogcolor, - texlodslope, - padxxxxxx, - framebufpixformat, - clearmode, + clutformat, // 0xC5 + texfilter, // 0xC6 + texwrap, // 0xC7 + texlevel, // 0xC8 + texfunc, // 0xC9 + texenvcolor, // 0xCA + texflush, // 0xCB + texsync, // 0xCC + fog1, // 0xCD + fog2, // 0xCE + fogcolor, // 0xCF + texlodslope, // 0xD0 + padxxxxxx, // 0xD1 + framebufpixformat, // 0xD2 + clearmode, // 0xD3 scissor1, scissor2, minz, @@ -174,7 +174,7 @@ struct GPUgstate dith2, dith3, dith4, - lop, + lop, // 0xE6 zmsk, pmskc, pmska, @@ -212,6 +212,10 @@ struct GPUgstate bool isAlphaTestEnabled() const { return alphaTestEnable & 1; } bool isColorTestEnabled() const { return colorTestEnable & 1; } + u32 getColorMask() const { return (pmskc & 0xFFFFFF) | ((pmska & 0xFF) << 24); } + bool isLogicOpEnabled() const { return logicOpEnable & 1; } + GELogicOp getLogicOp() const { return static_cast(lop & 0xF); } + bool isStencilTestEnabled() const { return stencilTestEnable & 1; } int getStencilTestFunction() const { return stenciltest & 0x7; } int getStencilTestRef() const { return (stenciltest>>8) & 0xFF; } From c0da6b97c56d2852373acd17cdf28c10e27de630 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 21 Jul 2013 19:06:44 -0700 Subject: [PATCH 09/14] Add and use some color/alpha test accessors. --- GPU/GLES/FragmentShaderGenerator.cpp | 23 ++++++++++++----------- GPU/GLES/ShaderManager.cpp | 2 +- GPU/GPUState.h | 12 ++++++++++-- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 401b7f72ff..45feea1413 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -40,9 +40,10 @@ // GL_NV_shader_framebuffer_fetch looks interesting.... static bool IsAlphaTestTriviallyTrue() { - int alphaTestFunc = gstate.alphatest & 7; - int alphaTestRef = (gstate.alphatest >> 8) & 0xFF; - + GEComparison alphaTestFunc = gstate.getAlphaTestFunction(); + int alphaTestRef = gstate.getAlphaTestRef(); + int alphaTestMask = gstate.getAlphaTestMask(); + switch (alphaTestFunc) { case GE_COMP_ALWAYS: return true; @@ -52,7 +53,7 @@ static bool IsAlphaTestTriviallyTrue() { // This breaks the trees in MotoGP, for example. // case GE_COMP_GREATER: - //if (alphaTestRef == 0 && (gstate.alphaBlendEnable & 1) && gstate.getBlendFuncA() == GE_SRCBLEND_SRCALPHA && gstate.getBlendFuncB() == GE_SRCBLEND_INVSRCALPHA) + //if (alphaTestRef == 0 && (gstate.isAlphaBlendEnabled() & 1) && gstate.getBlendFuncA() == GE_SRCBLEND_SRCALPHA && gstate.getBlendFuncB() == GE_SRCBLEND_INVSRCALPHA) // return true; case GE_COMP_LEQUAL: @@ -64,7 +65,7 @@ static bool IsAlphaTestTriviallyTrue() { } static bool IsColorTestTriviallyTrue() { - int colorTestFunc = gstate.colortest & 3; + GEComparison colorTestFunc = gstate.getColorTestFunction(); switch (colorTestFunc) { case GE_COMP_ALWAYS: return true; @@ -123,7 +124,7 @@ void ComputeFragmentShaderID(FragmentShaderID *id) { if (gstate_c.textureFullAlpha && (gstate.texfunc & 0x7) != GE_TEXFUNC_REPLACE) doTextureAlpha = false; - // id->d[0] |= (gstate.clearmode & 1); + // id->d[0] |= (gstate.isModeClear() & 1); if (gstate.isTextureMapEnabled()) { id->d[0] |= 1 << 1; id->d[0] |= (gstate.texfunc & 0x7) << 2; @@ -132,10 +133,10 @@ void ComputeFragmentShaderID(FragmentShaderID *id) { id->d[0] |= (lmode & 1) << 7; id->d[0] |= gstate.isAlphaTestEnabled() << 8; if (enableAlphaTest) - id->d[0] |= (gstate.alphatest & 0x7) << 9; // alpha test func + id->d[0] |= gstate.getAlphaTestFunction() << 9; id->d[0] |= gstate.isColorTestEnabled() << 12; if (enableColorTest) - id->d[0] |= (gstate.colortest & 0x3) << 13; // color test func + id->d[0] |= gstate.getColorTestFunction() << 13; // color test func id->d[0] |= (enableFog & 1) << 15; id->d[0] |= (doTextureProjection & 1) << 16; id->d[0] |= (enableColorDoubling & 1) << 17; @@ -276,7 +277,7 @@ void GenerateFragmentShader(char *buffer) { } if (enableAlphaTest) { - int alphaTestFunc = gstate.alphatest & 7; + GEComparison alphaTestFunc = gstate.getAlphaTestFunction(); const char *alphaTestFuncs[] = { "#", "#", " != ", " == ", " >= ", " > ", " <= ", " < " }; // never/always don't make sense if (alphaTestFuncs[alphaTestFunc][0] != '#') { if (gstate_c.gpuVendor == GPU_VENDOR_POWERVR) @@ -296,9 +297,9 @@ void GenerateFragmentShader(char *buffer) { } if (enableColorTest) { - int colorTestFunc = gstate.colortest & 3; + GEComparison colorTestFunc = gstate.getColorTestFunction(); const char *colorTestFuncs[] = { "#", "#", " != ", " == " }; // never/always don't make sense - int colorTestMask = gstate.colormask; + u32 colorTestMask = gstate.getColorTestMask(); if (colorTestFuncs[colorTestFunc][0] != '#') { if (gstate_c.gpuVendor == GPU_VENDOR_POWERVR) WRITE(p, "if (roundTo255thv(v.rgb) %s u_alphacolorref.rgb) discard;\n", colorTestFuncs[colorTestFunc]); diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 291c4cf1a6..639313dc6f 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -301,7 +301,7 @@ void LinkedShader::updateUniforms() { SetColorUniform3(u_texenv, gstate.texenvcolor); } if (u_alphacolorref != -1 && (dirtyUniforms & DIRTY_ALPHACOLORREF)) { - SetColorUniform3Alpha255(u_alphacolorref, gstate.colorref, (gstate.alphatest >> 8) & 0xFF); + SetColorUniform3Alpha255(u_alphacolorref, gstate.getColorTestRef(), gstate.getAlphaTestRef()); } if (u_colormask != -1 && (dirtyUniforms & DIRTY_COLORMASK)) { SetColorUniform3(u_colormask, gstate.colormask); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 69532d432d..a0aeda0b28 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -209,8 +209,6 @@ struct GPUgstate bool isFogEnabled() const { return fogEnable & 1; } bool isAlphaBlendEnabled() const { return alphaBlendEnable & 1; } bool isDitherEnabled() const { return ditherEnable & 1; } - bool isAlphaTestEnabled() const { return alphaTestEnable & 1; } - bool isColorTestEnabled() const { return colorTestEnable & 1; } u32 getColorMask() const { return (pmskc & 0xFFFFFF) | ((pmska & 0xFF) << 24); } bool isLogicOpEnabled() const { return logicOpEnable & 1; } @@ -224,6 +222,16 @@ struct GPUgstate int getStencilOpZFail() const { return (stencilop>>8) & 0x7; } int getStencilOpZPass() const { return (stencilop>>16) & 0x7; } + bool isAlphaTestEnabled() const { return alphaTestEnable & 1; } + GEComparison getAlphaTestFunction() { return static_cast(alphatest & 0x7); } + int getAlphaTestRef() const { return (alphatest >> 8) & 0xFF; } + int getAlphaTestMask() const { return (alphatest >> 16) & 0xFF; } + + bool isColorTestEnabled() const { return colorTestEnable & 1; } + GEComparison getColorTestFunction() { return static_cast(colortest & 0x3); } + u32 getColorTestRef() const { return colorref & 0xFFFFFF; } + u32 getColorTestMask() const { return colormask & 0xFFFFFF; } + // Texturing bool isTextureMapEnabled() const { return textureMapEnable & 1; } int getTextureFunction() const { return texfunc & 0x7; } From 988614f6d0f8dd2b48c8fc63a6a6ae942b5890cc Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 21 Jul 2013 17:55:26 -0700 Subject: [PATCH 10/14] Use lightning GE state accessors where appropriate. --- GPU/GLES/FragmentShaderGenerator.cpp | 6 +++--- GPU/GLES/ShaderManager.cpp | 4 ++-- GPU/GLES/TransformPipeline.cpp | 26 +++++++++++++------------- GPU/GLES/VertexShaderGenerator.cpp | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 45feea1413..76278648fb 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -110,7 +110,7 @@ void ComputeFragmentShaderID(FragmentShaderID *id) { // We only need one clear shader, so let's ignore the rest of the bits. id->d[0] = 1; } else { - int lmode = (gstate.lmode & 1) && gstate.isLightingEnabled(); + bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled(); bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough(); bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue(); bool enableColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue(); @@ -156,8 +156,8 @@ void GenerateFragmentShader(char *buffer) { WRITE(p, "#version 110\n"); #endif - int lmode = (gstate.lmode & 1) && gstate.isLightingEnabled(); - int doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear(); + bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled(); + bool doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear(); bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear(); bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue() && !gstate.isModeClear(); bool enableColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && !gstate.isModeClear(); diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 639313dc6f..1886e53e41 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -398,10 +398,10 @@ void LinkedShader::updateUniforms() { // Lighting if (u_ambient != -1 && (dirtyUniforms & DIRTY_AMBIENT)) { - SetColorUniform3Alpha(u_ambient, gstate.ambientcolor, gstate.ambientalpha & 0xFF); + SetColorUniform3Alpha(u_ambient, gstate.ambientcolor, gstate.getAmbientA()); } if (u_matambientalpha != -1 && (dirtyUniforms & DIRTY_MATAMBIENTALPHA)) { - SetColorUniform3Alpha(u_matambientalpha, gstate.materialambient, gstate.materialalpha & 0xFF); + SetColorUniform3Alpha(u_matambientalpha, gstate.materialambient, gstate.getMaterialAmbientA()); } if (u_matdiffuse != -1 && (dirtyUniforms & DIRTY_MATDIFFUSE)) { SetColorUniform3(u_matdiffuse, gstate.materialdiffuse); diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 956379dcc2..2afcb7e154 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -505,7 +505,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw( int prim, u8 *decoded, LinkedShader *program, int vertexCount, u32 vertType, void *inds, int indexType, const DecVtxFormat &decVtxFormat, int maxIndex) { bool throughmode = (vertType & GE_VTYPE_THROUGH_MASK) != 0; - bool lmode = (gstate.lmode & 1) && gstate.isLightingEnabled(); + bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled(); // TODO: Split up into multiple draw calls for GLES 2.0 where you can't guarantee support for more than 0x10000 verts. @@ -549,10 +549,10 @@ void TransformDrawEngine::SoftwareTransformAndDraw( c1[j] = 0.0f; } } else { - c0[0] = (gstate.materialambient & 0xFF) / 255.f; - c0[1] = ((gstate.materialambient >> 8) & 0xFF) / 255.f; - c0[2] = ((gstate.materialambient >> 16) & 0xFF) / 255.f; - c0[3] = (gstate.materialalpha & 0xFF) / 255.f; + c0[0] = gstate.getMaterialAmbientR() / 255.f; + c0[1] = gstate.getMaterialAmbientG() / 255.f; + c0[2] = gstate.getMaterialAmbientB() / 255.f; + c0[3] = gstate.getMaterialAmbientA() / 255.f; } if (reader.hasUV()) { @@ -612,10 +612,10 @@ void TransformDrawEngine::SoftwareTransformAndDraw( if (reader.hasColor0()) { reader.ReadColor0(unlitColor); } else { - unlitColor[0] = (gstate.materialambient & 0xFF) / 255.f; - unlitColor[1] = ((gstate.materialambient >> 8) & 0xFF) / 255.f; - unlitColor[2] = ((gstate.materialambient >> 16) & 0xFF) / 255.f; - unlitColor[3] = (gstate.materialalpha & 0xFF) / 255.f; + unlitColor[0] = gstate.getMaterialAmbientR() / 255.f; + unlitColor[1] = gstate.getMaterialAmbientG() / 255.f; + unlitColor[2] = gstate.getMaterialAmbientB() / 255.f; + unlitColor[3] = gstate.getMaterialAmbientA() / 255.f; } float litColor0[4]; float litColor1[4]; @@ -643,10 +643,10 @@ void TransformDrawEngine::SoftwareTransformAndDraw( c0[j] = unlitColor[j]; } } else { - c0[0] = (gstate.materialambient & 0xFF) / 255.f; - c0[1] = ((gstate.materialambient >> 8) & 0xFF) / 255.f; - c0[2] = ((gstate.materialambient >> 16)& 0xFF) / 255.f; - c0[3] = (gstate.materialalpha & 0xFF) / 255.f; + c0[0] = gstate.getMaterialAmbientR() / 255.f; + c0[1] = gstate.getMaterialAmbientG() / 255.f; + c0[2] = gstate.getMaterialAmbientB() / 255.f; + c0[3] = gstate.getMaterialAmbientA() / 255.f; } if (lmode) { for (int j = 0; j < 4; j++) { diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index 0adf295715..a552023f22 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -54,7 +54,7 @@ void ComputeVertexShaderID(VertexShaderID *id, int prim, bool useHWTransform) { bool hasNormal = (vertType & GE_VTYPE_NRM_MASK) != 0; bool hasBones = (vertType & GE_VTYPE_WEIGHT_MASK) != 0; bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear(); - bool lmode = (gstate.lmode & 1) && gstate.isLightingEnabled(); + bool lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled(); memset(id->d, 0, sizeof(id->d)); id->d[0] = lmode & 1; @@ -142,7 +142,7 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) { #endif const u32 vertType = gstate.vertType; - int lmode = (gstate.lmode & 1) && gstate.isLightingEnabled(); + int lmode = gstate.isUsingSecondaryColor() && gstate.isLightingEnabled(); int doTexture = gstate.isTextureMapEnabled() && !gstate.isModeClear(); bool hasColor = (vertType & GE_VTYPE_COL_MASK) != 0 || !useHWTransform; From abd9dc61378bf36d365ba5bb2bed6933327be6d2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 21 Jul 2013 18:13:55 -0700 Subject: [PATCH 11/14] Use the light computation/type GE accessors. --- GPU/GLES/ShaderManager.cpp | 3 +-- GPU/GLES/StateMapping.cpp | 2 +- GPU/GLES/TransformPipeline.cpp | 13 ++++++------- GPU/GLES/VertexShaderGenerator.cpp | 25 +++++++++++-------------- GPU/GPUState.h | 14 ++++++++------ GPU/ge_constants.h | 2 +- 6 files changed, 28 insertions(+), 31 deletions(-) diff --git a/GPU/GLES/ShaderManager.cpp b/GPU/GLES/ShaderManager.cpp index 1886e53e41..97cf71efea 100644 --- a/GPU/GLES/ShaderManager.cpp +++ b/GPU/GLES/ShaderManager.cpp @@ -415,8 +415,7 @@ void LinkedShader::updateUniforms() { for (int i = 0; i < 4; i++) { if (dirtyUniforms & (DIRTY_LIGHT0 << i)) { - GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3); - if (type == GE_LIGHTTYPE_DIRECTIONAL) { + if (gstate.isDirectionalLight(i)) { // Prenormalize float x = gstate_c.lightpos[i][0]; float y = gstate_c.lightpos[i][1]; diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 3ba5528678..3dcaf83fe7 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -117,7 +117,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) { // TODO: All this setup is soon so expensive that we'll need dirty flags, or simply do it in the command writes where we detect dirty by xoring. Silly to do all this work on every drawcall. if (gstate_c.textureChanged) { - if (gstate.textureMapEnable & 1) { + if (gstate.isTextureMapEnabled()) { textureCache_->SetTexture(); } gstate_c.textureChanged = false; diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 2afcb7e154..dd1133af97 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -276,11 +276,10 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ for (int l = 0; l < 4; l++) { // can we skip this light? - if ((gstate.lightEnable[l] & 1) == 0) + if (!gstate.isLightChanEnabled(l)) continue; - GELightComputation comp = (GELightComputation)(gstate.ltype[l] & 3); - GELightType type = (GELightType)((gstate.ltype[l] >> 8) & 3); + GELightType type = gstate.getLightType(l); Vec3 toLight(0,0,0); Vec3 lightDir(0,0,0); @@ -290,8 +289,8 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ else toLight = Vec3(gstate_c.lightpos[l]) - pos; - bool doSpecular = (comp != GE_LIGHTCOMP_ONLYDIFFUSE); - bool poweredDiffuse = comp == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE; + bool doSpecular = gstate.isUsingSpecularLight(l); + bool poweredDiffuse = gstate.isUsingPoweredDiffuseLight(l); float distanceToLight = toLight.Length(); float dot = 0.0f; @@ -348,7 +347,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[ } } - if (gstate.lightEnable[l] & 1) + if (gstate.isLightChanEnabled(l)) { Color4 lightAmbient(gstate_c.lightColor[0][l], 0.0f); lightSum0 += (lightAmbient * *ambient + diff) * lightScale; @@ -922,7 +921,7 @@ int TransformDrawEngine::EstimatePerVertexCost() { } for (int i = 0; i < 4; i++) { - if (gstate.lightEnable[i] & 1) + if (gstate.isLightChanEnabled(i)) cost += 10; } if (gstate.getUVGenMode() != 0) { diff --git a/GPU/GLES/VertexShaderGenerator.cpp b/GPU/GLES/VertexShaderGenerator.cpp index a552023f22..ece49b8418 100644 --- a/GPU/GLES/VertexShaderGenerator.cpp +++ b/GPU/GLES/VertexShaderGenerator.cpp @@ -93,12 +93,12 @@ void ComputeVertexShaderID(VertexShaderID *id, int prim, bool useHWTransform) { if (gstate.isLightingEnabled() || gstate.getUVGenMode() == 2) { // Light bits for (int i = 0; i < 4; i++) { - id->d[1] |= (gstate.ltype[i] & 3) << (i * 4); - id->d[1] |= ((gstate.ltype[i] >> 8) & 3) << (i * 4 + 2); + id->d[1] |= gstate.getLightComputation(i) << (i * 4); + id->d[1] |= gstate.getLightType(i) << (i * 4 + 2); } id->d[1] |= (gstate.materialupdate & 7) << 16; for (int i = 0; i < 4; i++) { - id->d[1] |= (gstate.lightEnable[i] & 1) << (20 + i); + id->d[1] |= (gstate.isLightChanEnabled(i) & 1) << (20 + i); } } } @@ -159,7 +159,7 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) { for (int i = 0; i < 4; i++) { if (i == shadeLight0 || i == shadeLight1) doLight[i] = LIGHT_SHADE; - if ((gstate.lightingEnable & 1) && (gstate.lightEnable[i] & 1)) + if (gstate.isLightingEnabled() && gstate.isLightChanEnabled(i)) doLight[i] = LIGHT_FULL; } } @@ -222,7 +222,7 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) { if (doLight[i] == LIGHT_FULL) { // These are needed for the full thing WRITE(p, "uniform mediump vec3 u_lightdir%i;\n", i); - GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3); + GELightType type = gstate.getLightType(i); if (type != GE_LIGHTTYPE_DIRECTIONAL) WRITE(p, "uniform mediump vec3 u_lightatt%i;\n", i); @@ -234,8 +234,7 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) { WRITE(p, "uniform lowp vec3 u_lightambient%i;\n", i); WRITE(p, "uniform lowp vec3 u_lightdiffuse%i;\n", i); - GELightComputation comp = (GELightComputation)(gstate.ltype[i] & 3); - if (comp != GE_LIGHTCOMP_ONLYDIFFUSE) + if (gstate.isUsingSpecularLight(i)) WRITE(p, "uniform lowp vec3 u_lightspecular%i;\n", i); } } @@ -399,10 +398,9 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) { if (doLight[i] != LIGHT_FULL) continue; diffuseIsZero = false; - GELightComputation comp = (GELightComputation)(gstate.ltype[i] & 3); - if (comp != GE_LIGHTCOMP_ONLYDIFFUSE) + if (gstate.isUsingSpecularLight(i)) specularIsZero = false; - GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3); + GELightType type = gstate.getLightType(i); if (type != GE_LIGHTTYPE_DIRECTIONAL) distanceNeeded = true; } @@ -427,8 +425,7 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) { if (doLight[i] != LIGHT_FULL) continue; - GELightComputation comp = (GELightComputation)(gstate.ltype[i] & 3); - GELightType type = (GELightType)((gstate.ltype[i] >> 8) & 3); + GELightType type = gstate.getLightType(i); if (type == GE_LIGHTTYPE_DIRECTIONAL) { // We prenormalize light positions for directional lights. @@ -439,8 +436,8 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) { WRITE(p, " toLight /= distance;\n"); } - bool doSpecular = (comp != GE_LIGHTCOMP_ONLYDIFFUSE); - bool poweredDiffuse = comp == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE; + bool doSpecular = gstate.isUsingSpecularLight(i); + bool poweredDiffuse = gstate.isUsingPoweredDiffuseLight(i); if (poweredDiffuse) { WRITE(p, " mediump float dot%i = pow(dot(toLight, worldnormal), u_matspecular.a);\n", i); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index a0aeda0b28..7463d5a95d 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -249,13 +249,15 @@ struct GPUgstate // Lighting bool isLightingEnabled() const { return lightingEnable & 1; } - bool isLightChanEnabled(int chan) const { return lightEnable[chan] & 1;} - bool isUsingPoweredDiffuseLight(int chan) const { return (ltype[chan] & 0x3) == 0x2; } - bool isUsingSpecularLight(int chan) const { return (ltype[chan] & 0x3) == 0x1 || (ltype[chan] & 0x3) == 0x2; } + bool isLightChanEnabled(int chan) const { return lightEnable[chan] & 1; } + GELightComputation getLightComputation(int chan) const { return static_cast(ltype[chan] & 0x3); } + bool isUsingPoweredDiffuseLight(int chan) const { return getLightComputation(chan) == GE_LIGHTCOMP_BOTHWITHPOWDIFFUSE; } + bool isUsingSpecularLight(int chan) const { return getLightComputation(chan) != GE_LIGHTCOMP_ONLYDIFFUSE; } bool isUsingSecondaryColor() const { return lmode & 1; } - bool isDirectionalLight(int chan) const { return ((ltype[chan] & 0x30)>>8) == 0; } - bool isPointLight(int chan) const { return ((ltype[chan] & 0x30)>>8) == 1; } - bool isSpotLight(int chan) const { return ((ltype[chan] & 0x30)>>8) == 2; } + GELightType getLightType(int chan) const { return static_cast((ltype[chan] >> 8) & 3); } + bool isDirectionalLight(int chan) const { return getLightType(chan) == GE_LIGHTTYPE_DIRECTIONAL; } + bool isPointLight(int chan) const { return getLightType(chan) == GE_LIGHTTYPE_POINT; } + bool isSpotLight(int chan) const { return getLightType(chan) == GE_LIGHTTYPE_SPOT; } unsigned int getAmbientR() const { return ambientcolor&0xFF; } unsigned int getAmbientG() const { return (ambientcolor>>8)&0xFF; } diff --git a/GPU/ge_constants.h b/GPU/ge_constants.h index 1a32761dfe..c09275053c 100644 --- a/GPU/ge_constants.h +++ b/GPU/ge_constants.h @@ -340,7 +340,7 @@ enum GEComparison enum GELightType { - GE_LIGHTTYPE_DIRECTIONAL=0, + GE_LIGHTTYPE_DIRECTIONAL = 0, GE_LIGHTTYPE_POINT = 1, GE_LIGHTTYPE_SPOT = 2 }; From 46805b37cb1dc2c254e957c47f4198998e90729e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 21 Jul 2013 18:35:52 -0700 Subject: [PATCH 12/14] Use the texture-related GE accessors. --- GPU/GLES/FragmentShaderGenerator.cpp | 16 ++++++++-------- GPU/GPUState.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/GPU/GLES/FragmentShaderGenerator.cpp b/GPU/GLES/FragmentShaderGenerator.cpp index 76278648fb..cf5684af1d 100644 --- a/GPU/GLES/FragmentShaderGenerator.cpp +++ b/GPU/GLES/FragmentShaderGenerator.cpp @@ -114,20 +114,20 @@ void ComputeFragmentShaderID(FragmentShaderID *id) { bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough(); bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue(); bool enableColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue(); - bool enableColorDoubling = (gstate.texfunc & 0x10000) != 0; + bool enableColorDoubling = gstate.isColorDoublingEnabled(); // This isn't really correct, but it's a hack to get doubled blend modes to work more correctly. bool enableAlphaDoubling = CanDoubleSrcBlendMode(); bool doTextureProjection = gstate.getUVGenMode() == 1; bool doTextureAlpha = (gstate.texfunc & 0x100) != 0; // All texfuncs except replace are the same for RGB as for RGBA with full alpha. - if (gstate_c.textureFullAlpha && (gstate.texfunc & 0x7) != GE_TEXFUNC_REPLACE) + if (gstate_c.textureFullAlpha && gstate.getTextureFunction() != GE_TEXFUNC_REPLACE) doTextureAlpha = false; // id->d[0] |= (gstate.isModeClear() & 1); if (gstate.isTextureMapEnabled()) { id->d[0] |= 1 << 1; - id->d[0] |= (gstate.texfunc & 0x7) << 2; + id->d[0] |= gstate.getTextureFunction() << 2; id->d[0] |= (doTextureAlpha & 1) << 5; // rgb or rgba } id->d[0] |= (lmode & 1) << 7; @@ -161,13 +161,13 @@ void GenerateFragmentShader(char *buffer) { bool enableFog = gstate.isFogEnabled() && !gstate.isModeThrough() && !gstate.isModeClear(); bool enableAlphaTest = gstate.isAlphaTestEnabled() && !IsAlphaTestTriviallyTrue() && !gstate.isModeClear(); bool enableColorTest = gstate.isColorTestEnabled() && !IsColorTestTriviallyTrue() && !gstate.isModeClear(); - bool enableColorDoubling = (gstate.texfunc & 0x10000) != 0; + bool enableColorDoubling = gstate.isColorDoublingEnabled(); // This isn't really correct, but it's a hack to get doubled blend modes to work more correctly. bool enableAlphaDoubling = CanDoubleSrcBlendMode(); bool doTextureProjection = gstate.getUVGenMode() == 1; bool doTextureAlpha = (gstate.texfunc & 0x100) != 0; - if (gstate_c.textureFullAlpha && (gstate.texfunc & 0x7) != GE_TEXFUNC_REPLACE) + if (gstate_c.textureFullAlpha && gstate.getTextureFunction() != GE_TEXFUNC_REPLACE) doTextureAlpha = false; if (doTexture) @@ -240,7 +240,7 @@ void GenerateFragmentShader(char *buffer) { WRITE(p, " vec4 p = v_color0;\n"); if (doTextureAlpha) { // texfmt == RGBA - switch (gstate.texfunc & 0x7) { + switch (gstate.getTextureFunction()) { case GE_TEXFUNC_MODULATE: WRITE(p, " vec4 v = p * t%s;\n", secondary); break; case GE_TEXFUNC_DECAL: @@ -255,8 +255,8 @@ void GenerateFragmentShader(char *buffer) { WRITE(p, " vec4 v = p;\n"); break; } - } else { // texfmt == RGB - switch (gstate.texfunc & 0x7) { + } else { // texfmt == RGB + switch (gstate.getTextureFunction()) { case GE_TEXFUNC_MODULATE: WRITE(p, " vec4 v = vec4(t.rgb * p.rgb, p.a)%s;\n", secondary); break; case GE_TEXFUNC_DECAL: diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 7463d5a95d..5ffaea3769 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -234,7 +234,7 @@ struct GPUgstate // Texturing bool isTextureMapEnabled() const { return textureMapEnable & 1; } - int getTextureFunction() const { return texfunc & 0x7; } + GETexFunc getTextureFunction() const { return static_cast(texfunc & 0x7); } bool isColorDoublingEnabled() const { return (texfunc & 0x10000) != 0; } GETextureFormat getTextureFormat() const { return static_cast(texformat & 0xF); } From b2927213c764a111145da275d220bb09a7419330 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 21 Jul 2013 18:54:17 -0700 Subject: [PATCH 13/14] Use stencil GE state accessors. --- GPU/GLES/StateMapping.cpp | 12 ++++++------ GPU/GPUState.h | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 3dcaf83fe7..702fd0f613 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -267,12 +267,12 @@ void TransformDrawEngine::ApplyDrawState(int prim) { // Stencil Test if (gstate.isStencilTestEnabled()) { glstate.stencilTest.enable(); - glstate.stencilFunc.set(ztests[gstate.stenciltest & 0x7],// comparison function - (gstate.stenciltest >> 8) & 0xFF, // reference value - (gstate.stenciltest >> 16) & 0xFF); // mask - glstate.stencilOp.set(stencilOps[gstate.stencilop & 0x7], // stencil fail - stencilOps[(gstate.stencilop >> 8) & 0x7], // depth fail - stencilOps[(gstate.stencilop >> 16) & 0x7]); // depth pass + glstate.stencilFunc.set(ztests[gstate.getStencilTestFunction()], + gstate.getStencilTestRef(), + gstate.getStencilTestMask()); + glstate.stencilOp.set(stencilOps[gstate.getStencilOpSFail()], // stencil fail + stencilOps[gstate.getStencilOpZFail()], // depth fail + stencilOps[gstate.getStencilOpZPass()]); // depth pass } else glstate.stencilTest.disable(); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 5ffaea3769..8a6b0e13f1 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -215,12 +215,12 @@ struct GPUgstate GELogicOp getLogicOp() const { return static_cast(lop & 0xF); } bool isStencilTestEnabled() const { return stencilTestEnable & 1; } - int getStencilTestFunction() const { return stenciltest & 0x7; } + GEComparison getStencilTestFunction() const { return static_cast(stenciltest & 0x7); } int getStencilTestRef() const { return (stenciltest>>8) & 0xFF; } int getStencilTestMask() const { return (stenciltest>>16) & 0xFF; } - int getStencilOpSFail() const { return stencilop & 0x7; } - int getStencilOpZFail() const { return (stencilop>>8) & 0x7; } - int getStencilOpZPass() const { return (stencilop>>16) & 0x7; } + GEStencilOp getStencilOpSFail() const { return static_cast(stencilop & 0x7); } + GEStencilOp getStencilOpZFail() const { return static_cast((stencilop>>8) & 0x7); } + GEStencilOp getStencilOpZPass() const { return static_cast((stencilop>>16) & 0x7); } bool isAlphaTestEnabled() const { return alphaTestEnable & 1; } GEComparison getAlphaTestFunction() { return static_cast(alphatest & 0x7); } From 4cfa074546280784c79848d2c6c446ebcd50159b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 21 Jul 2013 19:34:55 -0700 Subject: [PATCH 14/14] Use GE state accessors in the texcache. --- GPU/GLES/TextureCache.cpp | 46 +++++++++++++++++++-------------------- GPU/GLES/TextureCache.h | 2 +- GPU/GPUState.h | 4 ++++ 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 3933b92c19..39d2dd5d77 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -283,7 +283,7 @@ void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u template inline void DeIndexTexture(ClutT *dest, const IndexT *indexed, int length, const ClutT *clut) { // Usually, there is no special offset, mask, or shift. - const bool nakedIndex = (gstate.clutformat & ~3) == 0xC500FF00; + const bool nakedIndex = gstate.isClutIndexSimple(); if (nakedIndex) { if (sizeof(IndexT) == 1) { @@ -311,7 +311,7 @@ inline void DeIndexTexture(ClutT *dest, const u32 texaddr, int length, const Clu template inline void DeIndexTexture4(ClutT *dest, const u8 *indexed, int length, const ClutT *clut) { // Usually, there is no special offset, mask, or shift. - const bool nakedIndex = (gstate.clutformat & ~3) == 0xC500FF00; + const bool nakedIndex = gstate.isClutIndexSimple(); if (nakedIndex) { for (int i = 0; i < length; i += 2) { @@ -367,7 +367,7 @@ void *TextureCache::readIndexedTex(int level, u32 texaddr, int bytesPerIndex, GL int h = 1 << ((gstate.texsize[0] >> 8) & 0xf); int length = bufw * h; void *buf = NULL; - switch ((gstate.clutformat & 3)) { + switch (gstate.getClutPaletteFormat()) { case GE_CMODE_16BIT_BGR5650: case GE_CMODE_16BIT_ABGR5551: case GE_CMODE_16BIT_ABGR4444: @@ -782,7 +782,7 @@ static inline u32 QuickClutHash(const u8 *clut, u32 bytes) { return hash; } -static inline u32 QuickTexHash(u32 addr, int bufw, int w, int h, u32 format) { +static inline u32 QuickTexHash(u32 addr, int bufw, int w, int h, GETextureFormat format) { const u32 sizeInRAM = (bitsPerPixel[format < 11 ? format : 0] * bufw * h) / 8; const u32 *checkp = (const u32 *) Memory::GetPointer(addr); u32 check = 0; @@ -832,7 +832,7 @@ void TextureCache::LoadClut() { void TextureCache::UpdateCurrentClut() { const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat(); - const u32 clutBase = (gstate.clutformat & 0x1f0000) >> 12; + const u32 clutBase = gstate.getClutIndexStartPos(); const u32 clutBaseBytes = clutBase * (clutFormat == GE_CMODE_32BIT_ABGR8888 ? sizeof(u32) : sizeof(u16)); // Technically, these extra bytes weren't loaded, but hopefully it was loaded earlier. // If not, we're going to hash random data, which hopefully doesn't cause a performance issue. @@ -853,7 +853,7 @@ void TextureCache::UpdateCurrentClut() { // Special optimization: fonts typically draw clut4 with just alpha values in a single color. clutAlphaLinear_ = false; clutAlphaLinearColor_ = 0; - if (gstate.clutformat == (0xC500FF00 | GE_CMODE_16BIT_ABGR4444)) { + if (gstate.getClutPaletteFormat() == GE_CMODE_16BIT_ABGR4444 && gstate.isClutIndexSimple()) { const u16 *clut = GetCurrentClut(); clutAlphaLinear_ = true; clutAlphaLinearColor_ = clut[15] & 0xFFF0; @@ -941,13 +941,13 @@ void TextureCache::SetTexture() { return; } - u32 format = gstate.texformat & 0xF; + GETextureFormat format = gstate.getTextureFormat(); if (format >= 11) { ERROR_LOG_REPORT(G3D, "Unknown texture format %i", format); - format = 0; + // TODO: Better assumption? + format = GE_TFMT_5650; } - // GE_TFMT_CLUT4 - GE_TFMT_CLUT32 are 0b1xx. - bool hasClut = (format & 4) != 0; + bool hasClut = gstate.isTextureFormatIndexed(); u64 cachekey = (u64)texaddr << 32; u32 cluthash; @@ -1202,7 +1202,7 @@ void TextureCache::SetTexture() { gstate_c.textureFullAlpha = (entry->status & TexCacheEntry::STATUS_ALPHA_MASK) == TexCacheEntry::STATUS_ALPHA_FULL; } -void *TextureCache::DecodeTextureLevel(u8 format, u8 clutformat, int level, u32 &texByteAlign, GLenum &dstFmt) { +void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat clutformat, int level, u32 &texByteAlign, GLenum &dstFmt) { void *finalBuf = NULL; u32 texaddr = (gstate.texaddr[level] & 0xFFFFF0) | ((gstate.texbufwidth[level] << 8) & 0x0F000000); @@ -1217,7 +1217,7 @@ void *TextureCache::DecodeTextureLevel(u8 format, u8 clutformat, int level, u32 { case GE_TFMT_CLUT4: { - dstFmt = getClutDestFormat((GEPaletteFormat)(clutformat)); + dstFmt = getClutDestFormat(clutformat); const bool mipmapShareClut = (gstate.texmode & 0x100) == 0; const int clutSharingOffset = mipmapShareClut ? 0 : level * 16; @@ -1269,28 +1269,28 @@ void *TextureCache::DecodeTextureLevel(u8 format, u8 clutformat, int level, u32 break; default: - ERROR_LOG(G3D, "Unknown CLUT4 texture mode %d", (gstate.clutformat & 3)); + ERROR_LOG(G3D, "Unknown CLUT4 texture mode %d", gstate.getClutPaletteFormat()); return NULL; } } break; case GE_TFMT_CLUT8: - dstFmt = getClutDestFormat((GEPaletteFormat)(gstate.clutformat & 3)); + dstFmt = getClutDestFormat(gstate.getClutPaletteFormat()); + texByteAlign = texByteAlignMap[gstate.getClutPaletteFormat()]; finalBuf = readIndexedTex(level, texaddr, 1, dstFmt); - texByteAlign = texByteAlignMap[(gstate.clutformat & 3)]; break; case GE_TFMT_CLUT16: - dstFmt = getClutDestFormat((GEPaletteFormat)(gstate.clutformat & 3)); + dstFmt = getClutDestFormat(gstate.getClutPaletteFormat()); + texByteAlign = texByteAlignMap[gstate.getClutPaletteFormat()]; finalBuf = readIndexedTex(level, texaddr, 2, dstFmt); - texByteAlign = texByteAlignMap[(gstate.clutformat & 3)]; break; case GE_TFMT_CLUT32: - dstFmt = getClutDestFormat((GEPaletteFormat)(gstate.clutformat & 3)); + dstFmt = getClutDestFormat(gstate.getClutPaletteFormat()); + texByteAlign = texByteAlignMap[gstate.getClutPaletteFormat()]; finalBuf = readIndexedTex(level, texaddr, 4, dstFmt); - texByteAlign = texByteAlignMap[(gstate.clutformat & 3)]; break; case GE_TFMT_4444: @@ -1509,8 +1509,8 @@ void TextureCache::LoadTextureLevel(TexCacheEntry &entry, int level, bool replac // TODO: Look into using BGRA for 32-bit textures when the GL_EXT_texture_format_BGRA8888 extension is available, as it's faster than RGBA on some chips. GLenum dstFmt = 0; - u8 clutformat = gstate.clutformat & 3; - void *finalBuf = DecodeTextureLevel(entry.format, clutformat, level, texByteAlign, dstFmt); + GEPaletteFormat clutformat = gstate.getClutPaletteFormat(); + void *finalBuf = DecodeTextureLevel(GETextureFormat(entry.format), clutformat, level, texByteAlign, dstFmt); if (finalBuf == NULL) { return; } @@ -1575,8 +1575,8 @@ bool TextureCache::DecodeTexture(u8* output, GPUgstate state) u32 texByteAlign = 1; GLenum dstFmt = 0; - u32 format = gstate.texformat & 0xF; - u32 clutformat = gstate.clutformat & 3; + GETextureFormat format = gstate.getTextureFormat(); + GEPaletteFormat clutformat = gstate.getClutPaletteFormat(); u8 level = 0; int bufw = GetLevelBufw(level, texaddr); diff --git a/GPU/GLES/TextureCache.h b/GPU/GLES/TextureCache.h index 772374ca88..c124b5ed28 100644 --- a/GPU/GLES/TextureCache.h +++ b/GPU/GLES/TextureCache.h @@ -111,7 +111,7 @@ private: void *readIndexedTex(int level, u32 texaddr, int bytesPerIndex, GLuint dstFmt); void UpdateSamplingParams(TexCacheEntry &entry, bool force); void LoadTextureLevel(TexCacheEntry &entry, int level, bool replaceImages); - void *DecodeTextureLevel(u8 format, u8 clutformat, int level, u32 &texByteAlign, GLenum &dstFmt); + void *DecodeTextureLevel(GETextureFormat format, GEPaletteFormat clutformat, int level, u32 &texByteAlign, GLenum &dstFmt); void CheckAlpha(TexCacheEntry &entry, u32 *pixelData, GLenum dstFmt, int w, int h); template const T *GetCurrentClut(); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 8a6b0e13f1..0d0ca24adb 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -237,6 +237,8 @@ struct GPUgstate GETexFunc getTextureFunction() const { return static_cast(texfunc & 0x7); } bool isColorDoublingEnabled() const { return (texfunc & 0x10000) != 0; } GETextureFormat getTextureFormat() const { return static_cast(texformat & 0xF); } + // GE_TFMT_CLUT4 - GE_TFMT_CLUT32 are 0b1xx. + bool isTextureFormatIndexed() const { return (texformat & 4) != 0; } int getTextureEnvColR() const { return texenvcolor&0xFF; } int getTextureEnvColG() const { return (texenvcolor>>8)&0xFF; } @@ -246,6 +248,8 @@ struct GPUgstate int getClutIndexShift() const { return (clutformat >> 2) & 0x1F; } int getClutIndexMask() const { return (clutformat >> 8) & 0xFF; } int getClutIndexStartPos() const { return ((clutformat >> 16) & 0x1F) << 4; } + // Meaning, no special mask, shift, or start pos. + bool isClutIndexSimple() const { return (clutformat & ~3) == 0xC500FF00; } // Lighting bool isLightingEnabled() const { return lightingEnable & 1; }