diff --git a/GPU/GLES/StateMapping.cpp b/GPU/GLES/StateMapping.cpp index 0d35e8e67c..0734c77fba 100644 --- a/GPU/GLES/StateMapping.cpp +++ b/GPU/GLES/StateMapping.cpp @@ -10,8 +10,8 @@ const GLint aLookup[] = { GL_SRC_ALPHA, // should be 2x GL_ONE_MINUS_SRC_ALPHA, // should be 2x GL_DST_ALPHA, // should be 2x - GL_ONE_MINUS_DST_ALPHA, // should be 2x - and COLOR? - GL_SRC_ALPHA, // should be FIXA + GL_ONE_MINUS_DST_ALPHA, // should be 2x - and COLOR? + GL_CONSTANT_COLOR, // FIXA }; const GLint bLookup[] = { @@ -25,7 +25,7 @@ const GLint bLookup[] = { GL_ONE_MINUS_SRC_ALPHA, // should be 2x GL_DST_ALPHA, // should be 2x GL_ONE_MINUS_DST_ALPHA, // should be 2x - GL_SRC_ALPHA, // should be FIXB + GL_CONSTANT_COLOR, // FIXB }; const GLint eqLookup[] = { GL_FUNC_ADD, diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index 0fa436b8d5..7da2ef6e3f 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -600,7 +600,7 @@ void PSPSetTexture() u32 w = 1 << (gstate.texsize[0] & 0xf); u32 h = 1 << ((gstate.texsize[0]>>8) & 0xf); - NOTICE_LOG(G3D, "Creating texture %i from %08x: %i x %i (stride: %i). fmt: %i", entry.texture, entry.addr, w, h, bufw, entry.format); + INFO_LOG(G3D, "Creating texture %i from %08x: %i x %i (stride: %i). fmt: %i", entry.texture, entry.addr, w, h, bufw, entry.format); gstate_c.curTextureWidth=w; gstate_c.curTextureHeight=h; @@ -609,8 +609,6 @@ void PSPSetTexture() void *finalBuf = NULL; - DEBUG_LOG(G3D,"Texture Width %04x Height %04x Bufw %d Fmt %d", w, h, bufw, format); - // 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. // TODO: Actually decode the mipmaps. diff --git a/GPU/GLES/TransformPipeline.cpp b/GPU/GLES/TransformPipeline.cpp index 9eeb8d25e5..ff6d1261df 100644 --- a/GPU/GLES/TransformPipeline.cpp +++ b/GPU/GLES/TransformPipeline.cpp @@ -526,6 +526,8 @@ void TransformAndDrawPrim(void *verts, void *inds, int prim, int vertexCount, Li } } + // 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. + // Set cull bool wantCull = !gstate.isModeClear() && !gstate.isModeThrough() && gstate.isCullEnabled(); glstate.cullFace.set(wantCull); @@ -541,12 +543,53 @@ void TransformAndDrawPrim(void *verts, void *inds, int prim, int vertexCount, Li if(wantBlend) { // This can't be done exactly as there are several PSP blend modes that are impossible to do on OpenGL ES 2.0, and some even on regular OpenGL for desktop. // HOWEVER - we should be able to approximate the 2x modes in the shader, although they will clip wrongly. - u8 blendFuncA = gstate.getBlendFuncA(); - u8 blendFuncB = gstate.getBlendFuncB(); - u8 blendFuncEq = gstate.getBlendEq(); + int blendFuncA = gstate.getBlendFuncA(); + int blendFuncB = gstate.getBlendFuncB(); + int blendFuncEq = gstate.getBlendEq(); - glstate.blendFunc.set(aLookup[blendFuncA], bLookup[blendFuncB]); glstate.blendEquation.set(eqLookup[blendFuncEq]); + + if (blendFuncA != GE_SRCBLEND_FIXA && blendFuncB != GE_DSTBLEND_FIXB) { + // All is valid, no blendcolor needed + glstate.blendFunc.set(aLookup[blendFuncA], bLookup[blendFuncB]); + } else { + GLuint glBlendFuncA = blendFuncA == GE_SRCBLEND_FIXA ? 0 : aLookup[blendFuncA]; + GLuint glBlendFuncB = blendFuncB == GE_DSTBLEND_FIXB ? 0 : bLookup[blendFuncB]; + u32 fixA = gstate.getFixA(); + u32 fixB = gstate.getFixB(); + // Shortcut by using GL_ONE where possible, no need to set blendcolor + if (!glBlendFuncA && blendFuncA == GE_SRCBLEND_FIXA && fixA == 0xFFFFFF) { + glBlendFuncA = GL_ONE; + } + if (!glBlendFuncB && blendFuncB == GE_DSTBLEND_FIXB && fixB == 0xFFFFFF) { + glBlendFuncB = GL_ONE; + } + if (!glBlendFuncA && glBlendFuncB) { + // Can use blendcolor trivially. + const float blendColor[4] = {(fixA & 0xFF)/255.0f, ((fixA >> 8) & 0xFF)/255.0f, ((fixA >> 16) & 0xFF)/255.0f, 1.0f}; + glstate.blendColor.set(blendColor); + glBlendFuncA = GL_CONSTANT_COLOR; + } else if (glBlendFuncA && !glBlendFuncB) { + // Can use blendcolor trivially. + const float blendColor[4] = {(fixB & 0xFF)/255.0f, ((fixB >> 8) & 0xFF)/255.0f, ((fixB >> 16) & 0xFF)/255.0f, 1.0f}; + glstate.blendColor.set(blendColor); + glBlendFuncB = GL_CONSTANT_COLOR; + } else if (!glBlendFuncA && !glBlendFuncB) { // Should also check for approximate equality + if (fixA == (fixB ^ 0xFFFFFF)) { + glBlendFuncA = GL_CONSTANT_COLOR; + glBlendFuncB = GL_ONE_MINUS_CONSTANT_COLOR; + const float blendColor[4] = {(fixA & 0xFF)/255.0f, ((fixA >> 8) & 0xFF)/255.0f, ((fixA >> 16) & 0xFF)/255.0f, 1.0f}; + glstate.blendColor.set(blendColor); + } else { + NOTICE_LOG(HLE, "ERROR INVALID blendcolorstate: FixA=%06x FixB=%06x FuncA=%i FuncB=%i", gstate.getFixA(), gstate.getFixB(), gstate.getBlendFuncA(), gstate.getBlendFuncB()); + glBlendFuncA = GL_ONE; + glBlendFuncB = GL_ONE; + } + } + // At this point, through all paths above, glBlendFuncA and glBlendFuncB will be set somehow. + + glstate.blendFunc.set(glBlendFuncA, glBlendFuncB); + } } bool wantDepthTest = gstate.isModeClear() || gstate.isDepthTestEnabled(); diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 1aef69d17f..e9750babaa 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -242,12 +242,14 @@ struct GPUgstate inline bool isModeThrough() const { return (vertType & GE_VTYPE_THROUGH) != 0; } inline bool isModeClear() const { return clearmode & 1; } inline bool isCullEnabled() const { return cullfaceEnable & 1; } - inline u8 getCullMode() const { return cullmode & 1; } - inline u8 getBlendFuncA() const { return blend & 0xF; } - inline u8 getBlendFuncB() const { return (blend >> 4) & 0xF; } - inline u8 getBlendEq() const { return (blend >> 8) & 0x7; } + inline int getCullMode() const { return cullmode & 1; } + inline int getBlendFuncA() const { return blend & 0xF; } + inline u32 getFixA() const { return blendfixa & 0xFFFFFF; } + inline u32 getFixB() const { return blendfixb & 0xFFFFFF; } + inline int getBlendFuncB() const { return (blend >> 4) & 0xF; } + inline int getBlendEq() const { return (blend >> 8) & 0x7; } inline bool isDepthTestEnabled() const { return zTestEnable & 1; } - inline u8 getDepthTestFunc() const { return ztestfunc & 0x7; } + inline int getDepthTestFunc() const { return ztestfunc & 0x7; } }; // Real data in the context ends here diff --git a/GPU/ge_constants.h b/GPU/ge_constants.h index be9caab1dc..d23449f88c 100644 --- a/GPU/ge_constants.h +++ b/GPU/ge_constants.h @@ -384,7 +384,7 @@ enum GEBlendSrcFactor GE_SRCBLEND_DOUBLEINVSRCALPHA, GE_SRCBLEND_DOUBLEDSTALPHA, GE_SRCBLEND_DOUBLEINVDSTALPHA, - GE_SRCBLEND_FIXEDA, + GE_SRCBLEND_FIXA, }; enum GEBlendDstFactor @@ -399,7 +399,7 @@ enum GEBlendDstFactor GE_DSTBLEND_DOUBLEINVSRCALPHA, GE_DSTBLEND_DOUBLEDSTALPHA, GE_DSTBLEND_DOUBLEINVDSTALPHA, - GE_DSTBLEND_FIXEDB, + GE_DSTBLEND_FIXB, }; enum GETexFunc diff --git a/native b/native index 41e5a5f367..f4278247ed 160000 --- a/native +++ b/native @@ -1 +1 @@ -Subproject commit 41e5a5f3675765114d25357509ddd564d5691674 +Subproject commit f4278247ed7f9d8db221bc2c1a062227442e99bc