mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Skipped the ZCompLoc pass if the result can be determined at compile time. Brings back the speed lost by r146b02615c07.
This commit is contained in:
@ -26,8 +26,7 @@
|
|||||||
#include "BPMemory.h"
|
#include "BPMemory.h"
|
||||||
#include "VideoConfig.h"
|
#include "VideoConfig.h"
|
||||||
#include "NativeVertexFormat.h"
|
#include "NativeVertexFormat.h"
|
||||||
|
#include "PixelShaderManager.h"
|
||||||
static ALPHA_PRETEST_RESULT AlphaPreTest();
|
|
||||||
|
|
||||||
static void StageHash(int stage, u32* out)
|
static void StageHash(int stage, u32* out)
|
||||||
{
|
{
|
||||||
@ -117,7 +116,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, PSGRENDER_MODE PSGRenderMode, u32 com
|
|||||||
uid->values[0] |= MustWriteToDepth << 11; // 1
|
uid->values[0] |= MustWriteToDepth << 11; // 1
|
||||||
uid->values[0] |= PixelLightingEnabled << 12; // 1
|
uid->values[0] |= PixelLightingEnabled << 12; // 1
|
||||||
if (!PixelLightingEnabled) uid->values[0] |= xfregs.numTexGen.numTexGens << 13; // 4
|
if (!PixelLightingEnabled) uid->values[0] |= xfregs.numTexGen.numTexGens << 13; // 4
|
||||||
ALPHA_PRETEST_RESULT alphaPreTest = AlphaPreTest();
|
ALPHA_PRETEST_RESULT alphaPreTest = PixelShaderManager::AlphaPreTest();
|
||||||
uid->values[0] |= ((u32)alphaPreTest) << 17; // 2
|
uid->values[0] |= ((u32)alphaPreTest) << 17; // 2
|
||||||
uid->values[0] |= ZCompLocEnabled << 18; // 2
|
uid->values[0] |= ZCompLocEnabled << 18; // 2
|
||||||
if (((alphaPreTest == ALPHAPT_ALWAYSFAIL) || (alphaPreTest == ALPHAPT_ALWAYSPASS && PSGRenderMode == PSGRENDER_DSTALPHA_ALPHA_PASS)) && !DepthTextureEnable)
|
if (((alphaPreTest == ALPHAPT_ALWAYSFAIL) || (alphaPreTest == ALPHAPT_ALWAYSPASS && PSGRenderMode == PSGRENDER_DSTALPHA_ALPHA_PASS)) && !DepthTextureEnable)
|
||||||
@ -636,7 +635,7 @@ const char *GeneratePixelShaderCode(PSGRENDER_MODE PSGRenderMode, API_TYPE ApiTy
|
|||||||
WRITE(p, "float zCoord = " I_ZBIAS "[1].x + (uv2.w / uv3.w) * " I_ZBIAS "[1].y;\n");
|
WRITE(p, "float zCoord = " I_ZBIAS "[1].x + (uv2.w / uv3.w) * " I_ZBIAS "[1].y;\n");
|
||||||
}
|
}
|
||||||
char* pmainstart = p;
|
char* pmainstart = p;
|
||||||
if(PSGRenderMode == PSGRENDER_ZCOMPLOCK && !DepthTextureEnable)
|
if(PSGRenderMode == PSGRENDER_ZCOMPLOC && !DepthTextureEnable)
|
||||||
{
|
{
|
||||||
// Within ZCompLoc pass, make this an empty function
|
// Within ZCompLoc pass, make this an empty function
|
||||||
WRITE(p, "ocol0 = 0;\n");
|
WRITE(p, "ocol0 = 0;\n");
|
||||||
@ -646,7 +645,7 @@ const char *GeneratePixelShaderCode(PSGRENDER_MODE PSGRenderMode, API_TYPE ApiTy
|
|||||||
WRITE(p, "}\n");
|
WRITE(p, "}\n");
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
ALPHA_PRETEST_RESULT Pretest = AlphaPreTest();
|
ALPHA_PRETEST_RESULT Pretest = PixelShaderManager::AlphaPreTest();
|
||||||
// Test if we can predict the alpha test result or if we are in depth only mode
|
// Test if we can predict the alpha test result or if we are in depth only mode
|
||||||
if((Pretest != ALPHAPT_UNDEFINED) && !DepthTextureEnable)
|
if((Pretest != ALPHAPT_UNDEFINED) && !DepthTextureEnable)
|
||||||
{
|
{
|
||||||
@ -1169,39 +1168,6 @@ static const char *tevAlphaFunclogicTable[] =
|
|||||||
" != ", // xor
|
" != ", // xor
|
||||||
" == " // xnor
|
" == " // xnor
|
||||||
};
|
};
|
||||||
static ALPHA_PRETEST_RESULT AlphaPreTest()
|
|
||||||
{
|
|
||||||
u32 op = bpmem.alphaFunc.logic;
|
|
||||||
u32 comp[2] = {bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1};
|
|
||||||
|
|
||||||
// First kill all the simple cases
|
|
||||||
switch(op)
|
|
||||||
{
|
|
||||||
case 0: // AND
|
|
||||||
if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) return ALPHAPT_ALWAYSPASS;
|
|
||||||
if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER) return ALPHAPT_ALWAYSFAIL;
|
|
||||||
break;
|
|
||||||
case 1: // OR
|
|
||||||
if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS) return ALPHAPT_ALWAYSPASS;
|
|
||||||
if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)return ALPHAPT_ALWAYSFAIL;
|
|
||||||
break;
|
|
||||||
case 2: // XOR
|
|
||||||
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
|
|
||||||
return ALPHAPT_ALWAYSPASS;
|
|
||||||
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
|
|
||||||
return ALPHAPT_ALWAYSFAIL;
|
|
||||||
break;
|
|
||||||
case 3: // XNOR
|
|
||||||
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
|
|
||||||
return ALPHAPT_ALWAYSFAIL;
|
|
||||||
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
|
|
||||||
return ALPHAPT_ALWAYSPASS;
|
|
||||||
break;
|
|
||||||
default: PanicAlert("bad logic for alpha test? %08x", op);
|
|
||||||
}
|
|
||||||
return ALPHAPT_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void WriteAlphaTest(char *&p, API_TYPE ApiType,PSGRENDER_MODE PSGRenderMode)
|
static void WriteAlphaTest(char *&p, API_TYPE ApiType,PSGRENDER_MODE PSGRenderMode)
|
||||||
{
|
{
|
||||||
|
@ -111,7 +111,7 @@ enum PSGRENDER_MODE
|
|||||||
PSGRENDER_NORMAL, // Render normally, without destination alpha
|
PSGRENDER_NORMAL, // Render normally, without destination alpha
|
||||||
PSGRENDER_DSTALPHA_ALPHA_PASS, // Render normally first, then render again for alpha
|
PSGRENDER_DSTALPHA_ALPHA_PASS, // Render normally first, then render again for alpha
|
||||||
PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND, // Use dual-source blending
|
PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND, // Use dual-source blending
|
||||||
PSGRENDER_ZCOMPLOCK //Render to Depth Channel only with no depth dextures enabled
|
PSGRENDER_ZCOMPLOC //Render to Depth Channel only with no depth dextures enabled
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ALPHA_PRETEST_RESULT
|
enum ALPHA_PRETEST_RESULT
|
||||||
|
@ -466,6 +466,39 @@ void PixelShaderManager::SetMaterialColorChanged(int index)
|
|||||||
nMaterialsChanged |= (1 << index);
|
nMaterialsChanged |= (1 << index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALPHA_PRETEST_RESULT PixelShaderManager::AlphaPreTest()
|
||||||
|
{
|
||||||
|
u32 op = bpmem.alphaFunc.logic;
|
||||||
|
u32 comp[2] = {bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1};
|
||||||
|
|
||||||
|
// First kill all the simple cases
|
||||||
|
switch(op)
|
||||||
|
{
|
||||||
|
case 0: // AND
|
||||||
|
if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) return ALPHAPT_ALWAYSPASS;
|
||||||
|
if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER) return ALPHAPT_ALWAYSFAIL;
|
||||||
|
break;
|
||||||
|
case 1: // OR
|
||||||
|
if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS) return ALPHAPT_ALWAYSPASS;
|
||||||
|
if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)return ALPHAPT_ALWAYSFAIL;
|
||||||
|
break;
|
||||||
|
case 2: // XOR
|
||||||
|
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
|
||||||
|
return ALPHAPT_ALWAYSPASS;
|
||||||
|
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
|
||||||
|
return ALPHAPT_ALWAYSFAIL;
|
||||||
|
break;
|
||||||
|
case 3: // XNOR
|
||||||
|
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
|
||||||
|
return ALPHAPT_ALWAYSFAIL;
|
||||||
|
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
|
||||||
|
return ALPHAPT_ALWAYSPASS;
|
||||||
|
break;
|
||||||
|
default: PanicAlert("bad logic for alpha test? %08x", op);
|
||||||
|
}
|
||||||
|
return ALPHAPT_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
void PixelShaderManager::DoState(PointerWrap &p)
|
void PixelShaderManager::DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
p.Do(lastRGBAfull);
|
p.Do(lastRGBAfull);
|
||||||
|
@ -54,6 +54,7 @@ public:
|
|||||||
static void SetColorMatrix(const float* pmatrix);
|
static void SetColorMatrix(const float* pmatrix);
|
||||||
static void InvalidateXFRange(int start, int end);
|
static void InvalidateXFRange(int start, int end);
|
||||||
static void SetMaterialColorChanged(int index);
|
static void SetMaterialColorChanged(int index);
|
||||||
|
static ALPHA_PRETEST_RESULT AlphaPreTest();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,9 +187,9 @@ void VertexManager::vFlush()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool useZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable;
|
bool useZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable;
|
||||||
if(useZcomploc)
|
if (useZcomploc && PixelShaderManager::AlphaPreTest() == ALPHAPT_UNDEFINED)
|
||||||
{
|
{
|
||||||
if (!PixelShaderCache::SetShader(PSGRENDER_ZCOMPLOCK, g_nativeVertexFmt->m_components))
|
if (!PixelShaderCache::SetShader(PSGRENDER_ZCOMPLOC, g_nativeVertexFmt->m_components))
|
||||||
{
|
{
|
||||||
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||||
goto shader_fail;
|
goto shader_fail;
|
||||||
|
@ -220,9 +220,9 @@ void VertexManager::vFlush()
|
|||||||
g_renderer->RestoreState();
|
g_renderer->RestoreState();
|
||||||
}
|
}
|
||||||
bool useZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable;
|
bool useZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable;
|
||||||
if (useZcomploc)
|
if (useZcomploc && PixelShaderManager::AlphaPreTest() == ALPHAPT_UNDEFINED)
|
||||||
{
|
{
|
||||||
ps = PixelShaderCache::SetShader(PSGRENDER_ZCOMPLOCK,g_nativeVertexFmt->m_components);
|
ps = PixelShaderCache::SetShader(PSGRENDER_ZCOMPLOC,g_nativeVertexFmt->m_components);
|
||||||
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
|
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
|
||||||
|
|
||||||
g_renderer->ApplyState(RSM_Zcomploc);
|
g_renderer->ApplyState(RSM_Zcomploc);
|
||||||
|
Reference in New Issue
Block a user