diff options
Diffstat (limited to 'Source/Core/VideoCommon/Src/VertexShaderGen.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/Src/VertexShaderGen.cpp | 319 |
1 files changed, 200 insertions, 119 deletions
diff --git a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp index cad117c2c8..2c0f5676ed 100644 --- a/Source/Core/VideoCommon/Src/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/VertexShaderGen.cpp @@ -114,7 +114,8 @@ void ValidateVertexShaderIDs(API_TYPE api, VERTEXSHADERUIDSAFE old_id, const std static int num_failures = 0; char szTemp[MAX_PATH]; sprintf(szTemp, "%svsuid_mismatch_%04i.txt", File::GetUserPath(D_DUMP_IDX).c_str(), num_failures++); - std::ofstream file(szTemp); + std::ofstream file; + OpenFStream(file, szTemp, std::ios_base::out); file << msg; file << "\n\nOld shader code:\n" << old_code; file << "\n\nNew shader code:\n" << new_code; @@ -130,46 +131,51 @@ static char text[16384]; #define WRITE p+=sprintf -char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE api_type) +char* GenerateVSOutputStruct(char* p, u32 components, API_TYPE ApiType) { + // GLSL makes this ugly + // TODO: Make pretty WRITE(p, "struct VS_OUTPUT {\n"); - WRITE(p, " float4 pos : POSITION;\n"); - WRITE(p, " float4 colors_0 : COLOR0;\n"); - WRITE(p, " float4 colors_1 : COLOR1;\n"); + WRITE(p, " float4 pos %s POSITION;\n", ApiType == API_OPENGL ? ";//" : ":"); + WRITE(p, " float4 colors_0 %s COLOR0;\n", ApiType == API_OPENGL ? ";//" : ":"); + WRITE(p, " float4 colors_1 %s COLOR1;\n", ApiType == API_OPENGL ? ";//" : ":"); if (xfregs.numTexGen.numTexGens < 7) { for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) - WRITE(p, " float3 tex%d : TEXCOORD%d;\n", i, i); - WRITE(p, " float4 clipPos : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens); + WRITE(p, " float3 tex%d %s TEXCOORD%d;\n", i, ApiType == API_OPENGL ? ";//" : ":", i); + WRITE(p, " float4 clipPos %s TEXCOORD%d;\n", ApiType == API_OPENGL ? ";//" : ":", xfregs.numTexGen.numTexGens); if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) - WRITE(p, " float4 Normal : TEXCOORD%d;\n", xfregs.numTexGen.numTexGens + 1); + WRITE(p, " float4 Normal %s TEXCOORD%d;\n", ApiType == API_OPENGL ? ";//" : ":", xfregs.numTexGen.numTexGens + 1); } else { // clip position is in w of first 4 texcoords if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { for (int i = 0; i < 8; ++i) - WRITE(p, " float4 tex%d : TEXCOORD%d;\n", i, i); + WRITE(p, " float4 tex%d %s TEXCOORD%d;\n", i, ApiType == API_OPENGL? ";//" : ":", i); } else { for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) - WRITE(p, " float%d tex%d : TEXCOORD%d;\n", i < 4 ? 4 : 3 , i, i); + WRITE(p, " float%d tex%d %s TEXCOORD%d;\n", i < 4 ? 4 : 3 , i, ApiType == API_OPENGL ? ";//" : ":", i); } - } + } WRITE(p, "};\n"); return p; } -const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) +extern const char* WriteRegister(API_TYPE ApiType, const char *prefix, const u32 num); +extern const char *WriteLocation(API_TYPE ApiType); + +const char *GenerateVertexShaderCode(u32 components, API_TYPE ApiType) { setlocale(LC_NUMERIC, "C"); // Reset locale for compilation text[sizeof(text) - 1] = 0x7C; // canary _assert_(bpmem.genMode.numtexgens == xfregs.numTexGen.numTexGens); _assert_(bpmem.genMode.numcolchans == xfregs.numChan.numColorChans); - - bool is_d3d = (api_type & API_D3D9 || api_type == API_D3D11); + + bool is_d3d = (ApiType & API_D3D9 || ApiType == API_D3D11); u32 lightMask = 0; if (xfregs.numChan.numColorChans > 0) lightMask |= xfregs.color[0].GetFullLightMask() | xfregs.alpha[0].GetFullLightMask(); @@ -178,91 +184,133 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) char *p = text; WRITE(p, "//Vertex Shader: comp:%x, \n", components); - WRITE(p, "typedef struct { float4 T0, T1, T2; float4 N0, N1, N2; } s_" I_POSNORMALMATRIX";\n" - "typedef struct { float4 t; } FLT4;\n" - "typedef struct { FLT4 T[24]; } s_" I_TEXMATRICES";\n" - "typedef struct { FLT4 T[64]; } s_" I_TRANSFORMMATRICES";\n" - "typedef struct { FLT4 T[32]; } s_" I_NORMALMATRICES";\n" - "typedef struct { FLT4 T[64]; } s_" I_POSTTRANSFORMMATRICES";\n" - "typedef struct { float4 col; float4 cosatt; float4 distatt; float4 pos; float4 dir; } Light;\n" - "typedef struct { Light lights[8]; } s_" I_LIGHTS";\n" - "typedef struct { float4 C0, C1, C2, C3; } s_" I_MATERIALS";\n" - "typedef struct { float4 T0, T1, T2, T3; } s_" I_PROJECTION";\n" - ); - - p = GenerateVSOutputStruct(p, components, api_type); // uniforms + if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) + WRITE(p, "layout(std140) uniform VSBlock {\n"); - WRITE(p, "uniform s_" I_TRANSFORMMATRICES" " I_TRANSFORMMATRICES" : register(c%d);\n", C_TRANSFORMMATRICES); - WRITE(p, "uniform s_" I_TEXMATRICES" " I_TEXMATRICES" : register(c%d);\n", C_TEXMATRICES); // also using tex matrices - WRITE(p, "uniform s_" I_NORMALMATRICES" " I_NORMALMATRICES" : register(c%d);\n", C_NORMALMATRICES); - WRITE(p, "uniform s_" I_POSNORMALMATRIX" " I_POSNORMALMATRIX" : register(c%d);\n", C_POSNORMALMATRIX); - WRITE(p, "uniform s_" I_POSTTRANSFORMMATRICES" " I_POSTTRANSFORMMATRICES" : register(c%d);\n", C_POSTTRANSFORMMATRICES); - WRITE(p, "uniform s_" I_LIGHTS" " I_LIGHTS" : register(c%d);\n", C_LIGHTS); - WRITE(p, "uniform s_" I_MATERIALS" " I_MATERIALS" : register(c%d);\n", C_MATERIALS); - WRITE(p, "uniform s_" I_PROJECTION" " I_PROJECTION" : register(c%d);\n", C_PROJECTION); - WRITE(p, "uniform float4 " I_DEPTHPARAMS" : register(c%d);\n", C_DEPTHPARAMS); - - WRITE(p, "VS_OUTPUT main(\n"); - - // inputs - if (components & VB_HAS_NRM0) - WRITE(p, " float3 rawnorm0 : NORMAL0,\n"); - if (components & VB_HAS_NRM1) { - if (is_d3d) - WRITE(p, " float3 rawnorm1 : NORMAL1,\n"); - else - WRITE(p, " float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); - } - if (components & VB_HAS_NRM2) { - if (is_d3d) - WRITE(p, " float3 rawnorm2 : NORMAL2,\n"); - else - WRITE(p, " float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); - } - if (components & VB_HAS_COL0) - WRITE(p, " float4 color0 : COLOR0,\n"); - if (components & VB_HAS_COL1) - WRITE(p, " float4 color1 : COLOR1,\n"); - for (int i = 0; i < 8; ++i) { - u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i)); - if ((components & (VB_HAS_UV0<<i)) || hastexmtx) - WRITE(p, " float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i); - } - if (components & VB_HAS_POSMTXIDX) { - if (is_d3d) + WRITE(p, "%sfloat4 " I_POSNORMALMATRIX"[6] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_POSNORMALMATRIX)); + WRITE(p, "%sfloat4 " I_PROJECTION"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_PROJECTION)); + WRITE(p, "%sfloat4 " I_MATERIALS"[4] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_MATERIALS)); + WRITE(p, "%sfloat4 " I_LIGHTS"[40] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_LIGHTS)); + WRITE(p, "%sfloat4 " I_TEXMATRICES"[24] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_TEXMATRICES)); // also using tex matrices + WRITE(p, "%sfloat4 " I_TRANSFORMMATRICES"[64] %s;\n", WriteLocation(ApiType),WriteRegister(ApiType, "c", C_TRANSFORMMATRICES)); + WRITE(p, "%sfloat4 " I_NORMALMATRICES"[32] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_NORMALMATRICES)); + WRITE(p, "%sfloat4 " I_POSTTRANSFORMMATRICES"[64] %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_POSTTRANSFORMMATRICES)); + WRITE(p, "%sfloat4 " I_DEPTHPARAMS" %s;\n", WriteLocation(ApiType), WriteRegister(ApiType, "c", C_DEPTHPARAMS)); + + if (g_ActiveConfig.backend_info.bSupportsGLSLUBO) + WRITE(p, "};\n"); + + p = GenerateVSOutputStruct(p, components, ApiType); + + if(ApiType == API_OPENGL) + { + WRITE(p, "ATTRIN float4 rawpos; // ATTR%d,\n", SHADER_POSITION_ATTRIB); + if (components & VB_HAS_POSMTXIDX) + WRITE(p, "ATTRIN int posmtx; // ATTR%d,\n", SHADER_POSMTX_ATTRIB); + if (components & VB_HAS_NRM0) + WRITE(p, "ATTRIN float3 rawnorm0; // ATTR%d,\n", SHADER_NORM0_ATTRIB); + if (components & VB_HAS_NRM1) + WRITE(p, "ATTRIN float3 rawnorm1; // ATTR%d,\n", SHADER_NORM1_ATTRIB); + if (components & VB_HAS_NRM2) + WRITE(p, "ATTRIN float3 rawnorm2; // ATTR%d,\n", SHADER_NORM2_ATTRIB); + + if (components & VB_HAS_COL0) + WRITE(p, "ATTRIN float4 color0; // ATTR%d,\n", SHADER_COLOR0_ATTRIB); + if (components & VB_HAS_COL1) + WRITE(p, "ATTRIN float4 color1; // ATTR%d,\n", SHADER_COLOR1_ATTRIB); + + for (int i = 0; i < 8; ++i) { + u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i)); + if ((components & (VB_HAS_UV0<<i)) || hastexmtx) + WRITE(p, "ATTRIN float%d tex%d; // ATTR%d,\n", hastexmtx ? 3 : 2, i, SHADER_TEXTURE0_ATTRIB + i); + } + + // Let's set up attributes + if (xfregs.numTexGen.numTexGens < 7) { - WRITE(p, " float4 blend_indices : BLENDINDICES,\n"); + for (int i = 0; i < 8; ++i) + WRITE(p, "VARYOUT float3 uv%d_2;\n", i); + WRITE(p, "VARYOUT float4 clipPos_2;\n"); + if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) + WRITE(p, "VARYOUT float4 Normal_2;\n"); } else - WRITE(p, " float fposmtx : ATTR%d,\n", SHADER_POSMTX_ATTRIB); + { + // wpos is in w of first 4 texcoords + if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) + { + for (int i = 0; i < 8; ++i) + WRITE(p, "VARYOUT float4 uv%d_2;\n", i); + } + else + { + for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) + WRITE(p, "VARYOUT float%d uv%d_2;\n", i < 4 ? 4 : 3 , i); + } + } + WRITE(p, "VARYOUT float4 colors_02;\n"); + WRITE(p, "VARYOUT float4 colors_12;\n"); + + WRITE(p, "void main()\n{\n"); + } + else + { + WRITE(p, "VS_OUTPUT main(\n"); + + // inputs + if (components & VB_HAS_NRM0) + WRITE(p, " float3 rawnorm0 : NORMAL0,\n"); + if (components & VB_HAS_NRM1) { + if (is_d3d) + WRITE(p, " float3 rawnorm1 : NORMAL1,\n"); + else + WRITE(p, " float3 rawnorm1 : ATTR%d,\n", SHADER_NORM1_ATTRIB); + } + if (components & VB_HAS_NRM2) { + if (is_d3d) + WRITE(p, " float3 rawnorm2 : NORMAL2,\n"); + else + WRITE(p, " float3 rawnorm2 : ATTR%d,\n", SHADER_NORM2_ATTRIB); + } + if (components & VB_HAS_COL0) + WRITE(p, " float4 color0 : COLOR0,\n"); + if (components & VB_HAS_COL1) + WRITE(p, " float4 color1 : COLOR1,\n"); + for (int i = 0; i < 8; ++i) { + u32 hastexmtx = (components & (VB_HAS_TEXMTXIDX0<<i)); + if ((components & (VB_HAS_UV0<<i)) || hastexmtx) + WRITE(p, " float%d tex%d : TEXCOORD%d,\n", hastexmtx ? 3 : 2, i, i); + } + if (components & VB_HAS_POSMTXIDX) { + if (is_d3d) + WRITE(p, " float4 blend_indices : BLENDINDICES,\n"); + else + WRITE(p, " float fposmtx : ATTR%d,\n", SHADER_POSMTX_ATTRIB); + } + WRITE(p, " float4 rawpos : POSITION) {\n"); } - WRITE(p, " float4 rawpos : POSITION) {\n"); WRITE(p, "VS_OUTPUT o;\n"); // transforms if (components & VB_HAS_POSMTXIDX) { - if (api_type & API_D3D9) + if (ApiType & API_D3D9) { WRITE(p, "int4 indices = D3DCOLORtoUBYTE4(blend_indices);\n"); WRITE(p, "int posmtx = indices.x;\n"); } - else if (api_type == API_D3D11) + else if (ApiType == API_D3D11) { WRITE(p, "int posmtx = blend_indices.x * 255.0f;\n"); } - else - { - WRITE(p, "int posmtx = fposmtx;\n"); - } - WRITE(p, "float4 pos = float4(dot(" I_TRANSFORMMATRICES".T[posmtx].t, rawpos), dot(" I_TRANSFORMMATRICES".T[posmtx+1].t, rawpos), dot(" I_TRANSFORMMATRICES".T[posmtx+2].t, rawpos), 1);\n"); + WRITE(p, "float4 pos = float4(dot(" I_TRANSFORMMATRICES"[posmtx], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+1], rawpos), dot(" I_TRANSFORMMATRICES"[posmtx+2], rawpos), 1);\n"); if (components & VB_HAS_NRMALL) { WRITE(p, "int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n"); - WRITE(p, "float3 N0 = " I_NORMALMATRICES".T[normidx].t.xyz, N1 = " I_NORMALMATRICES".T[normidx+1].t.xyz, N2 = " I_NORMALMATRICES".T[normidx+2].t.xyz;\n"); + WRITE(p, "float3 N0 = " I_NORMALMATRICES"[normidx].xyz, N1 = " I_NORMALMATRICES"[normidx+1].xyz, N2 = " I_NORMALMATRICES"[normidx+2].xyz;\n"); } if (components & VB_HAS_NRM0) @@ -274,27 +322,25 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) } else { - WRITE(p, "float4 pos = float4(dot(" I_POSNORMALMATRIX".T0, rawpos), dot(" I_POSNORMALMATRIX".T1, rawpos), dot(" I_POSNORMALMATRIX".T2, rawpos), 1.0f);\n"); + WRITE(p, "float4 pos = float4(dot(" I_POSNORMALMATRIX"[0], rawpos), dot(" I_POSNORMALMATRIX"[1], rawpos), dot(" I_POSNORMALMATRIX"[2], rawpos), 1.0f);\n"); if (components & VB_HAS_NRM0) - WRITE(p, "float3 _norm0 = normalize(float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm0), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm0)));\n"); + WRITE(p, "float3 _norm0 = normalize(float3(dot(" I_POSNORMALMATRIX"[3].xyz, rawnorm0), dot(" I_POSNORMALMATRIX"[4].xyz, rawnorm0), dot(" I_POSNORMALMATRIX"[5].xyz, rawnorm0)));\n"); if (components & VB_HAS_NRM1) - WRITE(p, "float3 _norm1 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm1), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm1));\n"); + WRITE(p, "float3 _norm1 = float3(dot(" I_POSNORMALMATRIX"[3].xyz, rawnorm1), dot(" I_POSNORMALMATRIX"[4].xyz, rawnorm1), dot(" I_POSNORMALMATRIX"[5].xyz, rawnorm1));\n"); if (components & VB_HAS_NRM2) - WRITE(p, "float3 _norm2 = float3(dot(" I_POSNORMALMATRIX".N0.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N1.xyz, rawnorm2), dot(" I_POSNORMALMATRIX".N2.xyz, rawnorm2));\n"); + WRITE(p, "float3 _norm2 = float3(dot(" I_POSNORMALMATRIX"[3].xyz, rawnorm2), dot(" I_POSNORMALMATRIX"[4].xyz, rawnorm2), dot(" I_POSNORMALMATRIX"[5].xyz, rawnorm2));\n"); } if (!(components & VB_HAS_NRM0)) WRITE(p, "float3 _norm0 = float3(0.0f, 0.0f, 0.0f);\n"); - - - WRITE(p, "o.pos = float4(dot(" I_PROJECTION".T0, pos), dot(" I_PROJECTION".T1, pos), dot(" I_PROJECTION".T2, pos), dot(" I_PROJECTION".T3, pos));\n"); + WRITE(p, "o.pos = float4(dot(" I_PROJECTION"[0], pos), dot(" I_PROJECTION"[1], pos), dot(" I_PROJECTION"[2], pos), dot(" I_PROJECTION"[3], pos));\n"); WRITE(p, "float4 mat, lacc;\n" "float3 ldir, h;\n" "float dist, dist2, attn;\n"); - if(xfregs.numChan.numColorChans == 0) + if (xfregs.numChan.numColorChans == 0) { if (components & VB_HAS_COL0) WRITE(p, "o.colors_0 = color0;\n"); @@ -305,7 +351,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) // TODO: This probably isn't necessary if pixel lighting is enabled. p = GenerateLightingShader(p, components, I_MATERIALS, I_LIGHTS, "color", "o.colors_"); - if(xfregs.numChan.numColorChans < 2) + if (xfregs.numChan.numColorChans < 2) { if (components & VB_HAS_COL1) WRITE(p, "o.colors_1 = color1;\n"); @@ -367,7 +413,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) 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, "ldir = normalize(" I_LIGHTS"[%d + 3].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); } else @@ -387,18 +433,20 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) break; case XF_TEXGEN_REGULAR: default: - if (components & (VB_HAS_TEXMTXIDX0<<i)) { + if (components & (VB_HAS_TEXMTXIDX0<<i)) + { + WRITE(p, "int tmp = int(tex%d.z);\n", 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); + WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TRANSFORMMATRICES"[tmp]), dot(coord, " I_TRANSFORMMATRICES"[tmp+1]), dot(coord, " I_TRANSFORMMATRICES"[tmp+2]));\n", 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); + WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TRANSFORMMATRICES"[tmp]), dot(coord, " I_TRANSFORMMATRICES"[tmp+1]), 1);\n", 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); + WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]));\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); + WRITE(p, "o.tex%d.xyz = float3(dot(coord, " I_TEXMATRICES"[%d]), dot(coord, " I_TEXMATRICES"[%d]), 1);\n", i, 3*i, 3*i+1); } break; } @@ -407,9 +455,9 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) const PostMtxInfo& postInfo = xfregs.postMtxInfo[i]; int postidx = postInfo.index; - WRITE(p, "float4 P0 = " I_POSTTRANSFORMMATRICES".T[%d].t;\n" - "float4 P1 = " I_POSTTRANSFORMMATRICES".T[%d].t;\n" - "float4 P2 = " I_POSTTRANSFORMMATRICES".T[%d].t;\n", + WRITE(p, "float4 P0 = " I_POSTTRANSFORMMATRICES"[%d];\n" + "float4 P1 = " I_POSTTRANSFORMMATRICES"[%d];\n" + "float4 P2 = " I_POSTTRANSFORMMATRICES"[%d];\n", postidx&0x3f, (postidx+1)&0x3f, (postidx+2)&0x3f); if (texGenSpecialCase) { @@ -455,9 +503,9 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) WRITE(p, "o.tex7 = pos.xyzz;\n"); else WRITE(p, "o.tex7.w = pos.z;\n"); - } + } if (components & VB_HAS_COL0) - WRITE(p, "o.colors_0 = color0;\n"); + WRITE(p, "o.colors_0 = color0;\n"); if (components & VB_HAS_COL1) WRITE(p, "o.colors_1 = color1;\n"); @@ -465,44 +513,77 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type) //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values //if not early z culling will improve speed - // TODO: Can probably be dropped? if (is_d3d) { WRITE(p, "o.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); } else { - // this results in a scale from -1..0 to -1..1 after perspective - // divide - WRITE(p, "o.pos.z = o.pos.w + o.pos.z * 2.0f;\n"); - - // Sonic Unleashed puts its final rendering at the near or - // far plane of the viewing frustrum(actually box, they use - // orthogonal projection for that), and we end up putting it - // just beyond, and the rendering gets clipped away. (The - // primitive gets dropped) - WRITE(p, "o.pos.z = o.pos.z * 1048575.0f/1048576.0f;\n"); - - // the next steps of the OGL pipeline are: - // (x_c,y_c,z_c,w_c) = o.pos //switch to OGL spec terminology - // clipping to -w_c <= (x_c,y_c,z_c) <= w_c - // (x_d,y_d,z_d) = (x_c,y_c,z_c)/w_c//perspective divide - // z_w = (f-n)/2*z_d + (n+f)/2 - // z_w now contains the value to go to the 0..1 depth buffer - - //trying to get the correct semantic while not using glDepthRange - //seems to get rather complicated + // this results in a scale from -1..0 to -1..1 after perspective + // divide + WRITE(p, "o.pos.z = o.pos.w + o.pos.z * 2.0f;\n"); + + // Sonic Unleashed puts its final rendering at the near or + // far plane of the viewing frustrum(actually box, they use + // orthogonal projection for that), and we end up putting it + // just beyond, and the rendering gets clipped away. (The + // primitive gets dropped) + WRITE(p, "o.pos.z = o.pos.z * 1048575.0f/1048576.0f;\n"); + + // the next steps of the OGL pipeline are: + // (x_c,y_c,z_c,w_c) = o.pos //switch to OGL spec terminology + // clipping to -w_c <= (x_c,y_c,z_c) <= w_c + // (x_d,y_d,z_d) = (x_c,y_c,z_c)/w_c//perspective divide + // z_w = (f-n)/2*z_d + (n+f)/2 + // z_w now contains the value to go to the 0..1 depth buffer + + //trying to get the correct semantic while not using glDepthRange + //seems to get rather complicated } - if (api_type & API_D3D9) + if (ApiType & API_D3D9) { // D3D9 is addressing pixel centers instead of pixel boundaries in clip space. // Thus we need to offset the final position by half a pixel WRITE(p, "o.pos = o.pos + float4(" I_DEPTHPARAMS".z, " I_DEPTHPARAMS".w, 0.f, 0.f);\n"); } - WRITE(p, "return o;\n}\n"); + if(ApiType == API_OPENGL) + { + // Bit ugly here + // TODO: Make pretty + // Will look better when we bind uniforms in GLSL 1.3 + // clipPos/w needs to be done in pixel shader, not here + if (xfregs.numTexGen.numTexGens < 7) { + for (unsigned int i = 0; i < 8; ++i) + if(i < xfregs.numTexGen.numTexGens) + WRITE(p, " uv%d_2.xyz = o.tex%d;\n", i, i); + else + WRITE(p, " uv%d_2.xyz = float3(0.0f, 0.0f, 0.0f);\n", i); + WRITE(p, " clipPos_2 = o.clipPos;\n"); + if(g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) + WRITE(p, " Normal_2 = o.Normal;\n"); + } else { + // clip position is in w of first 4 texcoords + if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) + { + for (int i = 0; i < 8; ++i) + WRITE(p, " uv%d_2 = o.tex%d;\n", i, i); + } + else + { + for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i) + WRITE(p, " uv%d_2%s = o.tex%d;\n", i, i < 4 ? ".xyzw" : ".xyz" , i); + } + } + WRITE(p, "colors_02 = o.colors_0;\n"); + WRITE(p, "colors_12 = o.colors_1;\n"); + WRITE(p, "gl_Position = o.pos;\n"); + WRITE(p, "}\n"); + } + else + WRITE(p, "return o;\n}\n"); if (text[sizeof(text) - 1] != 0x7C) PanicAlert("VertexShader generator - buffer too small, canary has been eaten!"); |
