Support FIXA and FIXB blend factors as well as possible.

This commit is contained in:
Henrik Rydgard 2012-11-25 15:49:37 +01:00
parent ced89f5983
commit d0f829353d
6 changed files with 61 additions and 18 deletions

View file

@ -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,

View file

@ -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.

View file

@ -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();

View file

@ -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

View file

@ -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

2
native

@ -1 +1 @@
Subproject commit 41e5a5f3675765114d25357509ddd564d5691674
Subproject commit f4278247ed7f9d8db221bc2c1a062227442e99bc