From 2c0bee5da9db003a984f0896cb629e0411bdfcde Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 21 Dec 2014 12:06:01 +0100 Subject: [PATCH 1/5] DriverDetails: Update Intel bug description. --- Source/Core/VideoBackends/OGL/Render.cpp | 2 +- Source/Core/VideoCommon/DriverDetails.cpp | 2 +- Source/Core/VideoCommon/DriverDetails.h | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index be3b37c580..949c0c707b 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -463,7 +463,7 @@ Renderer::Renderer() g_Config.backend_info.bSupportsBBox = GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"); g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5"); g_Config.backend_info.bSupportsGeometryShaders = (GLExtensions::Version() >= 320) && - !DriverDetails::HasBug(DriverDetails::BUG_INTELBROKENINTERFACEBLOCKS); + !DriverDetails::HasBug(DriverDetails::BUG_INTELBROKENSTRUCTS); // Desktop OpenGL supports the binding layout if it supports 420pack // OpenGL ES 3.1 supports it implicitly without an extension diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index 1a7baccc38..220ae647d3 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -59,7 +59,7 @@ namespace DriverDetails {OS_WINDOWS,VENDOR_NVIDIA, DRIVER_NVIDIA, -1, BUG_BROKENUNSYNCMAPPING, -1.0, -1.0, true}, {OS_LINUX, VENDOR_NVIDIA, DRIVER_NVIDIA, -1, BUG_BROKENUNSYNCMAPPING, -1.0, -1.0, true}, {OS_WINDOWS,VENDOR_INTEL, DRIVER_INTEL, -1, BUG_INTELBROKENBUFFERSTORAGE, 101810.3907, 101810.3960, true}, - {OS_WINDOWS,VENDOR_INTEL, DRIVER_INTEL, -1, BUG_INTELBROKENINTERFACEBLOCKS, -1.0, -1.0, true}, + {OS_WINDOWS,VENDOR_INTEL, DRIVER_INTEL, -1, BUG_INTELBROKENSTRUCTS, -1.0, -1.0, true}, }; static std::map m_bugs; diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index c04114349b..3485b5e4dd 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -200,15 +200,14 @@ namespace DriverDetails // Broken on Windows Intel // if (cond == false) BUG_BROKENNEGATEDBOOLEAN, - // Bug: Intel's Windows driver breaks interface blocks that contain structs. + // Bug: Intel's Windows driver can't pass structs between shader stages. // Affected devices: Intel (Windows) // Started Version: -1 // Ended Version: -1 - // We need interface blocks to make the geometry shader optional and we need structs to make - // assignment easier in the geometry shader stage. However Intel's Windows drivers don't seem - // to be able handle this combination. + // We need structs to make assignment easier in the geometry shader stage. However Intel's + // Windows drivers don't seem to be able handle passing them between shader stages. // TODO: Find affected versions. - BUG_INTELBROKENINTERFACEBLOCKS, + BUG_INTELBROKENSTRUCTS, }; From 7eb353b3bd05d7a24362c58ac61dcc40a04c3deb Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 21 Dec 2014 12:52:14 +0100 Subject: [PATCH 2/5] VideoCommon: Don't pass structs between shaders, use the interface blocks instead. --- Source/Core/VideoBackends/OGL/Render.cpp | 3 +- Source/Core/VideoCommon/GeometryShaderGen.cpp | 36 ++++++++++++----- Source/Core/VideoCommon/PixelShaderGen.cpp | 29 ++++++-------- Source/Core/VideoCommon/ShaderGenCommon.h | 40 +++++++++++++------ Source/Core/VideoCommon/VertexShaderGen.cpp | 10 +++-- 5 files changed, 74 insertions(+), 44 deletions(-) diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 949c0c707b..8bb1ecc8f2 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -462,8 +462,7 @@ Renderer::Renderer() g_Config.backend_info.bSupportsEarlyZ = GLExtensions::Supports("GL_ARB_shader_image_load_store"); g_Config.backend_info.bSupportsBBox = GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"); g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5"); - g_Config.backend_info.bSupportsGeometryShaders = (GLExtensions::Version() >= 320) && - !DriverDetails::HasBug(DriverDetails::BUG_INTELBROKENSTRUCTS); + g_Config.backend_info.bSupportsGeometryShaders = GLExtensions::Version() >= 320; // Desktop OpenGL supports the binding layout if it supports 420pack // OpenGL ES 3.1 supports it implicitly without an extension diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 7e8fa080e2..0a49487bf8 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -84,7 +84,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A uid_data->numTexGens = bpmem.genMode.numtexgens; uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; - GenerateVSOutputStruct(out, ApiType); + out.Write("struct VS_OUTPUT {\n"); + GenerateVSOutputMembers(out, ApiType); + out.Write("};\n"); if (ApiType == API_OPENGL) { @@ -92,11 +94,11 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("#define InstanceID gl_InvocationID\n"); out.Write("in VertexData {\n"); - out.Write("\tcentroid %s VS_OUTPUT o;\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "in"); + GenerateVSOutputMembers(out, ApiType, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid in"); out.Write("} vs[%d];\n", vertex_in); out.Write("out VertexData {\n"); - out.Write("\tcentroid %s VS_OUTPUT o;\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "out"); + GenerateVSOutputMembers(out, ApiType, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid out"); if (g_ActiveConfig.iStereoMode > 0) out.Write("\tflat int layer;\n"); @@ -133,8 +135,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A { if (ApiType == API_OPENGL) { - out.Write("\tVS_OUTPUT start = vs[0].o;\n"); - out.Write("\tVS_OUTPUT end = vs[1].o;\n"); + out.Write("\tVS_OUTPUT start, end;\n"); + AssignVSOutputMembers(out, "start", "vs[0]"); + AssignVSOutputMembers(out, "end", "vs[1]"); } else { @@ -163,9 +166,14 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A else if (primitive_type == PRIMITIVE_POINTS) { if (ApiType == API_OPENGL) - out.Write("\tVS_OUTPUT center = vs[0].o;\n"); + { + out.Write("\tVS_OUTPUT center;\n"); + AssignVSOutputMembers(out, "center", "vs[0]"); + } else + { out.Write("\tVS_OUTPUT center = o[0];\n"); + } // Offset from center to upper right vertex // Lerp PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1] @@ -188,9 +196,14 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tfor (int i = 0; i < %d; ++i) {\n", vertex_in); if (ApiType == API_OPENGL) - out.Write("\tVS_OUTPUT f = vs[i].o;\n"); + { + out.Write("\tVS_OUTPUT f;\n"); + AssignVSOutputMembers(out, "f", "vs[i]"); + } else + { out.Write("\tVS_OUTPUT f = o[i];\n"); + } if (g_ActiveConfig.iStereoMode > 0) { @@ -289,9 +302,14 @@ static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool out.Write("\tif (i == 0) first = %s;\n", vertex); if (ApiType == API_OPENGL) + { out.Write("\tgl_Position = %s.pos;\n", vertex); - - out.Write("\tps.o = %s;\n", vertex); + AssignVSOutputMembers(out, "ps", vertex); + } + else + { + out.Write("\tps.o = %s;\n", vertex); + } if (ApiType == API_OPENGL) out.Write("\tEmitVertex();\n"); diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index e2c0168d13..f7b63bfb30 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -264,7 +264,9 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T } } - GenerateVSOutputStruct(out, ApiType); + out.Write("struct VS_OUTPUT {\n"); + GenerateVSOutputMembers(out, ApiType); + out.Write("};\n"); const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED); const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z); @@ -320,7 +322,7 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) { out.Write("in VertexData {\n"); - out.Write("\tcentroid %s VS_OUTPUT o;\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "in"); + GenerateVSOutputMembers(out, ApiType, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid in"); if (g_ActiveConfig.iStereoMode > 0) out.Write("\tflat int layer;\n"); @@ -348,23 +350,16 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) { - // compute window position if needed because binding semantic WPOS is not widely supported - // Let's set up attributes for (unsigned int i = 0; i < numTexgen; ++i) - { - out.Write("\tfloat3 uv%d = o.tex%d;\n", i, i); - } - out.Write("\tfloat4 clipPos = o.clipPos;\n"); - if (g_ActiveConfig.bEnablePixelLighting) - { - out.Write("\tfloat4 Normal = o.Normal;\n"); - } + out.Write("\tfloat3 uv%d = tex%d;\n", i, i); + } + else + { + // On Mali, global variables must be initialized as constants. + // This is why we initialize these variables locally instead. + out.Write("\tfloat4 colors_0 = colors_02;\n"); + out.Write("\tfloat4 colors_1 = colors_12;\n"); } - - // On Mali, global variables must be initialized as constants. - // This is why we initialize these variables locally instead. - out.Write("\tfloat4 colors_0 = %s;\n", g_ActiveConfig.backend_info.bSupportsGeometryShaders ? "o.colors_0" : "colors_02"); - out.Write("\tfloat4 colors_1 = %s;\n", g_ActiveConfig.backend_info.bSupportsGeometryShaders ? "o.colors_1" : "colors_12"); out.Write("\tfloat4 rawpos = gl_FragCoord;\n"); } diff --git a/Source/Core/VideoCommon/ShaderGenCommon.h b/Source/Core/VideoCommon/ShaderGenCommon.h index 444abad82c..505ef2f116 100644 --- a/Source/Core/VideoCommon/ShaderGenCommon.h +++ b/Source/Core/VideoCommon/ShaderGenCommon.h @@ -221,9 +221,13 @@ private: }; template -static void DefineOutputStructMember(T& object, API_TYPE api_type, const char* type, const char* name, int var_index, const char* semantic = "", int semantic_index = -1) +static void DefineOutputMember(T& object, API_TYPE api_type, const char* qualifier, const char* type, const char* name, int var_index, const char* semantic = "", int semantic_index = -1) { - object.Write(" %s %s", type, name); + if (qualifier != nullptr) + object.Write("\t%s %s %s", qualifier, type, name); + else + object.Write("\t%s %s", type, name); + if (var_index != -1) object.Write("%d", var_index); @@ -239,23 +243,35 @@ static void DefineOutputStructMember(T& object, API_TYPE api_type, const char* t } template -static inline void GenerateVSOutputStruct(T& object, API_TYPE api_type) +static inline void GenerateVSOutputMembers(T& object, API_TYPE api_type, const char* qualifier = nullptr) { - object.Write("struct VS_OUTPUT {\n"); - - DefineOutputStructMember(object, api_type, "float4", "pos", -1, "POSITION"); - DefineOutputStructMember(object, api_type, "float4", "colors_", 0, "COLOR", 0); - DefineOutputStructMember(object, api_type, "float4", "colors_", 1, "COLOR", 1); + DefineOutputMember(object, api_type, qualifier, "float4", "pos", -1, "POSITION"); + DefineOutputMember(object, api_type, qualifier, "float4", "colors_", 0, "COLOR", 0); + DefineOutputMember(object, api_type, qualifier, "float4", "colors_", 1, "COLOR", 1); for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i) - DefineOutputStructMember(object, api_type, "float3", "tex", i, "TEXCOORD", i); + DefineOutputMember(object, api_type, qualifier, "float3", "tex", i, "TEXCOORD", i); - DefineOutputStructMember(object, api_type, "float4", "clipPos", -1, "TEXCOORD", xfmem.numTexGen.numTexGens); + DefineOutputMember(object, api_type, qualifier, "float4", "clipPos", -1, "TEXCOORD", xfmem.numTexGen.numTexGens); if (g_ActiveConfig.bEnablePixelLighting) - DefineOutputStructMember(object, api_type, "float4", "Normal", -1, "TEXCOORD", xfmem.numTexGen.numTexGens + 1); + DefineOutputMember(object, api_type, qualifier, "float4", "Normal", -1, "TEXCOORD", xfmem.numTexGen.numTexGens + 1); +} - object.Write("};\n"); +template +static inline void AssignVSOutputMembers(T& object, const char* a, const char* b) +{ + object.Write("\t%s.pos = %s.pos;\n", a, b); + object.Write("\t%s.colors_0 = %s.colors_0;\n", a, b); + object.Write("\t%s.colors_1 = %s.colors_1;\n", a, b); + + for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i) + object.Write("\t%s.tex%d = %s.tex%d;\n", a, i, b, i); + + object.Write("\t%s.clipPos = %s.clipPos;\n", a, b); + + if (g_ActiveConfig.bEnablePixelLighting) + object.Write("\t%s.Normal = %s.Normal;\n", a, b); } // Constant variable names diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 10ebc89f86..b48d1a1738 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -42,7 +42,9 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ out.Write(s_shader_uniforms); out.Write("};\n"); - GenerateVSOutputStruct(out, api_type); + out.Write("struct VS_OUTPUT {\n"); + GenerateVSOutputMembers(out, api_type); + out.Write("};\n"); uid_data->numTexGens = xfmem.numTexGen.numTexGens; uid_data->components = components; @@ -74,9 +76,9 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) { - out.Write("out VertexData {\n" - "\tcentroid %s VS_OUTPUT o;\n" - "};\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "out"); + out.Write("out VertexData {\n"); + GenerateVSOutputMembers(out, api_type, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid out"); + out.Write("} o;\n"); } else { From 3f763e69992890f8b278411cf03aba779eb2d531 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 22 Dec 2014 02:47:31 +0100 Subject: [PATCH 3/5] DriverDetails: Remove Intel Structs bug since it doesn't affect us anymore. --- Source/Core/VideoCommon/DriverDetails.cpp | 1 - Source/Core/VideoCommon/DriverDetails.h | 8 -------- Source/Core/VideoCommon/VertexShaderGen.cpp | 4 ++-- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index 220ae647d3..dbcd45133f 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -59,7 +59,6 @@ namespace DriverDetails {OS_WINDOWS,VENDOR_NVIDIA, DRIVER_NVIDIA, -1, BUG_BROKENUNSYNCMAPPING, -1.0, -1.0, true}, {OS_LINUX, VENDOR_NVIDIA, DRIVER_NVIDIA, -1, BUG_BROKENUNSYNCMAPPING, -1.0, -1.0, true}, {OS_WINDOWS,VENDOR_INTEL, DRIVER_INTEL, -1, BUG_INTELBROKENBUFFERSTORAGE, 101810.3907, 101810.3960, true}, - {OS_WINDOWS,VENDOR_INTEL, DRIVER_INTEL, -1, BUG_INTELBROKENSTRUCTS, -1.0, -1.0, true}, }; static std::map m_bugs; diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index 3485b5e4dd..278e339fac 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -200,14 +200,6 @@ namespace DriverDetails // Broken on Windows Intel // if (cond == false) BUG_BROKENNEGATEDBOOLEAN, - // Bug: Intel's Windows driver can't pass structs between shader stages. - // Affected devices: Intel (Windows) - // Started Version: -1 - // Ended Version: -1 - // We need structs to make assignment easier in the geometry shader stage. However Intel's - // Windows drivers don't seem to be able handle passing them between shader stages. - // TODO: Find affected versions. - BUG_INTELBROKENSTRUCTS, }; diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index b48d1a1738..07b349dc35 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -388,8 +388,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ { if (!g_ActiveConfig.backend_info.bSupportsGeometryShaders) { - // TODO: Pass structs between shader stages even if geometry shaders - // are not supported, however that will break GL 3.0 and 3.1 support. + // TODO: Pass interface blocks between shader stages even if geometry shaders + // are not supported, however that will require at least OpenGL 3.2 support. for (unsigned int i = 0; i < xfmem.numTexGen.numTexGens; ++i) out.Write("uv%d.xyz = o.tex%d;\n", i, i); out.Write("clipPos = o.clipPos;\n"); From 8676891f773af96c38683cbf8489e6aa7bddc0c0 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 22 Dec 2014 03:36:39 +0100 Subject: [PATCH 4/5] VertexShaderGen: Don't read from output variables. --- Source/Core/VideoCommon/VertexShaderGen.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 07b349dc35..98ca1d8451 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -78,7 +78,7 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ { out.Write("out VertexData {\n"); GenerateVSOutputMembers(out, api_type, g_ActiveConfig.backend_info.bSupportsBindingLayout ? "centroid" : "centroid out"); - out.Write("} o;\n"); + out.Write("} vs;\n"); } else { @@ -98,9 +98,6 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ } out.Write("void main()\n{\n"); - - if (!g_ActiveConfig.backend_info.bSupportsGeometryShaders) - out.Write("VS_OUTPUT o;\n"); } else // D3D { @@ -126,10 +123,10 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ if (components & VB_HAS_POSMTXIDX) out.Write(" int posmtx : BLENDINDICES,\n"); out.Write(" float4 rawpos : POSITION) {\n"); - - out.Write("VS_OUTPUT o;\n"); } + out.Write("VS_OUTPUT o;\n"); + // transforms if (components & VB_HAS_POSMTXIDX) { @@ -386,7 +383,11 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ if (api_type == API_OPENGL) { - if (!g_ActiveConfig.backend_info.bSupportsGeometryShaders) + if (g_ActiveConfig.backend_info.bSupportsGeometryShaders) + { + AssignVSOutputMembers(out, "vs", "o"); + } + else { // TODO: Pass interface blocks between shader stages even if geometry shaders // are not supported, however that will require at least OpenGL 3.2 support. From 3ed777b0f99a2cbbc77c35a8e3b87f364cbc0630 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 26 Dec 2014 00:56:12 +0100 Subject: [PATCH 5/5] PixelShaderGen: Don't assign to input variables. --- Source/Core/VideoCommon/LightingShaderGen.h | 2 +- Source/Core/VideoCommon/PixelShaderGen.cpp | 26 +++++++++++---------- Source/Core/VideoCommon/VertexShaderGen.cpp | 8 +++---- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Source/Core/VideoCommon/LightingShaderGen.h b/Source/Core/VideoCommon/LightingShaderGen.h index 05f4e607c5..b28fe5b386 100644 --- a/Source/Core/VideoCommon/LightingShaderGen.h +++ b/Source/Core/VideoCommon/LightingShaderGen.h @@ -264,7 +264,7 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com GenerateLightShader(object, uid_data, i, lit_index, coloralpha); } } - object.Write("lacc = clamp(lacc, 0, 255);"); + object.Write("lacc = clamp(lacc, 0, 255);\n"); object.Write("%s%d = float4((mat * (lacc + (lacc >> 7))) >> 8) / 255.0;\n", dest, j); object.Write("}\n"); } diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index f7b63bfb30..77ccd0b683 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -124,8 +124,8 @@ static const char *tevAInputTable[] = static const char *tevRasTable[] = { - "iround(colors_0 * 255.0)", - "iround(colors_1 * 255.0)", + "iround(col0 * 255.0)", + "iround(col1 * 255.0)", "ERROR13", //2 "ERROR14", //3 "ERROR15", //4 @@ -331,8 +331,8 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T } else { - out.Write("centroid in float4 colors_02;\n"); - out.Write("centroid in float4 colors_12;\n"); + out.Write("centroid in float4 colors_0;\n"); + out.Write("centroid in float4 colors_1;\n"); // compute window position if needed because binding semantic WPOS is not widely supported // Let's set up attributes for (unsigned int i = 0; i < numTexgen; ++i) @@ -353,13 +353,6 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T for (unsigned int i = 0; i < numTexgen; ++i) out.Write("\tfloat3 uv%d = tex%d;\n", i, i); } - else - { - // On Mali, global variables must be initialized as constants. - // This is why we initialize these variables locally instead. - out.Write("\tfloat4 colors_0 = colors_02;\n"); - out.Write("\tfloat4 colors_1 = colors_12;\n"); - } out.Write("\tfloat4 rawpos = gl_FragCoord;\n"); } @@ -402,13 +395,22 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T "\tfloat3 ldir, h;\n" "\tfloat dist, dist2, attn;\n"); + // On GLSL, input variables must not be assigned to. + // This is why we declare these variables locally instead. + out.Write("\tfloat4 col0, col1;\n"); + // TODO: Our current constant usage code isn't able to handle more than one buffer. // So we can't mark the VS constant as used here. But keep them here as reference. //out.SetConstantsUsed(C_PLIGHT_COLORS, C_PLIGHT_COLORS+7); // TODO: Can be optimized further //out.SetConstantsUsed(C_PLIGHTS, C_PLIGHTS+31); // TODO: Can be optimized further //out.SetConstantsUsed(C_PMATERIALS, C_PMATERIALS+3); uid_data->components = components; - GenerateLightingShader(out, uid_data->lighting, components, "colors_", "colors_"); + GenerateLightingShader(out, uid_data->lighting, components, "colors_", "col"); + } + else + { + out.Write("\tfloat4 col0 = colors_0;\n"); + out.Write("\tfloat4 col1 = colors_1;\n"); } // HACK to handle cases where the tex gen is not enabled diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index 98ca1d8451..e30f28d463 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -93,8 +93,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ out.Write("centroid out float4 clipPos;\n"); if (g_ActiveConfig.bEnablePixelLighting) out.Write("centroid out float4 Normal;\n"); - out.Write("centroid out float4 colors_02;\n"); - out.Write("centroid out float4 colors_12;\n"); + out.Write("centroid out float4 colors_0;\n"); + out.Write("centroid out float4 colors_1;\n"); } out.Write("void main()\n{\n"); @@ -396,8 +396,8 @@ static inline void GenerateVertexShader(T& out, u32 components, API_TYPE api_typ out.Write("clipPos = o.clipPos;\n"); if (g_ActiveConfig.bEnablePixelLighting) out.Write("Normal = o.Normal;\n"); - out.Write("colors_02 = o.colors_0;\n"); - out.Write("colors_12 = o.colors_1;\n"); + out.Write("colors_0 = o.colors_0;\n"); + out.Write("colors_1 = o.colors_1;\n"); } out.Write("gl_Position = o.pos;\n");