Merge pull request #2883 from unknownbrackets/gpu-minor

Use GE state accessors more often
This commit is contained in:
Henrik Rydgård 2013-07-22 00:24:14 -07:00
commit 98a7fc124d
9 changed files with 253 additions and 175 deletions

View file

@ -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;
@ -109,33 +110,33 @@ 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();
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.clearmode & 1);
// 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;
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;
@ -155,18 +156,18 @@ 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();
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)
@ -239,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:
@ -254,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:
@ -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]);

View file

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

View file

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

View file

@ -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;
}
@ -283,7 +283,7 @@ void *TextureCache::UnswizzleFromMem(u32 texaddr, u32 bufw, u32 bytesPerPixel, u
template <typename IndexT, typename ClutT>
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 <typename ClutT>
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;
@ -831,8 +831,8 @@ void TextureCache::LoadClut() {
}
void TextureCache::UpdateCurrentClut() {
const GEPaletteFormat clutFormat = (GEPaletteFormat)(gstate.clutformat & 3);
const u32 clutBase = (gstate.clutformat & 0x1f0000) >> 12;
const GEPaletteFormat clutFormat = gstate.getClutPaletteFormat();
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<u16>();
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);

View file

@ -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 <typename T>
const T *GetCurrentClut();

View file

@ -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;
@ -505,7 +504,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 +548,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 +611,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 +642,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++) {
@ -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) {

View file

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

View file

@ -78,84 +78,84 @@ 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,
lmode,
ltype[4],
lpos[12],
ldir[12],
latt[12],
lconv[4],
lcutoff[4],
lcolor[12],
cullmode,
fbptr,
fbwidth,
zbptr,
zbwidth,
texaddr[8],
texbufwidth[8],
clutaddr,
clutaddrupper,
transfersrc,
transfersrcw,
transferdst,
transferdstw,
materialspecularcoef, // 0x5B
ambientcolor, // 0x5C
ambientalpha, // 0x5D
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], // 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,
clutformat,
texfilter,
texwrap,
texlevel,
texfunc,
texenvcolor,
texflush,
texsync,
fog1,
fog2,
fogcolor,
texlodslope,
padxxxxxx,
framebufpixformat,
clearmode,
texsize[8], // 0xB8-BF
texmapmode, // 0xC0
texshade, // 0xC1
texmode, // 0xC2
texformat, // 0xC3
loadclut, // 0xC4
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,
@ -207,13 +207,95 @@ 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; }
u32 getColorMask() const { return (pmskc & 0xFFFFFF) | ((pmska & 0xFF) << 24); }
bool isLogicOpEnabled() const { return logicOpEnable & 1; }
GELogicOp getLogicOp() const { return static_cast<GELogicOp>(lop & 0xF); }
bool isStencilTestEnabled() const { return stencilTestEnable & 1; }
GEComparison getStencilTestFunction() const { return static_cast<GEComparison>(stenciltest & 0x7); }
int getStencilTestRef() const { return (stenciltest>>8) & 0xFF; }
int getStencilTestMask() const { return (stenciltest>>16) & 0xFF; }
GEStencilOp getStencilOpSFail() const { return static_cast<GEStencilOp>(stencilop & 0x7); }
GEStencilOp getStencilOpZFail() const { return static_cast<GEStencilOp>((stencilop>>8) & 0x7); }
GEStencilOp getStencilOpZPass() const { return static_cast<GEStencilOp>((stencilop>>16) & 0x7); }
bool isAlphaTestEnabled() const { return alphaTestEnable & 1; }
GEComparison getAlphaTestFunction() { return static_cast<GEComparison>(alphatest & 0x7); }
int getAlphaTestRef() const { return (alphatest >> 8) & 0xFF; }
int getAlphaTestMask() const { return (alphatest >> 16) & 0xFF; }
bool isColorTestEnabled() const { return colorTestEnable & 1; }
bool isLightingEnabled() const { return lightingEnable & 1; }
GEComparison getColorTestFunction() { return static_cast<GEComparison>(colortest & 0x3); }
u32 getColorTestRef() const { return colorref & 0xFFFFFF; }
u32 getColorTestMask() const { return colormask & 0xFFFFFF; }
// Texturing
bool isTextureMapEnabled() const { return textureMapEnable & 1; }
GETexFunc getTextureFunction() const { return static_cast<GETexFunc>(texfunc & 0x7); }
bool isColorDoublingEnabled() const { return (texfunc & 0x10000) != 0; }
GETextureFormat getTextureFormat() const { return static_cast<GETextureFormat>(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; }
int getTextureEnvColB() const { return (texenvcolor>>16)&0xFF; }
GEPaletteFormat getClutPaletteFormat() { return static_cast<GEPaletteFormat>(clutformat & 3); }
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; }
bool isLightChanEnabled(int chan) const { return lightEnable[chan] & 1; }
GELightComputation getLightComputation(int chan) const { return static_cast<GELightComputation>(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; }
GELightType getLightType(int chan) const { return static_cast<GELightType>((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; }
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 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 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

View file

@ -340,7 +340,7 @@ enum GEComparison
enum GELightType
{
GE_LIGHTTYPE_DIRECTIONAL=0,
GE_LIGHTTYPE_DIRECTIONAL = 0,
GE_LIGHTTYPE_POINT = 1,
GE_LIGHTTYPE_SPOT = 2
};