Merge rodolfoosvaldobogado's zcomploc code (Graphic_Fixes branch)

This commit is contained in:
skidau 2012-05-26 13:47:07 +10:00
commit 146b02615c
20 changed files with 319 additions and 176 deletions

View File

@ -24,7 +24,7 @@
// Increment this every time you change shader generation code. // Increment this every time you change shader generation code.
enum enum
{ {
LINEAR_DISKCACHE_VER = 6975 LINEAR_DISKCACHE_VER = 6979
}; };
// On disk format: // On disk format:

View File

@ -103,21 +103,21 @@ void GFXDebuggerBase::DumpPixelShader(const char* path)
if (!useDstAlpha) if (!useDstAlpha)
{ {
output = "Destination alpha disabled:\n"; output = "Destination alpha disabled:\n";
output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); output += GeneratePixelShaderCode(PSGRENDER_NORMAL, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
} }
else else
{ {
if(g_ActiveConfig.backend_info.bSupportsDualSourceBlend) if(g_ActiveConfig.backend_info.bSupportsDualSourceBlend)
{ {
output = "Using dual source blending for destination alpha:\n"; output = "Using dual source blending for destination alpha:\n";
output += GeneratePixelShaderCode(DSTALPHA_DUAL_SOURCE_BLEND, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); output += GeneratePixelShaderCode(PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
} }
else else
{ {
output = "Using two passes for emulating destination alpha:\n"; output = "Using two passes for emulating destination alpha:\n";
output += GeneratePixelShaderCode(DSTALPHA_NONE, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); output += GeneratePixelShaderCode(PSGRENDER_NORMAL, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
output += "\n\nDestination alpha pass shader:\n"; output += "\n\nDestination alpha pass shader:\n";
output += GeneratePixelShaderCode(DSTALPHA_ALPHA_PASS, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components); output += GeneratePixelShaderCode(PSGRENDER_DSTALPHA_ALPHA_PASS, g_ActiveConfig.backend_info.APIType, g_nativeVertexFmt->m_components);
} }
} }

View File

@ -27,7 +27,7 @@
#include "VideoConfig.h" #include "VideoConfig.h"
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
static int AlphaPreTest(); static ALPHA_PRETEST_RESULT AlphaPreTest();
static void StageHash(int stage, u32* out) static void StageHash(int stage, u32* out)
{ {
@ -102,26 +102,25 @@ static void StageHash(int stage, u32* out)
// a unique identifier, basically containing all the bits. Yup, it's a lot .... // a unique identifier, basically containing all the bits. Yup, it's a lot ....
// It would likely be a lot more efficient to build this incrementally as the attributes // It would likely be a lot more efficient to build this incrementally as the attributes
// are set... // are set...
void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 components) void GetPixelShaderId(PIXELSHADERUID *uid, PSGRENDER_MODE PSGRenderMode, u32 components)
{ {
memset(uid->values, 0, sizeof(uid->values)); memset(uid->values, 0, sizeof(uid->values));
uid->values[0] |= bpmem.genMode.numtevstages; // 4 uid->values[0] |= bpmem.genMode.numtevstages; // 4
uid->values[0] |= bpmem.genMode.numtexgens << 4; // 4 uid->values[0] |= bpmem.genMode.numtexgens << 4; // 4
uid->values[0] |= dstAlphaMode << 8; // 2 uid->values[0] |= ((u32)PSGRenderMode) << 8; // 2
bool PixelLigthingEnabled = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
bool DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth; bool DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && (bpmem.zmode.testenable || bpmem.zmode.updateenable));
bool MustWriteToDepth = DepthTextureEnable || g_ActiveConfig.bEnablePerPixelDepth;
bool FastZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable && false;
uid->values[0] |= DepthTextureEnable << 10; // 1 uid->values[0] |= DepthTextureEnable << 10; // 1
uid->values[0] |= MustWriteToDepth << 11; // 1
bool enablePL = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; uid->values[0] |= PixelLigthingEnabled << 12; // 1
uid->values[0] |= enablePL << 11; // 1 if (!PixelLigthingEnabled) uid->values[0] |= xfregs.numTexGen.numTexGens << 13; // 4
ALPHA_PRETEST_RESULT alphaPreTest = AlphaPreTest();
if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 12; // 4 uid->values[0] |= ((u32)alphaPreTest) << 17; // 2
u32 alphaPreTest = AlphaPreTest()+1; uid->values[0] |= FastZcomploc << 18; // 2
if (((alphaPreTest == ALPHAPT_ALWAYSFAIL) || (alphaPreTest == ALPHAPT_ALWAYSPASS && PSGRenderMode == PSGRENDER_DSTALPHA_ALPHA_PASS)) && !DepthTextureEnable)
uid->values[0] |= alphaPreTest << 16; // 2
if (alphaPreTest == 1 || (alphaPreTest && !DepthTextureEnable && dstAlphaMode == DSTALPHA_ALPHA_PASS))
{ {
// Courtesy of PreAlphaTest, we're done already ;) // Courtesy of PreAlphaTest, we're done already ;)
// NOTE: The comment header of generated shaders depends on the value of bpmem.genmode.numindstages.. shouldnt really bother about that though. // NOTE: The comment header of generated shaders depends on the value of bpmem.genmode.numindstages.. shouldnt really bother about that though.
@ -131,13 +130,13 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i)
{ {
if (18+i < 32) if (19+i < 32)
uid->values[0] |= xfregs.texMtxInfo[i].projection << (18+i); // 1 uid->values[0] |= xfregs.texMtxInfo[i].projection << (19+i); // 1
else else
uid->values[1] |= xfregs.texMtxInfo[i].projection << (i - 14); // 1 uid->values[1] |= xfregs.texMtxInfo[i].projection << (i - 13); // 1
} }
uid->values[1] = bpmem.genMode.numindstages << 2; // 3 uid->values[1] = bpmem.genMode.numindstages << 3; // 3
u32 indirectStagesUsed = 0; u32 indirectStagesUsed = 0;
for (unsigned int i = 0; i < bpmem.genMode.numindstages; ++i) for (unsigned int i = 0; i < bpmem.genMode.numindstages; ++i)
if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages) if (bpmem.tevind[i].IsActive() && bpmem.tevind[i].bt < bpmem.genMode.numindstages)
@ -145,13 +144,13 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
assert(indirectStagesUsed == (indirectStagesUsed & 0xF)); assert(indirectStagesUsed == (indirectStagesUsed & 0xF));
uid->values[1] |= indirectStagesUsed << 5; // 4; uid->values[1] |= indirectStagesUsed << 6; // 4;
for (unsigned int i = 0; i < bpmem.genMode.numindstages; ++i) for (unsigned int i = 0; i < bpmem.genMode.numindstages; ++i)
{ {
if (indirectStagesUsed & (1 << i)) if (indirectStagesUsed & (1 << i))
{ {
uid->values[1] |= (bpmem.tevindref.getTexCoord(i) < bpmem.genMode.numtexgens) << (9 + 3*i); // 1 uid->values[1] |= (bpmem.tevindref.getTexCoord(i) < bpmem.genMode.numtexgens) << (10 + 3*i); // 1
if (bpmem.tevindref.getTexCoord(i) < bpmem.genMode.numtexgens) if (bpmem.tevindref.getTexCoord(i) < bpmem.genMode.numtexgens)
uid->values[1] |= bpmem.tevindref.getTexCoord(i) << (10 + 3*i); // 2 uid->values[1] |= bpmem.tevindref.getTexCoord(i) << (10 + 3*i); // 2
} }
@ -180,7 +179,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
} }
} }
if (dstAlphaMode != DSTALPHA_ALPHA_PASS) if (PSGRenderMode != PSGRENDER_DSTALPHA_ALPHA_PASS)
{ {
if (bpmem.fog.c_proj_fsel.fsel != 0) if (bpmem.fog.c_proj_fsel.fsel != 0)
{ {
@ -190,7 +189,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
} }
++ptr; ++ptr;
if (enablePL) if (PixelLigthingEnabled)
{ {
ptr += GetLightingShaderId(ptr); ptr += GetLightingShaderId(ptr);
*ptr++ = components; *ptr++ = components;
@ -199,20 +198,26 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
uid->num_values = ptr - uid->values; uid->num_values = ptr - uid->values;
} }
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components) void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, PSGRENDER_MODE PSGRenderMode, u32 components)
{ {
memset(uid->values, 0, sizeof(uid->values)); memset(uid->values, 0, sizeof(uid->values));
bool PixelLigthingEnabled = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
bool DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && (bpmem.zmode.testenable || bpmem.zmode.updateenable));
bool MustWriteToDepth = DepthTextureEnable || g_ActiveConfig.bEnablePerPixelDepth;
bool FastZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable && false;
u32* ptr = uid->values; u32* ptr = uid->values;
*ptr++ = dstAlphaMode; // 0 *ptr++ = ((u32)PSGRenderMode); // 0
*ptr++ = bpmem.genMode.hex; // 1 *ptr++ = bpmem.genMode.hex; // 1
*ptr++ = bpmem.ztex2.hex; // 2 *ptr++ = bpmem.ztex2.hex; // 2
*ptr++ = bpmem.zcontrol.hex; // 3 *ptr++ = bpmem.zcontrol.hex; // 3
*ptr++ = bpmem.zmode.hex; // 4 *ptr++ = bpmem.zmode.hex; // 4
*ptr++ = g_ActiveConfig.bEnablePerPixelDepth; // 5 *ptr++ = MustWriteToDepth; // 5
*ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 6 *ptr++ = PixelLigthingEnabled; // 6
*ptr++ = xfregs.numTexGen.hex; // 7 *ptr++ = xfregs.numTexGen.hex; // 7
*ptr++ = DepthTextureEnable; // 8
*ptr++ = FastZcomploc; // 9
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) if (PixelLigthingEnabled)
{ {
*ptr++ = xfregs.color[0].hex; *ptr++ = xfregs.color[0].hex;
*ptr++ = xfregs.alpha[0].hex; *ptr++ = xfregs.alpha[0].hex;
@ -222,43 +227,43 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u
} }
for (unsigned int i = 0; i < 8; ++i) for (unsigned int i = 0; i < 8; ++i)
*ptr++ = xfregs.texMtxInfo[i].hex; // 8-15 *ptr++ = xfregs.texMtxInfo[i].hex; // 9-17
for (unsigned int i = 0; i < 16; ++i) for (unsigned int i = 0; i < 16; ++i)
*ptr++ = bpmem.tevind[i].hex; // 16-31 *ptr++ = bpmem.tevind[i].hex; // 18-33
*ptr++ = bpmem.tevindref.hex; // 32 *ptr++ = bpmem.tevindref.hex; // 34
for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times
{ {
*ptr++ = bpmem.combiners[i].colorC.hex; // 33+5*i *ptr++ = bpmem.combiners[i].colorC.hex; // 35+5*i
*ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i *ptr++ = bpmem.combiners[i].alphaC.hex; // 36+5*i
*ptr++ = bpmem.tevind[i].hex; // 35+5*i *ptr++ = bpmem.tevind[i].hex; // 37+5*i
*ptr++ = bpmem.tevksel[i/2].hex; // 36+5*i *ptr++ = bpmem.tevksel[i/2].hex; // 38+5*i
*ptr++ = bpmem.tevorders[i/2].hex; // 37+5*i *ptr++ = bpmem.tevorders[i/2].hex; // 39+5*i
} }
ptr = &uid->values[113]; ptr = &uid->values[115];
*ptr++ = bpmem.alphaFunc.hex; // 113 *ptr++ = bpmem.alphaFunc.hex; // 116
*ptr++ = bpmem.fog.c_proj_fsel.hex; // 114 *ptr++ = bpmem.fog.c_proj_fsel.hex; // 117
*ptr++ = bpmem.fogRange.Base.hex; // 115 *ptr++ = bpmem.fogRange.Base.hex; // 118
_assert_((ptr - uid->values) == uid->GetNumValues()); _assert_((ptr - uid->values) == uid->GetNumValues());
} }
void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::string& old_code, DSTALPHA_MODE dstAlphaMode, u32 components) void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::string& old_code, PSGRENDER_MODE PSGRenderMode, u32 components)
{ {
if (!g_ActiveConfig.bEnableShaderDebugging) if (!g_ActiveConfig.bEnableShaderDebugging)
return; return;
PIXELSHADERUIDSAFE new_id; PIXELSHADERUIDSAFE new_id;
GetSafePixelShaderId(&new_id, dstAlphaMode, components); GetSafePixelShaderId(&new_id, PSGRenderMode, components);
if (!(old_id == new_id)) if (!(old_id == new_id))
{ {
std::string new_code(GeneratePixelShaderCode(dstAlphaMode, api, components)); std::string new_code(GeneratePixelShaderCode(PSGRenderMode, api, components));
if (old_code != new_code) if (old_code != new_code)
{ {
_assert_(old_id.GetNumValues() == new_id.GetNumValues()); _assert_(old_id.GetNumValues() == new_id.GetNumValues());
@ -299,7 +304,7 @@ void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::
static void WriteStage(char *&p, int n, API_TYPE ApiType); static void WriteStage(char *&p, int n, API_TYPE ApiType);
static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType); static void SampleTexture(char *&p, const char *destination, const char *texcoords, const char *texswap, int texmap, API_TYPE ApiType);
// static void WriteAlphaCompare(char *&p, int num, int comp); // static void WriteAlphaCompare(char *&p, int num, int comp);
static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode); static void WriteAlphaTest(char *&p, API_TYPE ApiType,PSGRENDER_MODE PSGRenderMode);
static void WriteFog(char *&p); static void WriteFog(char *&p);
static const char *tevKSelTableC[] = // KCSEL static const char *tevKSelTableC[] = // KCSEL
@ -485,7 +490,10 @@ static const char *tevIndFmtScale[] = {"255.0f", "31.0f", "15.0f", "7.0f" };
static char swapModeTable[4][5]; static char swapModeTable[4][5];
static char text[16384]; static char text[16384];
static bool PixelLigthingEnabled;
static bool DepthTextureEnable; static bool DepthTextureEnable;
static bool MustWriteToDepth;
static bool FastZcomploc;
static void BuildSwapModeTable() static void BuildSwapModeTable()
{ {
@ -500,7 +508,7 @@ static void BuildSwapModeTable()
} }
} }
const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components) const char *GeneratePixelShaderCode(PSGRENDER_MODE PSGRenderMode, API_TYPE ApiType, u32 components)
{ {
setlocale(LC_NUMERIC, "C"); // Reset locale for compilation setlocale(LC_NUMERIC, "C"); // Reset locale for compilation
text[sizeof(text) - 1] = 0x7C; // canary text[sizeof(text) - 1] = 0x7C; // canary
@ -523,7 +531,10 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt;
} }
} }
DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth ; PixelLigthingEnabled = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && (bpmem.zmode.testenable || bpmem.zmode.updateenable));
MustWriteToDepth = DepthTextureEnable || g_ActiveConfig.bEnablePerPixelDepth;
FastZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable && false;
// Declare samplers // Declare samplers
if(ApiType != API_D3D11) if(ApiType != API_D3D11)
@ -565,7 +576,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, "uniform float4 " I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX); WRITE(p, "uniform float4 " I_INDTEXMTX"[6] : register(c%d);\n", C_INDTEXMTX);
WRITE(p, "uniform float4 " I_FOG"[3] : register(c%d);\n", C_FOG); WRITE(p, "uniform float4 " I_FOG"[3] : register(c%d);\n", C_FOG);
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) if(PixelLigthingEnabled)
{ {
WRITE(p,"typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n"); WRITE(p,"typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n");
WRITE(p,"typedef struct { Light lights[8]; } s_" I_PLIGHTS";\n"); WRITE(p,"typedef struct { Light lights[8]; } s_" I_PLIGHTS";\n");
@ -578,15 +589,15 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
if(ApiType != API_D3D11) if(ApiType != API_D3D11)
{ {
WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n", WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "", PSGRenderMode == PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "",
DepthTextureEnable ? "\n out float depth : DEPTH," : "", MustWriteToDepth ? "\n out float depth : DEPTH," : "",
ApiType & API_OPENGL ? "WPOS" : ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS"); ApiType & API_OPENGL ? "WPOS" : ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS");
} }
else else
{ {
WRITE(p, " out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n", WRITE(p, " out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "", PSGRenderMode == PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "",
DepthTextureEnable ? "\n out float depth : SV_Depth," : ""); MustWriteToDepth ? "\n out float depth : SV_Depth," : "");
} }
WRITE(p, " in float4 colors_0 : COLOR0,\n"); WRITE(p, " in float4 colors_0 : COLOR0,\n");
@ -598,46 +609,74 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
for (int i = 0; i < numTexgen; ++i) for (int i = 0; i < numTexgen; ++i)
WRITE(p, ",\n in float3 uv%d : TEXCOORD%d", i, i); WRITE(p, ",\n in float3 uv%d : TEXCOORD%d", i, i);
WRITE(p, ",\n in float4 clipPos : TEXCOORD%d", numTexgen); WRITE(p, ",\n in float4 clipPos : TEXCOORD%d", numTexgen);
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) if(PixelLigthingEnabled)
WRITE(p, ",\n in float4 Normal : TEXCOORD%d", numTexgen + 1); WRITE(p, ",\n in float4 Normal : TEXCOORD%d", numTexgen + 1);
} }
else else
{ {
// wpos is in w of first 4 texcoords // wpos is in w of first 4 texcoords
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) if(PixelLigthingEnabled)
{ {
for (int i = 0; i < 8; ++i) for (int i = 0; i < numTexgen; ++i)
WRITE(p, ",\n in float4 uv%d : TEXCOORD%d", i, i); WRITE(p, ",\n in float4 uv%d : TEXCOORD%d", i, i);
} }
else else
{ {
for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) for (unsigned int i = 0; i < numTexgen; ++i)
WRITE(p, ",\n in float%d uv%d : TEXCOORD%d", i < 4 ? 4 : 3 , i, i); WRITE(p, ",\n in float%d uv%d : TEXCOORD%d", i < 4 ? 4 : 3 , i, i);
} }
} }
WRITE(p, " ) {\n"); WRITE(p, " ) {\n");
if((bpmem.fog.c_proj_fsel.fsel != 0) || MustWriteToDepth)
{
// the screen space depth value = far z + (clip z / clip w) * z range
if (numTexgen < 7)
WRITE(p, "float zCoord = "I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * "I_ZBIAS"[1].y;\n");
else
WRITE(p, "float zCoord = "I_ZBIAS"[1].x + (uv2.w / uv3.w) * "I_ZBIAS"[1].y;\n");
}
char* pmainstart = p; char* pmainstart = p;
int Pretest = AlphaPreTest(); if(PSGRenderMode == PSGRENDER_ZCOMPLOCK && !DepthTextureEnable)
if(Pretest >= 0 && !DepthTextureEnable)
{ {
if (!Pretest) //we are in zcomlock pass, so just make this an empty function
{
// alpha test will always fail, so restart the shader and just make it an empty function
WRITE(p, "ocol0 = 0;\n"); WRITE(p, "ocol0 = 0;\n");
if(DepthTextureEnable) // only write to depth if shader Mode requeires it
WRITE(p, "depth = 1.f;\n"); if(MustWriteToDepth)
if(dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) WRITE(p, "depth = zCoord;\n");
WRITE(p, "}\n");
return text;
}
ALPHA_PRETEST_RESULT Pretest = AlphaPreTest();
//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_ALWAYSFAIL)
{
// alpha test will always fail, just make this an empty function
WRITE(p, "ocol0 = 0;\n");
// only write to depth if the shader mode requires it
if(MustWriteToDepth)
WRITE(p, "depth = zCoord;\n");
// if we are in dual source blend mode initialize the secondary color o the shader will fail
if(PSGRenderMode == PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND)
WRITE(p, "ocol1 = 0;\n"); WRITE(p, "ocol1 = 0;\n");
//No discard if zcomlock is enebled and we are using fast zcomploc
if(!FastZcomploc)
{
WRITE(p, "discard;\n"); WRITE(p, "discard;\n");
if(ApiType != API_D3D11) if(ApiType != API_D3D11)
WRITE(p, "return;\n"); WRITE(p, "return;\n");
} }
else if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
{
WRITE(p, " ocol0 = " I_ALPHA"[0].aaaa;\n");
} }
if(!Pretest || dstAlphaMode == DSTALPHA_ALPHA_PASS) else if (PSGRenderMode == PSGRENDER_DSTALPHA_ALPHA_PASS)
{
//write constant alpha value
WRITE(p, " ocol0 = " I_ALPHA"[0].aaaa;\n");
// only write to depth if the shader mode requires it
if(MustWriteToDepth)
WRITE(p, "depth = zCoord;\n");
}
if((Pretest == ALPHAPT_ALWAYSFAIL) || (PSGRenderMode == PSGRENDER_DSTALPHA_ALPHA_PASS))
{ {
WRITE(p, "}\n"); WRITE(p, "}\n");
return text; return text;
@ -653,9 +692,9 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
" float4 cc2=float4(0.0f,0.0f,0.0f,0.0f), cprev=float4(0.0f,0.0f,0.0f,0.0f);\n" " float4 cc2=float4(0.0f,0.0f,0.0f,0.0f), cprev=float4(0.0f,0.0f,0.0f,0.0f);\n"
" float4 crastemp=float4(0.0f,0.0f,0.0f,0.0f),ckonsttemp=float4(0.0f,0.0f,0.0f,0.0f);\n\n"); " float4 crastemp=float4(0.0f,0.0f,0.0f,0.0f),ckonsttemp=float4(0.0f,0.0f,0.0f,0.0f);\n\n");
if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) if(PixelLigthingEnabled)
{ {
if (xfregs.numTexGen.numTexGens < 7) if (numTexgen < 7)
{ {
WRITE(p,"float3 _norm0 = normalize(Normal.xyz);\n\n"); WRITE(p,"float3 _norm0 = normalize(Normal.xyz);\n\n");
WRITE(p,"float3 pos = float3(clipPos.x,clipPos.y,Normal.w);\n"); WRITE(p,"float3 pos = float3(clipPos.x,clipPos.y,Normal.w);\n");
@ -730,21 +769,10 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
// emulation of unsigned 8 overflow when casting // emulation of unsigned 8 overflow when casting
WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
if(Pretest == -1) if (MustWriteToDepth)
{
WriteAlphaTest(p, ApiType, dstAlphaMode);
}
if((bpmem.fog.c_proj_fsel.fsel != 0) || DepthTextureEnable)
{
// the screen space depth value = far z + (clip z / clip w) * z range
WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n");
}
if (DepthTextureEnable)
{ {
// use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format...
if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) if (DepthTextureEnable)
{ {
if (bpmem.ztex2.op == ZTEXTURE_ADD) if (bpmem.ztex2.op == ZTEXTURE_ADD)
WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w + zCoord;\n"); WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w + zCoord;\n");
@ -759,7 +787,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, "depth = zCoord;\n"); WRITE(p, "depth = zCoord;\n");
} }
if (dstAlphaMode == DSTALPHA_ALPHA_PASS) if (PSGRenderMode == PSGRENDER_DSTALPHA_ALPHA_PASS)
WRITE(p, " ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n"); WRITE(p, " ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n");
else else
{ {
@ -769,7 +797,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
// On D3D11, use dual-source color blending to perform dst alpha in a // On D3D11, use dual-source color blending to perform dst alpha in a
// single pass // single pass
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) if (PSGRenderMode == PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND)
{ {
// Colors will be blended against the alpha from ocol1... // Colors will be blended against the alpha from ocol1...
WRITE(p, " ocol1 = ocol0;\n"); WRITE(p, " ocol1 = ocol0;\n");
@ -777,6 +805,21 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, " ocol0.a = " I_ALPHA"[0].a;\n"); WRITE(p, " ocol0.a = " I_ALPHA"[0].a;\n");
} }
// Alpha test could fail here if depth texture is enabled
if (Pretest == ALPHAPT_ALWAYSFAIL)
{
if(!FastZcomploc)
{
WRITE(p, "discard;\n");
if(ApiType != API_D3D11)
WRITE(p, "return;\n");
}
}
else if(Pretest == ALPHAPT_UNDEFINED)
{
WriteAlphaTest(p, ApiType, PSGRenderMode);
}
WRITE(p, "}\n"); WRITE(p, "}\n");
if (text[sizeof(text) - 1] != 0x7C) if (text[sizeof(text) - 1] != 0x7C)
PanicAlert("PixelShader generator - buffer too small, canary has been eaten!"); PanicAlert("PixelShader generator - buffer too small, canary has been eaten!");
@ -1118,7 +1161,7 @@ static const char *tevAlphaFunclogicTable[] =
" != ", // xor " != ", // xor
" == " // xnor " == " // xnor
}; };
static int AlphaPreTest() static ALPHA_PRETEST_RESULT AlphaPreTest()
{ {
u32 op = bpmem.alphaFunc.logic; u32 op = bpmem.alphaFunc.logic;
u32 comp[2] = {bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1}; u32 comp[2] = {bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1};
@ -1127,32 +1170,32 @@ static int AlphaPreTest()
switch(op) switch(op)
{ {
case 0: // AND case 0: // AND
if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) return true; if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) return ALPHAPT_ALWAYSPASS;
if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER) return false; if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER) return ALPHAPT_ALWAYSFAIL;
break; break;
case 1: // OR case 1: // OR
if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS) return true; if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS) return ALPHAPT_ALWAYSPASS;
if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)return false; if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)return ALPHAPT_ALWAYSFAIL;
break; break;
case 2: // XOR case 2: // XOR
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS)) if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
return true; return ALPHAPT_ALWAYSPASS;
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
return false; return ALPHAPT_ALWAYSFAIL;
break; break;
case 3: // XNOR case 3: // XNOR
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS)) if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
return false; return ALPHAPT_ALWAYSFAIL;
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
return true; return ALPHAPT_ALWAYSPASS;
break; break;
default: PanicAlert("bad logic for alpha test? %08x", op); default: PanicAlert("bad logic for alpha test? %08x", op);
} }
return -1; return ALPHAPT_UNDEFINED;
} }
static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode) static void WriteAlphaTest(char *&p, API_TYPE ApiType,PSGRENDER_MODE PSGRenderMode)
{ {
static const char *alphaRef[2] = static const char *alphaRef[2] =
{ {
@ -1172,12 +1215,6 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table
WRITE(p, ")) {\n"); WRITE(p, ")) {\n");
WRITE(p, "ocol0 = 0;\n");
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
WRITE(p, "ocol1 = 0;\n");
if (DepthTextureEnable)
WRITE(p, "depth = 1.f;\n");
// HAXX: zcomploc is a way to control whether depth test is done before // HAXX: zcomploc is a way to control whether depth test is done before
// or after texturing and alpha test. PC GPU does depth test before texturing ONLY if depth value is // or after texturing and alpha test. PC GPU does depth test before texturing ONLY if depth value is
// not updated during shader execution. // not updated during shader execution.
@ -1190,7 +1227,7 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
// depth channel. // depth channel.
// 2 - in the next pass disable depth chanel update, but proccess the color data normally // 2 - in the next pass disable depth chanel update, but proccess the color data normally
// this way is the only CORRECT way to emulate perfectly the zcomplock behaviour // this way is the only CORRECT way to emulate perfectly the zcomplock behaviour
if (!(bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable)) if (!FastZcomploc)
{ {
WRITE(p, "discard;\n"); WRITE(p, "discard;\n");
if (ApiType != API_D3D11) if (ApiType != API_D3D11)

View File

@ -105,20 +105,28 @@ public:
typedef _PIXELSHADERUID<false> PIXELSHADERUID; typedef _PIXELSHADERUID<false> PIXELSHADERUID;
typedef _PIXELSHADERUID<true> PIXELSHADERUIDSAFE; typedef _PIXELSHADERUID<true> PIXELSHADERUIDSAFE;
// Different ways to achieve rendering with destination alpha // Different ways to achieve rendering
enum DSTALPHA_MODE enum PSGRENDER_MODE
{ {
DSTALPHA_NONE, // Render normally, without destination alpha PSGRENDER_NORMAL, // Render normally, without destination alpha
DSTALPHA_ALPHA_PASS, // Render normally first, then render again for alpha PSGRENDER_DSTALPHA_ALPHA_PASS, // Render normally first, then render again for alpha
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
}; };
const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType, u32 components); enum ALPHA_PRETEST_RESULT
{
ALPHAPT_UNDEFINED, // AlphaTest Result is not defined
ALPHAPT_ALWAYSFAIL, // Alpha test alway Fail
ALPHAPT_ALWAYSPASS // Alpha test alway Pass
};
void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 components); const char *GeneratePixelShaderCode(PSGRENDER_MODE PSGRenderMode, API_TYPE ApiType, u32 components);
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u32 components);
void GetPixelShaderId(PIXELSHADERUID *uid, PSGRENDER_MODE PSGRenderMode, u32 components);
void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, PSGRENDER_MODE PSGRenderMode, u32 components);
// Used to make sure that our optimized pixel shader IDs don't lose any possible shader code changes // Used to make sure that our optimized pixel shader IDs don't lose any possible shader code changes
void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::string& old_code, DSTALPHA_MODE dstAlphaMode, u32 components); void ValidatePixelShaderIDs(API_TYPE api, PIXELSHADERUIDSAFE old_id, const std::string& old_code, PSGRENDER_MODE PSGRenderMode, u32 components);
#endif // GCOGL_PIXELSHADER_H #endif // GCOGL_PIXELSHADER_H

View File

@ -43,6 +43,11 @@ extern int OSDChoice, OSDTime;
extern bool bLastFrameDumped; extern bool bLastFrameDumped;
#define RSM_None 0
#define RSM_Multipass 1
#define RSM_Zcomploc 2
#define RSM_UseDstAlpha 4
// Renderer really isn't a very good name for this class - it's more like "Misc". // Renderer really isn't a very good name for this class - it's more like "Misc".
// The long term goal is to get rid of this class and replace it with others that make // The long term goal is to get rid of this class and replace it with others that make
// more sense. // more sense.
@ -63,7 +68,7 @@ public:
virtual void SetSamplerState(int stage,int texindex) = 0; virtual void SetSamplerState(int stage,int texindex) = 0;
virtual void SetInterlacingMode() = 0; virtual void SetInterlacingMode() = 0;
virtual void ApplyState(bool bUseDstAlpha) = 0; virtual void ApplyState(u32 mode) = 0;
virtual void RestoreState() = 0; virtual void RestoreState() = 0;
// Ideal internal resolution - determined by display resolution (automatic scaling) and/or a multiple of the native EFB resolution // Ideal internal resolution - determined by display resolution (automatic scaling) and/or a multiple of the native EFB resolution

View File

@ -459,10 +459,10 @@ void PixelShaderCache::Shutdown()
g_ps_disk_cache.Close(); g_ps_disk_cache.Close();
} }
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) bool PixelShaderCache::SetShader(PSGRENDER_MODE PSGRenderMode, u32 components)
{ {
PIXELSHADERUID uid; PIXELSHADERUID uid;
GetPixelShaderId(&uid, dstAlphaMode, components); GetPixelShaderId(&uid, PSGRenderMode, components);
// Check if the shader is already set // Check if the shader is already set
if (last_entry) if (last_entry)
@ -470,7 +470,7 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
if (uid == last_uid) if (uid == last_uid)
{ {
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
ValidatePixelShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, dstAlphaMode, components); ValidatePixelShaderIDs(API_D3D11, last_entry->safe_uid, last_entry->code, PSGRenderMode, components);
return (last_entry->shader != NULL); return (last_entry->shader != NULL);
} }
} }
@ -486,12 +486,12 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
last_entry = &entry; last_entry = &entry;
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE,true);
ValidatePixelShaderIDs(API_D3D11, entry.safe_uid, entry.code, dstAlphaMode, components); ValidatePixelShaderIDs(API_D3D11, entry.safe_uid, entry.code, PSGRenderMode, components);
return (entry.shader != NULL); return (entry.shader != NULL);
} }
// Need to compile a new shader // Need to compile a new shader
const char* code = GeneratePixelShaderCode(dstAlphaMode, API_D3D11, components); const char* code = GeneratePixelShaderCode(PSGRenderMode, API_D3D11, components);
D3DBlob* pbytecode; D3DBlob* pbytecode;
if (!D3D::CompilePixelShader(code, (unsigned int)strlen(code), &pbytecode)) if (!D3D::CompilePixelShader(code, (unsigned int)strlen(code), &pbytecode))
@ -509,7 +509,7 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
if (g_ActiveConfig.bEnableShaderDebugging && success) if (g_ActiveConfig.bEnableShaderDebugging && success)
{ {
PixelShaders[uid].code = code; PixelShaders[uid].code = code;
GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components); GetSafePixelShaderId(&PixelShaders[uid].safe_uid, PSGRenderMode, components);
} }
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);

View File

@ -23,7 +23,7 @@
#include <map> #include <map>
enum DSTALPHA_MODE; enum PSGRENDER_MODE;
namespace DX11 namespace DX11
{ {
@ -34,7 +34,7 @@ public:
static void Init(); static void Init();
static void Clear(); static void Clear();
static void Shutdown(); static void Shutdown();
static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); // TODO: Should be renamed to LoadShader static bool SetShader(PSGRENDER_MODE PSGRenderMode, u32 components); // TODO: Should be renamed to LoadShader
static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen); static bool InsertByteCode(const PIXELSHADERUID &uid, const void* bytecode, unsigned int bytecodelen);
static ID3D11PixelShader* GetActiveShader() { return last_entry->shader; } static ID3D11PixelShader* GetActiveShader() { return last_entry->shader; }

View File

@ -1211,11 +1211,11 @@ void Renderer::RestoreAPIState()
BPFunctions::SetScissor(); BPFunctions::SetScissor();
} }
void Renderer::ApplyState(bool bUseDstAlpha) void Renderer::ApplyState(u32 mode)
{ {
HRESULT hr; HRESULT hr;
if (bUseDstAlpha) if (mode & RSM_UseDstAlpha)
{ {
// Colors should blend against SRC1_ALPHA // Colors should blend against SRC1_ALPHA
if (gx_state.blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_SRC_ALPHA) if (gx_state.blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_SRC_ALPHA)
@ -1275,7 +1275,7 @@ void Renderer::ApplyState(bool bUseDstAlpha)
D3D::stateman->Apply(); D3D::stateman->Apply();
if (bUseDstAlpha) if (mode & RSM_UseDstAlpha)
{ {
// restore actual state // restore actual state
SetBlendMode(false); SetBlendMode(false);

View File

@ -25,7 +25,7 @@ public:
void SetInterlacingMode(); void SetInterlacingMode();
// TODO: Fix confusing names (see ResetAPIState and RestoreAPIState) // TODO: Fix confusing names (see ResetAPIState and RestoreAPIState)
void ApplyState(bool bUseDstAlpha); void ApplyState(u32 mode);
void RestoreState(); void RestoreState();
void ApplyCullDisable(); void ApplyCullDisable();

View File

@ -249,7 +249,7 @@ void VertexManager::vFlush()
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
if (!PixelShaderCache::SetShader( if (!PixelShaderCache::SetShader(
useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, useDstAlpha ? PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND : PSGRENDER_NORMAL,
g_nativeVertexFmt->m_components)) 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");});
@ -264,7 +264,7 @@ void VertexManager::vFlush()
unsigned int stride = g_nativeVertexFmt->GetVertexStride(); unsigned int stride = g_nativeVertexFmt->GetVertexStride();
g_nativeVertexFmt->SetupVertexPointers(); g_nativeVertexFmt->SetupVertexPointers();
g_renderer->ApplyState(useDstAlpha); g_renderer->ApplyState(useDstAlpha ? RSM_UseDstAlpha : RSM_None);
LoadBuffers(); LoadBuffers();
Draw(stride); Draw(stride);

View File

@ -330,11 +330,11 @@ void PixelShaderCache::Shutdown()
unique_shaders.clear(); unique_shaders.clear();
} }
bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) bool PixelShaderCache::SetShader(PSGRENDER_MODE PSGRenderMode, u32 components)
{ {
const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30; const API_TYPE api = ((D3D::GetCaps().PixelShaderVersion >> 8) & 0xFF) < 3 ? API_D3D9_SM20 : API_D3D9_SM30;
PIXELSHADERUID uid; PIXELSHADERUID uid;
GetPixelShaderId(&uid, dstAlphaMode, components); GetPixelShaderId(&uid, PSGRenderMode, components);
// Check if the shader is already set // Check if the shader is already set
if (last_entry) if (last_entry)
@ -342,7 +342,7 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
if (uid == last_uid) if (uid == last_uid)
{ {
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
ValidatePixelShaderIDs(api, last_entry->safe_uid, last_entry->code, dstAlphaMode, components); ValidatePixelShaderIDs(api, last_entry->safe_uid, last_entry->code, PSGRenderMode, components);
return last_entry->shader != NULL; return last_entry->shader != NULL;
} }
} }
@ -359,13 +359,13 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
if (entry.shader) D3D::SetPixelShader(entry.shader); if (entry.shader) D3D::SetPixelShader(entry.shader);
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
ValidatePixelShaderIDs(api, entry.safe_uid, entry.code, dstAlphaMode, components); ValidatePixelShaderIDs(api, entry.safe_uid, entry.code, PSGRenderMode, components);
return (entry.shader != NULL); return (entry.shader != NULL);
} }
// Need to compile a new shader // Need to compile a new shader
const char *code = GeneratePixelShaderCode(dstAlphaMode, api, components); const char *code = GeneratePixelShaderCode(PSGRenderMode, api, components);
if (g_ActiveConfig.bEnableShaderDebugging) if (g_ActiveConfig.bEnableShaderDebugging)
{ {
@ -401,7 +401,7 @@ bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components)
if (g_ActiveConfig.bEnableShaderDebugging && success) if (g_ActiveConfig.bEnableShaderDebugging && success)
{ {
PixelShaders[uid].code = code; PixelShaders[uid].code = code;
GetSafePixelShaderId(&PixelShaders[uid].safe_uid, dstAlphaMode, components); GetSafePixelShaderId(&PixelShaders[uid].safe_uid, PSGRenderMode, components);
} }
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);

View File

@ -63,7 +63,7 @@ private:
public: public:
static void Init(); static void Init();
static void Shutdown(); static void Shutdown();
static bool SetShader(DSTALPHA_MODE dstAlphaMode, u32 componets); static bool SetShader(PSGRENDER_MODE PSGRenderMode, u32 componets);
static bool InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate); static bool InsertByteCode(const PIXELSHADERUID &uid, const u8 *bytecode, int bytecodelen, bool activate);
static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram(int SSAAMode); static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram(int SSAAMode);
static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(int SSAAMode); static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram(int SSAAMode);

View File

@ -247,6 +247,7 @@ void TeardownDeviceObjects()
// Init functions // Init functions
Renderer::Renderer() Renderer::Renderer()
{ {
Renderer::LastMode = RSM_None;
st = new char[32768]; st = new char[32768];
int fullScreenRes, x, y, w_temp, h_temp; int fullScreenRes, x, y, w_temp, h_temp;
@ -1204,20 +1205,49 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
XFBWrited = false; XFBWrited = false;
} }
void Renderer::ApplyState(bool bUseDstAlpha) void Renderer::ApplyState(u32 mode)
{ {
if (bUseDstAlpha) if(mode & RSM_Zcomploc)
{
D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, 0);
}
if(mode & RSM_Multipass)
{
D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE);
D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false);
D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL);
}
if (mode & RSM_UseDstAlpha)
{ {
D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false);
} }
Renderer::LastMode |= mode;
} }
void Renderer::RestoreState() void Renderer::RestoreState()
{
if(Renderer::LastMode & RSM_Zcomploc)
{
D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE);
}
if(Renderer::LastMode & RSM_Multipass)
{
D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE);
D3D::RefreshRenderState(D3DRS_ZENABLE);
D3D::RefreshRenderState(D3DRS_ZWRITEENABLE);
D3D::RefreshRenderState(D3DRS_ZFUNC);
}
if(Renderer::LastMode & RSM_UseDstAlpha)
{ {
D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE);
D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE);
}
Renderer::LastMode = RSM_None;
// TODO: Enable this code. Caused glitches for me however (neobrain) // TODO: Enable this code. Caused glitches for me however (neobrain)
// for (unsigned int i = 0; i < 8; ++i) // for (unsigned int i = 0; i < 8; ++i)
// D3D::dev->SetTexture(i, NULL); // D3D::dev->SetTexture(i, NULL);

View File

@ -9,6 +9,8 @@ namespace DX9
class Renderer : public ::Renderer class Renderer : public ::Renderer
{ {
private:
u32 LastMode;
public: public:
Renderer(); Renderer();
~Renderer(); ~Renderer();
@ -24,7 +26,7 @@ public:
void SetSamplerState(int stage,int texindex); void SetSamplerState(int stage,int texindex);
void SetInterlacingMode(); void SetInterlacingMode();
void ApplyState(bool bUseDstAlpha); void ApplyState(u32 mode);
void RestoreState(); void RestoreState();
void RenderText(const char* pstr, int left, int top, u32 color); void RenderText(const char* pstr, int left, int top, u32 color);

View File

@ -154,7 +154,7 @@ void VertexManager::vFlush()
VertexShaderManager::SetConstants(); VertexShaderManager::SetConstants();
PixelShaderManager::SetConstants(); PixelShaderManager::SetConstants();
if (!PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components)) if (!PixelShaderCache::SetShader(PSGRENDER_NORMAL,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;
@ -175,14 +175,27 @@ void VertexManager::vFlush()
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24; bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24;
if (useDstAlpha) if (useDstAlpha)
{ {
DWORD write = 0; if (!PixelShaderCache::SetShader(PSGRENDER_DSTALPHA_ALPHA_PASS, g_nativeVertexFmt->m_components))
if (!PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS, 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;
} }
// update alpha only // update alpha only
g_renderer->ApplyState(true); g_renderer->ApplyState(RSM_UseDstAlpha | (bpmem.zmode.updateenable ? RSM_Multipass : RSM_None));
Draw(stride);
g_renderer->RestoreState();
}
bool useZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable;
if(useZcomploc)
{
if (!PixelShaderCache::SetShader(PSGRENDER_ZCOMPLOCK, g_nativeVertexFmt->m_components))
{
GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
goto shader_fail;
}
// update Depth only
g_renderer->ApplyState(RSM_Zcomploc);
Draw(stride); Draw(stride);
g_renderer->RestoreState(); g_renderer->RestoreState();
} }

View File

@ -181,10 +181,10 @@ void PixelShaderCache::Shutdown()
PixelShaders.clear(); PixelShaders.clear();
} }
FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 components) FRAGMENTSHADER* PixelShaderCache::SetShader(PSGRENDER_MODE PSGRenderMode, u32 components)
{ {
PIXELSHADERUID uid; PIXELSHADERUID uid;
GetPixelShaderId(&uid, dstAlphaMode, components); GetPixelShaderId(&uid, PSGRenderMode, components);
// Check if the shader is already set // Check if the shader is already set
if (last_entry) if (last_entry)
@ -192,7 +192,7 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp
if (uid == last_uid) if (uid == last_uid)
{ {
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
ValidatePixelShaderIDs(API_OPENGL, last_entry->safe_uid, last_entry->shader.strprog, dstAlphaMode, components); ValidatePixelShaderIDs(API_OPENGL, last_entry->safe_uid, last_entry->shader.strprog, PSGRenderMode, components);
return &last_entry->shader; return &last_entry->shader;
} }
} }
@ -206,18 +206,18 @@ FRAGMENTSHADER* PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 comp
last_entry = &entry; last_entry = &entry;
GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true); GFX_DEBUGGER_PAUSE_AT(NEXT_PIXEL_SHADER_CHANGE, true);
ValidatePixelShaderIDs(API_OPENGL, entry.safe_uid, entry.shader.strprog, dstAlphaMode, components); ValidatePixelShaderIDs(API_OPENGL, entry.safe_uid, entry.shader.strprog, PSGRenderMode, components);
return &last_entry->shader; return &last_entry->shader;
} }
// Make an entry in the table // Make an entry in the table
PSCacheEntry& newentry = PixelShaders[uid]; PSCacheEntry& newentry = PixelShaders[uid];
last_entry = &newentry; last_entry = &newentry;
const char *code = GeneratePixelShaderCode(dstAlphaMode, API_OPENGL, components); const char *code = GeneratePixelShaderCode(PSGRenderMode, API_OPENGL, components);
if (g_ActiveConfig.bEnableShaderDebugging && code) if (g_ActiveConfig.bEnableShaderDebugging && code)
{ {
GetSafePixelShaderId(&newentry.safe_uid, dstAlphaMode, components); GetSafePixelShaderId(&newentry.safe_uid, PSGRenderMode, components);
newentry.shader.strprog = code; newentry.shader.strprog = code;
} }

View File

@ -74,7 +74,7 @@ public:
static void Init(); static void Init();
static void Shutdown(); static void Shutdown();
static FRAGMENTSHADER* SetShader(DSTALPHA_MODE dstAlphaMode, u32 components); static FRAGMENTSHADER* SetShader(PSGRENDER_MODE PSGRenderMode, u32 components);
static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram); static bool CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram);
static GLuint GetColorMatrixProgram(); static GLuint GetColorMatrixProgram();

View File

@ -245,6 +245,7 @@ int GetNumMSAACoverageSamples(int MSAAMode)
// Init functions // Init functions
Renderer::Renderer() Renderer::Renderer()
{ {
Renderer::LastMode = RSM_None;
OSDInternalW = 0; OSDInternalW = 0;
OSDInternalH = 0; OSDInternalH = 0;
@ -515,6 +516,49 @@ Renderer::~Renderer()
delete g_framebuffer_manager; delete g_framebuffer_manager;
} }
void Renderer::ApplyState(u32 mode)
{
if(mode & RSM_Zcomploc)
{
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
}
if(mode & RSM_Multipass)
{
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDepthFunc(GL_EQUAL);
}
if (mode & RSM_UseDstAlpha)
{
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glDisable(GL_BLEND);
}
Renderer::LastMode |= mode;
}
void Renderer::RestoreState()
{
if(Renderer::LastMode & RSM_Zcomploc)
{
SetColorMask();
}
if(Renderer::LastMode & RSM_Multipass)
{
SetDepthMode();
}
if (Renderer::LastMode & RSM_UseDstAlpha)
{
SetColorMask();
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract)
glEnable(GL_BLEND);
}
Renderer::LastMode = RSM_None;
}
// Create On-Screen-Messages // Create On-Screen-Messages
void Renderer::DrawDebugInfo() void Renderer::DrawDebugInfo()
{ {

View File

@ -11,6 +11,8 @@ void ClearEFBCache();
class Renderer : public ::Renderer class Renderer : public ::Renderer
{ {
private:
u32 LastMode;
public: public:
Renderer(); Renderer();
~Renderer(); ~Renderer();
@ -27,8 +29,8 @@ public:
void SetInterlacingMode(); void SetInterlacingMode();
// TODO: Implement and use these // TODO: Implement and use these
void ApplyState(bool bUseDstAlpha) {} void ApplyState(u32 mode);
void RestoreState() {} void RestoreState();
void RenderText(const char* pstr, int left, int top, u32 color); void RenderText(const char* pstr, int left, int top, u32 color);
void DrawDebugInfo(); void DrawDebugInfo();

View File

@ -187,21 +187,21 @@ void VertexManager::vFlush()
// If host supports GL_ARB_blend_func_extended, we can do dst alpha in // If host supports GL_ARB_blend_func_extended, we can do dst alpha in
// the same pass as regular rendering. // the same pass as regular rendering.
g_renderer->SetBlendMode(true); g_renderer->SetBlendMode(true);
ps = PixelShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, g_nativeVertexFmt->m_components); ps = PixelShaderCache::SetShader(PSGRENDER_DSTALPHA_DUAL_SOURCE_BLEND, g_nativeVertexFmt->m_components);
} }
else else
{ {
g_renderer->SetBlendMode(true); g_renderer->SetBlendMode(true);
ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components); ps = PixelShaderCache::SetShader(PSGRENDER_NORMAL,g_nativeVertexFmt->m_components);
} }
} }
else else
{ {
ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components); ps = PixelShaderCache::SetShader(PSGRENDER_NORMAL,g_nativeVertexFmt->m_components);
} }
#else #else
bool dualSourcePossible = false; bool dualSourcePossible = false;
FRAGMENTSHADER* ps = PixelShaderCache::SetShader(DSTALPHA_NONE,g_nativeVertexFmt->m_components); FRAGMENTSHADER* ps = PixelShaderCache::SetShader(PSGRENDER_NORMAL,g_nativeVertexFmt->m_components);
#endif #endif
VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components); VERTEXSHADER* vs = VertexShaderCache::SetShader(g_nativeVertexFmt->m_components);
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here. if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); // Lego Star Wars crashes here.
@ -212,20 +212,22 @@ void VertexManager::vFlush()
// run through vertex groups again to set alpha // run through vertex groups again to set alpha
if (useDstAlpha && !dualSourcePossible) if (useDstAlpha && !dualSourcePossible)
{ {
ps = PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS,g_nativeVertexFmt->m_components); ps = PixelShaderCache::SetShader(PSGRENDER_DSTALPHA_ALPHA_PASS,g_nativeVertexFmt->m_components);
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
// only update alpha g_renderer->ApplyState(RSM_UseDstAlpha | (bpmem.zmode.updateenable ? RSM_Multipass : RSM_None));
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glDisable(GL_BLEND);
Draw(); Draw();
// restore color mask g_renderer->RestoreState();
g_renderer->SetColorMask(); }
bool useZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable;
if (useZcomploc)
{
ps = PixelShaderCache::SetShader(PSGRENDER_ZCOMPLOCK,g_nativeVertexFmt->m_components);
if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid);
if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) g_renderer->ApplyState(RSM_Zcomploc);
glEnable(GL_BLEND); Draw();
g_renderer->RestoreState();
} }
GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true); GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);