summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorRodolfo Osvaldo Bogado <rodolfoosvaldobogado@gmail.com>2010-06-29 14:40:37 +0000
committerRodolfo Osvaldo Bogado <rodolfoosvaldobogado@gmail.com>2010-06-29 14:40:37 +0000
commitd511b506120ccc8030b8773e73583365fd38de36 (patch)
treebac466603267672bcc2e57722b1ee82ed2768f2f /Source/Core/VideoCommon
parent4afe48a0fb2975dfc2bae58b115725bf94aa6d20 (diff)
this commit is divided in 4 parts:
1 - Optimize pixelshadergen to avoid redundant register overflow math, with this if a game don't need this will be not applied. this must bring some fill rate back and improve speed a little in fill rate limited systems. 2- some corrections to vertexshadergen to avoid uninitialized texture coordinates, dono if is the correct way to fix it but t least it will make house of the dead overkill playable in dx11. the bad thing: still missing geometri in dx9, in dx11 it works exactly as on opengl. 3 - some optimization made to improve fps a little wih the latests changes made to fifo. * back to the original code in beginfield as now it will work right. * check for efb access more often as a lot of time is lost waiting for efb access 4 - apply a little fix for missing textures in nvidia opengl tanks to Wagnard28 for finding that nvidia does not like invalid shader id :) please test for any regression git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5812 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/Src/PixelShaderGen.cpp133
-rw-r--r--Source/Core/VideoCommon/Src/VertexShaderGen.cpp36
2 files changed, 114 insertions, 55 deletions
diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
index afc1400c3a..388e16ffab 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
@@ -345,6 +345,15 @@ static char swapModeTable[4][5];
static char text[16384];
+struct RegisterState
+{
+ bool ColorNeedOverflowControl;
+ bool AlphaNeedOverflowControl;
+ bool AuxStored;
+};
+
+static RegisterState RegisterStates[4];
+
static void BuildSwapModeTable()
{
for (int i = 0; i < 4; i++)
@@ -383,21 +392,10 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, API_
}
// Declare samplers
- if (texture_mask)
+ if (texture_mask && ApiType == API_OPENGL)
{
- if (ApiType == API_D3D11)
- {
- WRITE(p, "sampler ");
- }
- else if (ApiType == API_D3D9)
- {
- WRITE(p, "uniform sampler ");
- }
- else
- {
- WRITE(p, "uniform samplerRECT ");
- }
- bool bfirst = true;
+ WRITE(p, "uniform samplerRECT ");
+ bool bfirst = true;
for (int i = 0; i < 8; ++i)
{
if (texture_mask & (1<<i))
@@ -406,21 +404,7 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, API_
bfirst = false;
}
}
- WRITE(p, ";\n");
- if(ApiType == API_D3D11)
- {
- bfirst = true;
- WRITE(p, "Texture2D ");
- for (int i = 0; i < 8; ++i)
- {
- if (texture_mask & (1<<i))
- {
- WRITE(p, "%s Tex%d : register(t%d)", bfirst?"":",", i, i);
- bfirst = false;
- }
- }
- WRITE(p, ";\n");
- }
+ WRITE(p, ";\n");
}
if (texture_mask != 0xff)
@@ -549,19 +533,39 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, API_
}
}
+ RegisterStates[0].AlphaNeedOverflowControl = false;
+ RegisterStates[0].ColorNeedOverflowControl = false;
+ RegisterStates[0].AuxStored = false;
+ for(int i = 0 ; i < 4 ; i++)
+ {
+ RegisterStates[i].AlphaNeedOverflowControl = true;
+ RegisterStates[i].ColorNeedOverflowControl = true;
+ RegisterStates[i].AuxStored = false;
+ }
for (int i = 0; i < numStages; i++)
WriteStage(p, i, texture_mask,ApiType); //build the equation for this stage
+
if(numStages)
{
// The results of the last texenv stage are put onto the screen,
// regardless of the used destination register
- WRITE(p, "prev.rgb = %s;\n",tevCOutputTable[bpmem.combiners[numStages-1].colorC.dest]);
- WRITE(p, "prev.a = %s;\n",tevAOutputTable[bpmem.combiners[numStages-1].alphaC.dest]);
+ if(bpmem.combiners[numStages - 1].colorC.dest != 0)
+ {
+ bool retrieveFromAuxRegister = !RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl && RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].AuxStored;
+ WRITE(p, "prev.rgb = %s%s;\n", retrieveFromAuxRegister ? "c" : "" ,tevCOutputTable[bpmem.combiners[numStages - 1].colorC.dest]);
+ RegisterStates[0].ColorNeedOverflowControl = RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl;
+ }
+ if(bpmem.combiners[numStages - 1].alphaC.dest != 0)
+ {
+ bool retrieveFromAuxRegister = !RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AlphaNeedOverflowControl && RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AuxStored;
+ WRITE(p, "prev.a = %s%s;\n", retrieveFromAuxRegister ? "c" : "" ,tevAOutputTable[bpmem.combiners[numStages - 1].alphaC.dest]);
+ RegisterStates[0].AlphaNeedOverflowControl = RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AlphaNeedOverflowControl;
+ }
}
-
- // emulation of unisgned 8 overflow when casting
- WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ // emulation of unisgned 8 overflow when casting if needed
+ if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
+ WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
if (!WriteAlphaTest(p, ApiType))
{
@@ -782,7 +786,19 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
|| ac.a == TEVALPHAARG_APREV
|| ac.b == TEVALPHAARG_APREV
|| ac.c == TEVALPHAARG_APREV)
- WRITE(p, "cprev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ {
+ if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
+ {
+ WRITE(p, "cprev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ RegisterStates[0].AlphaNeedOverflowControl = false;
+ RegisterStates[0].ColorNeedOverflowControl = false;
+ }
+ else
+ {
+ WRITE(p, "cprev = prev;\n");
+ }
+ RegisterStates[0].AuxStored = true;
+ }
if(cc.a == TEVCOLORARG_C0
|| cc.a == TEVCOLORARG_A0
@@ -793,7 +809,20 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
|| ac.a == TEVALPHAARG_A0
|| ac.b == TEVALPHAARG_A0
|| ac.c == TEVALPHAARG_A0)
- WRITE(p, "cc0 = frac(4.0f + c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ {
+ if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl)
+ {
+ WRITE(p, "cc0 = frac(4.0f + c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ RegisterStates[1].AlphaNeedOverflowControl = false;
+ RegisterStates[1].ColorNeedOverflowControl = false;
+ }
+ else
+ {
+ WRITE(p, "cc0 = c0;\n");
+ }
+ RegisterStates[1].AuxStored = true;
+ }
+
if(cc.a == TEVCOLORARG_C1
|| cc.a == TEVCOLORARG_A1
@@ -804,7 +833,19 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
|| ac.a == TEVALPHAARG_A1
|| ac.b == TEVALPHAARG_A1
|| ac.c == TEVALPHAARG_A1)
- WRITE(p, "cc1 = frac(4.0f + c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ {
+ if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl)
+ {
+ WRITE(p, "cc1 = frac(4.0f + c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ RegisterStates[2].AlphaNeedOverflowControl = false;
+ RegisterStates[2].ColorNeedOverflowControl = false;
+ }
+ else
+ {
+ WRITE(p, "cc1 = c1;\n");
+ }
+ RegisterStates[2].AuxStored = true;
+ }
if(cc.a == TEVCOLORARG_C2
|| cc.a == TEVCOLORARG_A2
@@ -815,8 +856,22 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
|| ac.a == TEVALPHAARG_A2
|| ac.b == TEVALPHAARG_A2
|| ac.c == TEVALPHAARG_A2)
- WRITE(p, "cc2 = frac(4.0f + c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ {
+ if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl)
+ {
+ WRITE(p, "cc2 = frac(4.0f + c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
+ RegisterStates[3].AlphaNeedOverflowControl = false;
+ RegisterStates[3].ColorNeedOverflowControl = false;
+ }
+ else
+ {
+ WRITE(p, "cc2 = c2;\n");
+ }
+ RegisterStates[3].AuxStored = true;
+ }
+ RegisterStates[cc.dest].ColorNeedOverflowControl = (cc.clamp == 0);
+ RegisterStates[cc.dest].AuxStored = false;
if (cc.clamp)
WRITE(p, "%s=saturate(", tevCOutputTable[cc.dest]);
else
@@ -863,6 +918,8 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
WRITE(p,")");
WRITE(p,";\n");
+ RegisterStates[ac.dest].AlphaNeedOverflowControl = (ac.clamp == 0);
+ RegisterStates[ac.dest].AuxStored = false;
// combine the alpha channel
if (ac.clamp)
WRITE(p, "%s=saturate(", tevAOutputTable[ac.dest]);
diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp
index 7f43508b02..53a2682314 100644
--- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp
+++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp
@@ -332,7 +332,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
// zero left over channels
for (int i = xfregs.nNumChans; i < 2; ++i)
- WRITE(p, "o.colors[%d] = float4(0.0f,0.0f,0.0f,0.0f);\n", i);
+ WRITE(p, "o.colors[%d] = float4(0.0f,0.0f,0.0f,1.0f);\n", i);
// special case if only pos and tex coord 0 and tex coord input is AB11
// donko - this has caused problems in some games. removed for now.
@@ -349,6 +349,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
TexMtxInfo& texinfo = xfregs.texcoords[i].texmtxinfo;
WRITE(p, "{\n");
+ WRITE(p, "coord = float4(0.0f,0.0f,1.0f,1.0f);\n");
switch (texinfo.sourcerow) {
case XF_SRCGEOM_INROW:
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
@@ -384,27 +385,12 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
// firs transformation
switch (texinfo.texgentype) {
- case XF_TEXGEN_REGULAR:
- if (components & (VB_HAS_TEXMTXIDX0<<i)) {
- if (texinfo.projection == XF_TEXPROJ_STQ )
- WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+1].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+2].t));\n", i, i, i, i);
- else {
- WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+1].t), 1);\n", i, i, i);
- }
- }
- else {
- if (texinfo.projection == XF_TEXPROJ_STQ )
- WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TEXMATRICES".T[%d].t), dot(coord, "I_TEXMATRICES".T[%d].t), dot(coord, "I_TEXMATRICES".T[%d].t));\n", i, 3*i, 3*i+1, 3*i+2);
- else
- WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TEXMATRICES".T[%d].t), dot(coord, "I_TEXMATRICES".T[%d].t), 1);\n", i, 3*i, 3*i+1);
- }
- break;
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) {
// transform the light dir into tangent space
WRITE(p, "ldir = normalize("I_LIGHTS".lights[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift);
- WRITE(p, "o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift);
+ WRITE(p, "o.tex%d.xyz = coord.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift);
}
else _assert_(0); // should have normals
@@ -417,6 +403,22 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
WRITE(p, "o.tex%d.xyz = float3(o.colors[1].x, o.colors[1].y, 1);\n", i);
break;
+ case XF_TEXGEN_REGULAR:
+ default:
+ if (components & (VB_HAS_TEXMTXIDX0<<i)) {
+ if (texinfo.projection == XF_TEXPROJ_STQ )
+ WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+1].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+2].t));\n", i, i, i, i);
+ else {
+ WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+1].t), 1);\n", i, i, i);
+ }
+ }
+ else {
+ if (texinfo.projection == XF_TEXPROJ_STQ )
+ WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TEXMATRICES".T[%d].t), dot(coord, "I_TEXMATRICES".T[%d].t), dot(coord, "I_TEXMATRICES".T[%d].t));\n", i, 3*i, 3*i+1, 3*i+2);
+ else
+ WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TEXMATRICES".T[%d].t), dot(coord, "I_TEXMATRICES".T[%d].t), 1);\n", i, 3*i, 3*i+1);
+ }
+ break;
}
if (xfregs.bEnableDualTexTransform && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types?