mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Support FIXA and FIXB blend factors as well as possible.
This commit is contained in:
parent
ced89f5983
commit
d0f829353d
6 changed files with 61 additions and 18 deletions
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
2
native
|
@ -1 +1 @@
|
|||
Subproject commit 41e5a5f3675765114d25357509ddd564d5691674
|
||||
Subproject commit f4278247ed7f9d8db221bc2c1a062227442e99bc
|
Loading…
Add table
Reference in a new issue