From b005f61a2e8e34e9de10183d1fe6f873f7dd9133 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Thu, 16 Oct 2014 18:52:32 +0200 Subject: Add geometry shader generator for stereo 3D. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 109 ++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Source/Core/VideoCommon/GeometryShaderGen.cpp (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp new file mode 100644 index 0000000000..1da342d68a --- /dev/null +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -0,0 +1,109 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include +#include +#ifdef __APPLE__ + #include +#endif + +#include "VideoCommon/GeometryShaderGen.h" +#include "VideoCommon/VideoConfig.h" +#include "VideoCommon/VertexShaderGen.h" +#include "VideoCommon/LightingShaderGen.h" + +static char text[16384]; + +template +static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiType) +{ + // Non-uid template parameters will write to the dummy data (=> gets optimized out) + geometry_shader_uid_data dummy_data; + geometry_shader_uid_data* uid_data = out.template GetUidData(); + if (uid_data == nullptr) + uid_data = &dummy_data; + + out.SetBuffer(text); + const bool is_writing_shadercode = (out.GetBuffer() != nullptr); +#ifndef ANDROID + locale_t locale; + locale_t old_locale; + if (is_writing_shadercode) + { + locale = newlocale(LC_NUMERIC_MASK, "C", nullptr); // New locale for compilation + old_locale = uselocale(locale); // Apply the locale for this thread + } +#endif + + if (is_writing_shadercode) + text[sizeof(text) - 1] = 0x7C; // canary + + out.Write("//Geometry Shader for 3D stereoscopy\n"); + + if (ApiType == API_OPENGL) + { + // Insert layout parameters + out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.bStereo ? 2 : 1); + out.Write("layout(triangle_strip, max_vertices = 3) out;\n"); + } + + out.Write("%s", s_lighting_struct); + + // uniforms + /*if (ApiType == API_OPENGL) + out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : ""); + else + out.Write("cbuffer VSBlock {\n"); + out.Write( + "\tfloat4 " I_POSNORMALMATRIX"[6];\n" + "\tfloat4 " I_PROJECTION"[4];\n" + "\tint4 " I_MATERIALS"[4];\n" + "\tLight " I_LIGHTS"[8];\n" + "\tfloat4 " I_TEXMATRICES"[24];\n" + "\tfloat4 " I_TRANSFORMMATRICES"[64];\n" + "\tfloat4 " I_NORMALMATRICES"[32];\n" + "\tfloat4 " I_POSTTRANSFORMMATRICES"[64];\n" + "\tfloat4 " I_DEPTHPARAMS";\n" + "};\n");*/ + + ShaderCode code; + char buf[16384]; + code.SetBuffer(buf); + GenerateVSOutputStructForGS(code, ApiType); + out.Write(code.GetBuffer()); + + out.Write("in VS_OUTPUT vertices[];\n"); + out.Write("out VS_OUTPUT frag;\n"); + + out.Write("void main()\n{\n"); + out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); + out.Write("\t\tfrag = vertices[i];\n"); + out.Write("\t\tgl_Position = gl_in[i].gl_Position;\n"); + out.Write("\t\tgl_Layer = gl_InvocationID;\n"); + out.Write("\t\tEmitVertex();\n"); + out.Write("\t}\n"); + out.Write("\tEndPrimitive();\n"); + out.Write("}\n"); + + if (is_writing_shadercode) + { + if (text[sizeof(text) - 1] != 0x7C) + PanicAlert("GeometryShader generator - buffer too small, canary has been eaten!"); + +#ifndef ANDROID + uselocale(old_locale); // restore locale + freelocale(locale); +#endif + } +} + +void GetGeometryShaderUid(GeometryShaderUid& object, u32 components, API_TYPE ApiType) +{ + GenerateGeometryShader(object, components, ApiType); +} + +void GenerateGeometryShaderCode(ShaderCode& object, u32 components, API_TYPE ApiType) +{ + GenerateGeometryShader(object, components, ApiType); +} -- cgit v1.2.3 From 2d8ec62bebb485c584887e24bd957ad4b08a4281 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 25 Oct 2014 02:05:49 +0200 Subject: Pass VS_OUTPUT structs between shaders. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 1da342d68a..991189a27f 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -73,12 +73,12 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy GenerateVSOutputStructForGS(code, ApiType); out.Write(code.GetBuffer()); - out.Write("in VS_OUTPUT vertices[];\n"); - out.Write("out VS_OUTPUT frag;\n"); + out.Write("centroid in VS_OUTPUT v[];\n"); + out.Write("centroid out VS_OUTPUT o;\n"); out.Write("void main()\n{\n"); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); - out.Write("\t\tfrag = vertices[i];\n"); + out.Write("\t\to = v[i];\n"); out.Write("\t\tgl_Position = gl_in[i].gl_Position;\n"); out.Write("\t\tgl_Layer = gl_InvocationID;\n"); out.Write("\t\tEmitVertex();\n"); -- cgit v1.2.3 From f6ea293027e553cf89f780ec2a1b716cc026a4b5 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 26 Oct 2014 19:17:00 +0100 Subject: VertexShaderManager: Compute stereoscopy projection matrices. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 991189a27f..9f1b5b69b4 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -51,7 +51,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("%s", s_lighting_struct); // uniforms - /*if (ApiType == API_OPENGL) + if (ApiType == API_OPENGL) out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : ""); else out.Write("cbuffer VSBlock {\n"); @@ -65,7 +65,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy "\tfloat4 " I_NORMALMATRICES"[32];\n" "\tfloat4 " I_POSTTRANSFORMMATRICES"[64];\n" "\tfloat4 " I_DEPTHPARAMS";\n" - "};\n");*/ + "\tfloat4 " I_STEREOPROJECTION"[8];\n" + "};\n"); ShaderCode code; char buf[16384]; @@ -79,7 +80,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("void main()\n{\n"); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); - out.Write("\t\tgl_Position = gl_in[i].gl_Position;\n"); + out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[gl_InvocationID * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[gl_InvocationID * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[gl_InvocationID * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[gl_InvocationID * 4 + 3], v[i].rawpos)); \n"); + out.Write("\t\tgl_Position = o.pos;\n"); out.Write("\t\tgl_Layer = gl_InvocationID;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); -- cgit v1.2.3 From d9e280e338b9b05d3651a5fe53d933999310aa7c Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 27 Oct 2014 00:29:37 +0100 Subject: PixelShaderGen: Sample the correct texture layer. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 9f1b5b69b4..c8467b9f4c 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -77,12 +77,15 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("centroid in VS_OUTPUT v[];\n"); out.Write("centroid out VS_OUTPUT o;\n"); + out.Write("flat out int eye;\n"); + out.Write("void main()\n{\n"); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); - out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[gl_InvocationID * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[gl_InvocationID * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[gl_InvocationID * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[gl_InvocationID * 4 + 3], v[i].rawpos)); \n"); + out.Write("\t\teye = gl_InvocationID;\n"); + out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[eye * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 3], v[i].rawpos)); \n"); out.Write("\t\tgl_Position = o.pos;\n"); - out.Write("\t\tgl_Layer = gl_InvocationID;\n"); + out.Write("\t\tgl_Layer = eye;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); out.Write("\tEndPrimitive();\n"); -- cgit v1.2.3 From 272ea90ca5e7a7f2c6e9a101b7b9e899b2757a70 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 27 Oct 2014 17:38:22 +0100 Subject: GeometryShaderGen: Allow stereoscopy to be disabled. Will facilitate future use of this generator for other purposes. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index c8467b9f4c..e305551cd8 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -44,6 +44,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (ApiType == API_OPENGL) { // Insert layout parameters + uid_data->stereo = g_ActiveConfig.bStereo; out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.bStereo ? 2 : 1); out.Write("layout(triangle_strip, max_vertices = 3) out;\n"); } @@ -83,7 +84,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); out.Write("\t\teye = gl_InvocationID;\n"); - out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[eye * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 3], v[i].rawpos)); \n"); + if (g_ActiveConfig.bStereo) + out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[eye * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 3], v[i].rawpos)); \n"); out.Write("\t\tgl_Position = o.pos;\n"); out.Write("\t\tgl_Layer = eye;\n"); out.Write("\t\tEmitVertex();\n"); -- cgit v1.2.3 From fa32f751d37604b7af46e7d9d118aacefbc5df76 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 29 Oct 2014 13:16:24 +0100 Subject: ShaderGen: Handle ShaderCode objects directly. ShaderGeneratorInterface does not have virtual function members, so we have to implement each type explicitly. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index e305551cd8..749929e8ea 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -69,11 +69,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy "\tfloat4 " I_STEREOPROJECTION"[8];\n" "};\n"); - ShaderCode code; - char buf[16384]; - code.SetBuffer(buf); - GenerateVSOutputStructForGS(code, ApiType); - out.Write(code.GetBuffer()); + GenerateVSOutputStruct(out, ApiType); out.Write("centroid in VS_OUTPUT v[];\n"); out.Write("centroid out VS_OUTPUT o;\n"); -- cgit v1.2.3 From 176191dc160145827d2dc86033f3af286c70669b Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 29 Oct 2014 14:15:12 +0100 Subject: ShaderGenCommon: Move uniforms into a common static string. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 749929e8ea..20636cccb8 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -56,18 +56,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : ""); else out.Write("cbuffer VSBlock {\n"); - out.Write( - "\tfloat4 " I_POSNORMALMATRIX"[6];\n" - "\tfloat4 " I_PROJECTION"[4];\n" - "\tint4 " I_MATERIALS"[4];\n" - "\tLight " I_LIGHTS"[8];\n" - "\tfloat4 " I_TEXMATRICES"[24];\n" - "\tfloat4 " I_TRANSFORMMATRICES"[64];\n" - "\tfloat4 " I_NORMALMATRICES"[32];\n" - "\tfloat4 " I_POSTTRANSFORMMATRICES"[64];\n" - "\tfloat4 " I_DEPTHPARAMS";\n" - "\tfloat4 " I_STEREOPROJECTION"[8];\n" - "};\n"); + out.Write(s_shader_uniforms); + out.Write("};\n"); GenerateVSOutputStruct(out, ApiType); -- cgit v1.2.3 From d583720a59e51d75c7772d745fb541a5cf00e2b8 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 29 Oct 2014 14:51:12 +0100 Subject: GeometryShaderGen: Support stereoscopy on GPUs without support for instancing. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 20636cccb8..a6307fe722 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -45,8 +45,11 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy { // Insert layout parameters uid_data->stereo = g_ActiveConfig.bStereo; - out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.bStereo ? 2 : 1); - out.Write("layout(triangle_strip, max_vertices = 3) out;\n"); + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.bStereo ? 2 : 1); + else + out.Write("layout(triangles) in;\n"); + out.Write("layout(triangle_strip, max_vertices = %d) out;\n", g_ActiveConfig.backend_info.bSupportsGSInstancing ? 3 : 6); } out.Write("%s", s_lighting_struct); @@ -67,9 +70,12 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("flat out int eye;\n"); out.Write("void main()\n{\n"); + if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("\tfor (eye = 0; eye < %d; ++eye) {\n", g_ActiveConfig.bStereo ? 2 : 1); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); - out.Write("\t\teye = gl_InvocationID;\n"); + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("\t\teye = gl_InvocationID;\n"); if (g_ActiveConfig.bStereo) out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[eye * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 3], v[i].rawpos)); \n"); out.Write("\t\tgl_Position = o.pos;\n"); @@ -77,6 +83,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); out.Write("\tEndPrimitive();\n"); + if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("\t}\n"); out.Write("}\n"); if (is_writing_shadercode) -- cgit v1.2.3 From 63b37e29d1c5ea6ecb2342ef9ba01b165aac602e Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 29 Oct 2014 14:57:49 +0100 Subject: ShaderGen: Rename "eye" to "layer". Keeping things generic. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index a6307fe722..f016acd6f4 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -67,19 +67,19 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("centroid in VS_OUTPUT v[];\n"); out.Write("centroid out VS_OUTPUT o;\n"); - out.Write("flat out int eye;\n"); + out.Write("flat out int layer;\n"); out.Write("void main()\n{\n"); if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("\tfor (eye = 0; eye < %d; ++eye) {\n", g_ActiveConfig.bStereo ? 2 : 1); + out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.bStereo ? 2 : 1); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); if (g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("\t\teye = gl_InvocationID;\n"); + out.Write("\t\tlayer = gl_InvocationID;\n"); if (g_ActiveConfig.bStereo) - out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[eye * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[eye * 4 + 3], v[i].rawpos)); \n"); + out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[layer * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[layer * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[layer * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[layer * 4 + 3], v[i].rawpos)); \n"); out.Write("\t\tgl_Position = o.pos;\n"); - out.Write("\t\tgl_Layer = eye;\n"); + out.Write("\t\tgl_Layer = layer;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); out.Write("\tEndPrimitive();\n"); -- cgit v1.2.3 From 6cacfad010b05cd9d79056a81c4dc7d19ca57273 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Thu, 30 Oct 2014 02:08:15 +0100 Subject: GeometryShader: Transform the projection within the geometry shader. Reduces the amount of data transferred through uniforms. The shearing transformation is reduced to a single multiplication/addition for optimization. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index f016acd6f4..6a39e2ca1d 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -70,16 +70,18 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("flat out int layer;\n"); out.Write("void main()\n{\n"); - if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("\tlayer = gl_InvocationID;\n"); + else out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.bStereo ? 2 : 1); + out.Write("\tgl_Layer = layer;\n"); + out.Write("\tvec4 stereoproj = "I_PROJECTION"[0];\n"); + out.Write("\tstereoproj[2] += "I_STEREOOFFSET"[layer] * stereoproj[0];\n"); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); - if (g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("\t\tlayer = gl_InvocationID;\n"); if (g_ActiveConfig.bStereo) - out.Write("\t\to.pos = float4(dot(" I_STEREOPROJECTION"[layer * 4 + 0], v[i].rawpos), dot(" I_STEREOPROJECTION"[layer * 4 + 1], v[i].rawpos), dot(" I_STEREOPROJECTION"[layer * 4 + 2], v[i].rawpos), dot(" I_STEREOPROJECTION"[layer * 4 + 3], v[i].rawpos)); \n"); + out.Write("\t\to.pos = float4(dot(stereoproj, v[i].rawpos), dot(" I_PROJECTION"[1], v[i].rawpos), dot(" I_PROJECTION"[2], v[i].rawpos), dot(" I_PROJECTION"[3], v[i].rawpos)); \n"); out.Write("\t\tgl_Position = o.pos;\n"); - out.Write("\t\tgl_Layer = layer;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); out.Write("\tEndPrimitive();\n"); -- cgit v1.2.3 From f370cb386cccfa56e2ef677a55b27561c8217e7d Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Thu, 30 Oct 2014 14:24:23 +0100 Subject: ProgramShaderCache: Always generate a geometry shader UID, even if stereoscopy is disabled. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 6a39e2ca1d..a247899d5c 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -41,10 +41,10 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("//Geometry Shader for 3D stereoscopy\n"); + uid_data->stereo = g_ActiveConfig.bStereo; if (ApiType == API_OPENGL) { // Insert layout parameters - uid_data->stereo = g_ActiveConfig.bStereo; if (g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.bStereo ? 2 : 1); else -- cgit v1.2.3 From 4d9589b35f2629c558a9a7efdee3d66497fc0fc6 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Thu, 30 Oct 2014 15:13:31 +0100 Subject: Cosmetics. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index a247899d5c..88be1d4098 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -70,23 +70,30 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("flat out int layer;\n"); out.Write("void main()\n{\n"); + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\tlayer = gl_InvocationID;\n"); else out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.bStereo ? 2 : 1); + out.Write("\tgl_Layer = layer;\n"); out.Write("\tvec4 stereoproj = "I_PROJECTION"[0];\n"); out.Write("\tstereoproj[2] += "I_STEREOOFFSET"[layer] * stereoproj[0];\n"); + out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); + if (g_ActiveConfig.bStereo) out.Write("\t\to.pos = float4(dot(stereoproj, v[i].rawpos), dot(" I_PROJECTION"[1], v[i].rawpos), dot(" I_PROJECTION"[2], v[i].rawpos), dot(" I_PROJECTION"[3], v[i].rawpos)); \n"); + out.Write("\t\tgl_Position = o.pos;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); out.Write("\tEndPrimitive();\n"); + if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\t}\n"); + out.Write("}\n"); if (is_writing_shadercode) -- cgit v1.2.3 From 9b22e151803ccfb757eb9319f1b32e3d1999f42e Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Thu, 30 Oct 2014 23:29:56 +0100 Subject: VideoConfigDiag: Add stereoscopy options group. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 88be1d4098..cded3bdea1 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -41,12 +41,12 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("//Geometry Shader for 3D stereoscopy\n"); - uid_data->stereo = g_ActiveConfig.bStereo; + uid_data->stereo = g_ActiveConfig.iStereoMode > 0; if (ApiType == API_OPENGL) { // Insert layout parameters if (g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.bStereo ? 2 : 1); + out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); else out.Write("layout(triangles) in;\n"); out.Write("layout(triangle_strip, max_vertices = %d) out;\n", g_ActiveConfig.backend_info.bSupportsGSInstancing ? 3 : 6); @@ -74,7 +74,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\tlayer = gl_InvocationID;\n"); else - out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.bStereo ? 2 : 1); + out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); out.Write("\tgl_Layer = layer;\n"); out.Write("\tvec4 stereoproj = "I_PROJECTION"[0];\n"); @@ -83,7 +83,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); - if (g_ActiveConfig.bStereo) + if (g_ActiveConfig.iStereoMode > 0) out.Write("\t\to.pos = float4(dot(stereoproj, v[i].rawpos), dot(" I_PROJECTION"[1], v[i].rawpos), dot(" I_PROJECTION"[2], v[i].rawpos), dot(" I_PROJECTION"[3], v[i].rawpos)); \n"); out.Write("\t\tgl_Position = o.pos;\n"); -- cgit v1.2.3 From d7804a4d3e9a5cbc5347148a0e37aa669e9e9e2b Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Thu, 30 Oct 2014 23:40:03 +0100 Subject: Cosmetics. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index cded3bdea1..57fc4b7d8b 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -9,9 +9,9 @@ #endif #include "VideoCommon/GeometryShaderGen.h" -#include "VideoCommon/VideoConfig.h" -#include "VideoCommon/VertexShaderGen.h" #include "VideoCommon/LightingShaderGen.h" +#include "VideoCommon/VertexShaderGen.h" +#include "VideoCommon/VideoConfig.h" static char text[16384]; @@ -77,8 +77,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); out.Write("\tgl_Layer = layer;\n"); - out.Write("\tvec4 stereoproj = "I_PROJECTION"[0];\n"); - out.Write("\tstereoproj[2] += "I_STEREOOFFSET"[layer] * stereoproj[0];\n"); + out.Write("\tvec4 stereoproj = " I_PROJECTION"[0];\n"); + out.Write("\tstereoproj[2] += " I_STEREOOFFSET"[layer] * stereoproj[0];\n"); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); -- cgit v1.2.3 From acc65ee60807d7ec605f85bc101a4dc9a9a63e32 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 1 Nov 2014 23:55:04 +0100 Subject: GeometryShader: Replicate missing position manipulations from vertex shader. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 57fc4b7d8b..8260ed5f05 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -86,6 +86,16 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (g_ActiveConfig.iStereoMode > 0) out.Write("\t\to.pos = float4(dot(stereoproj, v[i].rawpos), dot(" I_PROJECTION"[1], v[i].rawpos), dot(" I_PROJECTION"[2], v[i].rawpos), dot(" I_PROJECTION"[3], v[i].rawpos)); \n"); + if (ApiType == API_D3D) + { + out.Write("\t\to.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); + } + else // OGL + { + out.Write("\t\to.pos.z = o.pos.w + o.pos.z * 2.0;\n"); + } + + out.Write("\t\to.pos.xy = o.pos.xy - " I_DEPTHPARAMS".zw;\n"); out.Write("\t\tgl_Position = o.pos;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); -- cgit v1.2.3 From 51a4d6a4bef09e7b270ee26e5b2889379819da45 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 4 Nov 2014 01:12:00 +0100 Subject: GeometryShader: Adjust positions after projection. By adjusting the positions in clip space we can avoid the re-projection. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 8260ed5f05..d116dfe39a 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -77,25 +77,16 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); out.Write("\tgl_Layer = layer;\n"); - out.Write("\tvec4 stereoproj = " I_PROJECTION"[0];\n"); - out.Write("\tstereoproj[2] += " I_STEREOOFFSET"[layer] * stereoproj[0];\n"); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); out.Write("\t\to = v[i];\n"); if (g_ActiveConfig.iStereoMode > 0) - out.Write("\t\to.pos = float4(dot(stereoproj, v[i].rawpos), dot(" I_PROJECTION"[1], v[i].rawpos), dot(" I_PROJECTION"[2], v[i].rawpos), dot(" I_PROJECTION"[3], v[i].rawpos)); \n"); - - if (ApiType == API_D3D) - { - out.Write("\t\to.pos.z = " I_DEPTHPARAMS".x * o.pos.w + o.pos.z * " I_DEPTHPARAMS".y;\n"); - } - else // OGL { - out.Write("\t\to.pos.z = o.pos.w + o.pos.z * 2.0;\n"); + out.Write("\t\to.clipPos.x += o.clipPos.w * " I_STEREOOFFSET"[layer] * " I_PROJECTION"[0][0];\n"); + out.Write("\t\to.pos.x += o.pos.w * " I_STEREOOFFSET"[layer] * " I_PROJECTION"[0][0];\n"); } - out.Write("\t\to.pos.xy = o.pos.xy - " I_DEPTHPARAMS".zw;\n"); out.Write("\t\tgl_Position = o.pos;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); -- cgit v1.2.3 From 27f3f804a0fd002a19143b2373a6c622fcb56589 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 4 Nov 2014 11:53:19 +0100 Subject: ShaderGen: Only pass VS_OUTPUT between shaders if stereo 3D is enabled. GLSL130 doesn't support passing structs between shaders. This is not a problem for stereo 3D which has a GLSL150 requirement. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index d116dfe39a..bac3823747 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -64,8 +64,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy GenerateVSOutputStruct(out, ApiType); - out.Write("centroid in VS_OUTPUT v[];\n"); - out.Write("centroid out VS_OUTPUT o;\n"); + out.Write("centroid in VS_OUTPUT o[];\n"); + out.Write("centroid out VS_OUTPUT f;\n"); out.Write("flat out int layer;\n"); @@ -79,15 +79,15 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\tgl_Layer = layer;\n"); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); - out.Write("\t\to = v[i];\n"); + out.Write("\t\tf = o[i];\n"); if (g_ActiveConfig.iStereoMode > 0) { - out.Write("\t\to.clipPos.x += o.clipPos.w * " I_STEREOOFFSET"[layer] * " I_PROJECTION"[0][0];\n"); - out.Write("\t\to.pos.x += o.pos.w * " I_STEREOOFFSET"[layer] * " I_PROJECTION"[0][0];\n"); + out.Write("\t\tf.clipPos.x += f.clipPos.w * " I_STEREOOFFSET"[layer] * " I_PROJECTION"[0][0];\n"); + out.Write("\t\tf.pos.x += f.pos.w * " I_STEREOOFFSET"[layer] * " I_PROJECTION"[0][0];\n"); } - out.Write("\t\tgl_Position = o.pos;\n"); + out.Write("\t\tgl_Position = f.pos;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); out.Write("\tEndPrimitive();\n"); -- cgit v1.2.3 From f3ddf37d074f80bf40b42995e91db98b4d599534 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 8 Nov 2014 14:31:26 +0100 Subject: VideoCommon: Switch to Nvidia stereoscopy offset formula. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index bac3823747..ff7632da05 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -83,8 +83,8 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (g_ActiveConfig.iStereoMode > 0) { - out.Write("\t\tf.clipPos.x += f.clipPos.w * " I_STEREOOFFSET"[layer] * " I_PROJECTION"[0][0];\n"); - out.Write("\t\tf.pos.x += f.pos.w * " I_STEREOOFFSET"[layer] * " I_PROJECTION"[0][0];\n"); + out.Write("\t\tf.clipPos.x += " I_STEREOPARAMS"[layer] * (f.clipPos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\t\tf.pos.x += " I_STEREOPARAMS"[layer] * (f.pos.w - " I_STEREOPARAMS"[2]);\n"); } out.Write("\t\tgl_Position = f.pos;\n"); -- cgit v1.2.3 From 422125c1a94277e5e03ad57afe550c66eac1888d Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 12 Nov 2014 00:40:58 +0100 Subject: GeometryShaderGen: Add comments. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index ff7632da05..c0093caffe 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -71,11 +71,14 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("void main()\n{\n"); + // If the GPU supports invocation we don't need a for loop and can simply use the + // invocation identifier to determine which layer we're rendering. if (g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\tlayer = gl_InvocationID;\n"); else out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + // Select the output layer out.Write("\tgl_Layer = layer;\n"); out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); @@ -83,6 +86,13 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (g_ActiveConfig.iStereoMode > 0) { + // For stereoscopy add a small horizontal offset in Normalized Device Coordinates proportional + // to the depth of the vertex. We retrieve the depth value from the w-component of the projected + // vertex which contains the negated z-component of the original vertex. + // For negative parallax (out-of-screen effects) we subtract a convergence value from + // the depth value. This results in objects at a distance smaller than the convergence + // distance to seemingly appear in front of the screen. + // This formula is based on page 13 of the "Nvidia 3D Vision Automatic, Best Practices Guide" out.Write("\t\tf.clipPos.x += " I_STEREOPARAMS"[layer] * (f.clipPos.w - " I_STEREOPARAMS"[2]);\n"); out.Write("\t\tf.pos.x += " I_STEREOPARAMS"[layer] * (f.pos.w - " I_STEREOPARAMS"[2]);\n"); } -- cgit v1.2.3 From 106df04e8e87939014fb6ac8dcb35bb5f952176f Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 16 Nov 2014 02:15:43 +0100 Subject: GeometryShaderGen: Declare the vertex array size. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index c0093caffe..b3ba0d7962 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -64,7 +64,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy GenerateVSOutputStruct(out, ApiType); - out.Write("centroid in VS_OUTPUT o[];\n"); + out.Write("centroid in VS_OUTPUT o[3];\n"); out.Write("centroid out VS_OUTPUT f;\n"); out.Write("flat out int layer;\n"); -- cgit v1.2.3 From ed9f258b275b61f4ee154e19412efee34f2f8759 Mon Sep 17 00:00:00 2001 From: degasus Date: Sun, 16 Nov 2014 09:21:19 +0100 Subject: GeometryShader: Don't read from output variables --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index b3ba0d7962..afaa16582b 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -74,15 +74,15 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy // If the GPU supports invocation we don't need a for loop and can simply use the // invocation identifier to determine which layer we're rendering. if (g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("\tlayer = gl_InvocationID;\n"); + out.Write("\tint l = gl_InvocationID;\n"); else - out.Write("\tfor (layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("\tfor (int l = 0; l < %d; ++l) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - // Select the output layer - out.Write("\tgl_Layer = layer;\n"); - - out.Write("\tfor (int i = 0; i < gl_in.length(); ++i) {\n"); + out.Write("\tfor (int i = 0; i < 3; ++i) {\n"); + out.Write("\t\tlayer = l;\n"); + out.Write("\t\tgl_Layer = l;\n"); out.Write("\t\tf = o[i];\n"); + out.Write("\t\tfloat4 pos = o[i].pos;\n"); if (g_ActiveConfig.iStereoMode > 0) { @@ -93,11 +93,12 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy // the depth value. This results in objects at a distance smaller than the convergence // distance to seemingly appear in front of the screen. // This formula is based on page 13 of the "Nvidia 3D Vision Automatic, Best Practices Guide" - out.Write("\t\tf.clipPos.x += " I_STEREOPARAMS"[layer] * (f.clipPos.w - " I_STEREOPARAMS"[2]);\n"); - out.Write("\t\tf.pos.x += " I_STEREOPARAMS"[layer] * (f.pos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\t\tf.clipPos.x = o[i].clipPos.x + " I_STEREOPARAMS"[l] * (o[i].clipPos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\t\tpos.x = o[i].pos.x + " I_STEREOPARAMS"[l] * (o[i].pos.w - " I_STEREOPARAMS"[2]);\n"); } - out.Write("\t\tgl_Position = f.pos;\n"); + out.Write("\t\tf.pos.x = pos.x;\n"); + out.Write("\t\tgl_Position = pos;\n"); out.Write("\t\tEmitVertex();\n"); out.Write("\t}\n"); out.Write("\tEndPrimitive();\n"); -- cgit v1.2.3 From 9b2cd82da5e81c74eea06ebc6cf49454eb4eaf4e Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 22 Nov 2014 19:18:45 +0100 Subject: GeometryShaderGen: Set the properties of the VS_OUTPUT struct in the uid. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index afaa16582b..83a590a7ed 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -62,6 +62,9 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write(s_shader_uniforms); out.Write("};\n"); + uid_data->numTexGens = xfmem.numTexGen.numTexGens; + uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; + GenerateVSOutputStruct(out, ApiType); out.Write("centroid in VS_OUTPUT o[3];\n"); -- cgit v1.2.3