Add runtime checks to make sure we aren't overoptimizing the pixel shader cache.

This commit is contained in:
NeoBrainX 2011-09-07 20:20:29 +02:00
parent 4702de591e
commit 3939f9595a
5 changed files with 68 additions and 26 deletions

View File

@ -53,7 +53,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...)
{
// Read message and write it to the log
std::string caption;
char buffer[2048];
char buffer[4096];
static std::string info_caption;
static std::string warn_caption;
@ -86,7 +86,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...)
va_list args;
va_start(args, format);
CharArrayFromFormatV(buffer, 2047, str_translator(format).c_str(), args);
CharArrayFromFormatV(buffer, sizeof(buffer)-1, str_translator(format).c_str(), args);
va_end(args);
ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer);

View File

@ -172,13 +172,13 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode)
if (alphaPreTest == 0 || alphaPreTest == 2)
{
ptr[0] |= bpmem.fog.c_proj_fsel.fsel; // 3
ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 8; // 3
if (DepthTextureEnable)
{
ptr[0] |= bpmem.ztex2.op << 3; // 2
ptr[0] |= bpmem.zcontrol.zcomploc << 5; // 1
ptr[0] |= bpmem.zmode.testenable << 6; // 1
ptr[0] |= bpmem.zmode.updateenable << 7; // 1
ptr[0] |= bpmem.ztex2.op << 11; // 2
ptr[0] |= bpmem.zcontrol.zcomploc << 13; // 1
ptr[0] |= bpmem.zmode.testenable << 14; // 1
ptr[0] |= bpmem.zmode.updateenable << 15; // 1
}
}
@ -186,8 +186,8 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode)
{
if (bpmem.fog.c_proj_fsel.fsel != 0)
{
ptr[0] |= bpmem.fog.c_proj_fsel.proj << 8; // 1
ptr[0] |= bpmem.fogRange.Base.Enabled << 9; // 1
ptr[0] |= bpmem.fog.c_proj_fsel.proj << 16; // 1
ptr[0] |= bpmem.fogRange.Base.Enabled << 17; // 1
}
}
uid->tevstages = (ptr+1) - uid->values;
@ -318,14 +318,14 @@ void _GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode)
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode)
{
u32* ptr = uid->values;
*ptr++ = dstAlphaMode;
*ptr++ = bpmem.genMode.hex;
*ptr++ = bpmem.ztex2.hex;
*ptr++ = bpmem.zcontrol.hex;
*ptr++ = bpmem.zmode.hex;
*ptr++ = g_ActiveConfig.bEnablePerPixelDepth;
*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
*ptr++ = xfregs.numTexGen.hex;
*ptr++ = dstAlphaMode; // 0
*ptr++ = bpmem.genMode.hex; // 1
*ptr++ = bpmem.ztex2.hex; // 2
*ptr++ = bpmem.zcontrol.hex; // 3
*ptr++ = bpmem.zmode.hex; // 4
*ptr++ = g_ActiveConfig.bEnablePerPixelDepth; // 5
*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 6
*ptr++ = xfregs.numTexGen.hex; // 7
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
@ -333,25 +333,28 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode)
}
for (unsigned int i = 0; i < 8; ++i)
*ptr++ = xfregs.texMtxInfo[i].hex;
*ptr++ = xfregs.texMtxInfo[i].hex; // 8-15
for (unsigned int i = 0; i < 16; ++i)
*ptr++ = bpmem.tevind[i].hex;
*ptr++ = bpmem.tevind[i].hex; // 16-31
*ptr++ = bpmem.tevindref.hex;
*ptr++ = bpmem.tevindref.hex; // 32
for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i)
for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times
{
// TODO ...
StageHash(i, ptr);
ptr += 4; // max: ptr = &uid->values[66]
ptr += 4; // max: ptr = &uid->values[33+63]
}
*ptr++ = bpmem.fog.c_proj_fsel.hex;
ptr = &uid->values[97];
*ptr++ = bpmem.fogRange.Base.hex;
*ptr++ = bpmem.alphaFunc.hex; // 97
_assert_((ptr - uid->values) == uid->GetNumValues());
*ptr++ = bpmem.fog.c_proj_fsel.hex; // 98
*ptr++ = bpmem.fogRange.Base.hex; // 99
_assert_((ptr - uid->values) <= uid->GetNumValues());
}

View File

@ -119,6 +119,8 @@ enum DSTALPHA_MODE
};
const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components);
// TODO: Wtf, those need components as well! -.-
void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode);
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode);

View File

@ -184,12 +184,30 @@ void PixelShaderCache::Shutdown()
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
{
PIXELSHADERUID uid;
PIXELSHADERUIDSAFE safe_uid;
GetPixelShaderId(&uid, dstAlphaMode);
GetSafePixelShaderId(&safe_uid, dstAlphaMode);
// Check if the shader is already set
// Check if the shader is already set - TODO: Use pShaderLast instead of PixelShaders[uid]?
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
{
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
if (!(safe_uid == PixelShaders[uid].safe_uid))
{
std::string code(GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components));
if (code != PixelShaders[uid].code)
{
char msg[4096];
char* ptr = msg;
ptr += sprintf(ptr, "Mismatch!\nUnique IDs:\n");
for (int i = 0; i < PixelShaders[uid].safe_uid.GetNumValues()/2; ++i)
ptr += sprintf(ptr, "%02d, %08X %08X | %08X %08X\n", 2*i, PixelShaders[uid].safe_uid.values[2*i], PixelShaders[uid].safe_uid.values[2*i+1],
safe_uid.values[2*i], safe_uid.values[2*i+1]);
PanicAlert(msg);
}
}
return pShaderLast;
}
@ -207,14 +225,31 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp
}
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
if (!(safe_uid == entry.safe_uid))
{
std::string code(GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components));
if (code != entry.code)
{
char msg[4096];
char *ptr = msg;
ptr += sprintf(ptr, "Mismatch!\nUnique IDs:\n");
for (int i = 0; i < entry.safe_uid.GetNumValues()/2; ++i)
ptr += sprintf(ptr, "%02d\t%08X %08X | %08X %08X\n", 2*i, entry.safe_uid.values[2*i], entry.safe_uid.values[2*i+1],
safe_uid.values[2*i], safe_uid.values[2*i+1]);
PanicAlert(msg);
}
}
return pShaderLast;
}
// Make an entry in the table
PSCacheEntry& newentry = PixelShaders[uid];
newentry.frameCount = frameCount;
newentry.safe_uid = safe_uid;
pShaderLast = &newentry.shader;
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
newentry.code = code;
#if defined(_DEBUG) || defined(DEBUGFAST)
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {

View File

@ -56,6 +56,8 @@ class PixelShaderCache
{
shader.Destroy();
}
PIXELSHADERUIDSAFE safe_uid;
std::string code;
};
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;