diff options
| author | Rodolfo Osvaldo Bogado <rodolfoosvaldobogado@gmail.com> | 2010-06-29 14:40:37 +0000 |
|---|---|---|
| committer | Rodolfo Osvaldo Bogado <rodolfoosvaldobogado@gmail.com> | 2010-06-29 14:40:37 +0000 |
| commit | d511b506120ccc8030b8773e73583365fd38de36 (patch) | |
| tree | bac466603267672bcc2e57722b1ee82ed2768f2f /Source/Core/VideoCommon | |
| parent | 4afe48a0fb2975dfc2bae58b115725bf94aa6d20 (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.cpp | 133 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 36 |
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? |
