Add runtime checks to make sure we aren't overoptimizing the pixel shader cache.
This commit is contained in:
parent
4702de591e
commit
3939f9595a
|
@ -53,7 +53,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...)
|
||||||
{
|
{
|
||||||
// Read message and write it to the log
|
// Read message and write it to the log
|
||||||
std::string caption;
|
std::string caption;
|
||||||
char buffer[2048];
|
char buffer[4096];
|
||||||
|
|
||||||
static std::string info_caption;
|
static std::string info_caption;
|
||||||
static std::string warn_caption;
|
static std::string warn_caption;
|
||||||
|
@ -86,7 +86,7 @@ bool MsgAlert(bool yes_no, int Style, const char* format, ...)
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
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);
|
va_end(args);
|
||||||
|
|
||||||
ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer);
|
ERROR_LOG(MASTER_LOG, "%s: %s", caption.c_str(), buffer);
|
||||||
|
|
|
@ -172,13 +172,13 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode)
|
||||||
|
|
||||||
if (alphaPreTest == 0 || alphaPreTest == 2)
|
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)
|
if (DepthTextureEnable)
|
||||||
{
|
{
|
||||||
ptr[0] |= bpmem.ztex2.op << 3; // 2
|
ptr[0] |= bpmem.ztex2.op << 11; // 2
|
||||||
ptr[0] |= bpmem.zcontrol.zcomploc << 5; // 1
|
ptr[0] |= bpmem.zcontrol.zcomploc << 13; // 1
|
||||||
ptr[0] |= bpmem.zmode.testenable << 6; // 1
|
ptr[0] |= bpmem.zmode.testenable << 14; // 1
|
||||||
ptr[0] |= bpmem.zmode.updateenable << 7; // 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)
|
if (bpmem.fog.c_proj_fsel.fsel != 0)
|
||||||
{
|
{
|
||||||
ptr[0] |= bpmem.fog.c_proj_fsel.proj << 8; // 1
|
ptr[0] |= bpmem.fog.c_proj_fsel.proj << 16; // 1
|
||||||
ptr[0] |= bpmem.fogRange.Base.Enabled << 9; // 1
|
ptr[0] |= bpmem.fogRange.Base.Enabled << 17; // 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uid->tevstages = (ptr+1) - uid->values;
|
uid->tevstages = (ptr+1) - uid->values;
|
||||||
|
@ -318,14 +318,14 @@ void _GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode)
|
||||||
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode)
|
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode)
|
||||||
{
|
{
|
||||||
u32* ptr = uid->values;
|
u32* ptr = uid->values;
|
||||||
*ptr++ = dstAlphaMode;
|
*ptr++ = dstAlphaMode; // 0
|
||||||
*ptr++ = bpmem.genMode.hex;
|
*ptr++ = bpmem.genMode.hex; // 1
|
||||||
*ptr++ = bpmem.ztex2.hex;
|
*ptr++ = bpmem.ztex2.hex; // 2
|
||||||
*ptr++ = bpmem.zcontrol.hex;
|
*ptr++ = bpmem.zcontrol.hex; // 3
|
||||||
*ptr++ = bpmem.zmode.hex;
|
*ptr++ = bpmem.zmode.hex; // 4
|
||||||
*ptr++ = g_ActiveConfig.bEnablePerPixelDepth;
|
*ptr++ = g_ActiveConfig.bEnablePerPixelDepth; // 5
|
||||||
*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
|
*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 6
|
||||||
*ptr++ = xfregs.numTexGen.hex;
|
*ptr++ = xfregs.numTexGen.hex; // 7
|
||||||
|
|
||||||
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
|
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)
|
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)
|
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 ...
|
// TODO ...
|
||||||
StageHash(i, ptr);
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,8 @@ enum DSTALPHA_MODE
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components);
|
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 GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode);
|
||||||
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode);
|
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode);
|
||||||
|
|
||||||
|
|
|
@ -184,12 +184,30 @@ void PixelShaderCache::Shutdown()
|
||||||
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
|
||||||
{
|
{
|
||||||
PIXELSHADERUID uid;
|
PIXELSHADERUID uid;
|
||||||
|
PIXELSHADERUIDSAFE safe_uid;
|
||||||
GetPixelShaderId(&uid, dstAlphaMode);
|
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)
|
if (uid == last_pixel_shader_uid && PixelShaders[uid].frameCount == frameCount)
|
||||||
{
|
{
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
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;
|
return pShaderLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,14 +225,31 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp
|
||||||
}
|
}
|
||||||
|
|
||||||
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
|
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;
|
return pShaderLast;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make an entry in the table
|
// Make an entry in the table
|
||||||
PSCacheEntry& newentry = PixelShaders[uid];
|
PSCacheEntry& newentry = PixelShaders[uid];
|
||||||
newentry.frameCount = frameCount;
|
newentry.frameCount = frameCount;
|
||||||
|
newentry.safe_uid = safe_uid;
|
||||||
pShaderLast = &newentry.shader;
|
pShaderLast = &newentry.shader;
|
||||||
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
|
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components);
|
||||||
|
newentry.code = code;
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
if (g_ActiveConfig.iLog & CONF_SAVESHADERS && code) {
|
||||||
|
|
|
@ -56,6 +56,8 @@ class PixelShaderCache
|
||||||
{
|
{
|
||||||
shader.Destroy();
|
shader.Destroy();
|
||||||
}
|
}
|
||||||
|
PIXELSHADERUIDSAFE safe_uid;
|
||||||
|
std::string code;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
typedef std::map<PIXELSHADERUID, PSCacheEntry> PSCache;
|
||||||
|
|
Loading…
Reference in New Issue