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 From 9bcadc8029b615d3d447a2a875fd720a73255d11 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 5 Dec 2014 20:54:41 -0500 Subject: Common: Remove locale based functions from CommonFuncs. Since %f isn't used anymore in the shader generators, these can go. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 83a590a7ed..f9a8704269 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -3,10 +3,6 @@ // Refer to the license.txt file included. #include -#include -#ifdef __APPLE__ - #include -#endif #include "VideoCommon/GeometryShaderGen.h" #include "VideoCommon/LightingShaderGen.h" @@ -26,15 +22,6 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy 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 @@ -115,11 +102,6 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy { 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 } } -- cgit v1.2.3 From d5ebdf7a9755217ed599d0e02d8a6ae2343410c3 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 3 Dec 2014 22:17:56 +0100 Subject: D3D: Add GeometryShaderCache. --- 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 f9a8704269..424768e2ec 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -69,7 +69,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\tfor (int l = 0; l < %d; ++l) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); out.Write("\tfor (int i = 0; i < 3; ++i) {\n"); - out.Write("\t\tlayer = l;\n"); + out.Write("\t\tgs.layer = 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"); -- cgit v1.2.3 From 9253bb7d9651f3062e4b7002a2caff377e2290b7 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 2 Nov 2014 23:40:52 +0100 Subject: D3D: Add geometry shader stereoscopy support. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 45 +++++++++++++++++++++------ 1 file changed, 36 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 424768e2ec..3ebea24585 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -52,14 +52,25 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy uid_data->numTexGens = xfmem.numTexGen.numTexGens; uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; - GenerateVSOutputStruct(out, ApiType); + GenerateVSOutputStruct(out, ApiType); + GenerateGSOutputStruct(out, ApiType); - out.Write("centroid in VS_OUTPUT o[3];\n"); - out.Write("centroid out VS_OUTPUT f;\n"); + if (ApiType == API_OPENGL) + { + out.Write("centroid in VS_OUTPUT o[3];\n"); + out.Write("centroid out GS_OUTPUT gs;\n"); + + out.Write("void main()\n{\n"); + } + else // D3D + { + out.Write("[maxvertexcount(6)]\n"); + out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output)\n{\n"); - out.Write("flat out int layer;\n"); + out.Write("\tGS_OUTPUT gs;\n"); + } - out.Write("void main()\n{\n"); + out.Write("\tVS_OUTPUT f;\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. @@ -70,7 +81,10 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy out.Write("\tfor (int i = 0; i < 3; ++i) {\n"); out.Write("\t\tgs.layer = l;\n"); - out.Write("\t\tgl_Layer = l;\n"); + + if (ApiType == API_OPENGL) + out.Write("\t\tgl_Layer = l;\n"); + out.Write("\t\tf = o[i];\n"); out.Write("\t\tfloat4 pos = o[i].pos;\n"); @@ -88,10 +102,23 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy } out.Write("\t\tf.pos.x = pos.x;\n"); - out.Write("\t\tgl_Position = pos;\n"); - out.Write("\t\tEmitVertex();\n"); + + if (ApiType == API_OPENGL) + out.Write("\t\tgl_Position = pos;\n"); + + out.Write("\t\tgs.vs = f;\n"); + + if (ApiType == API_OPENGL) + out.Write("\t\tEmitVertex();\n"); + else + out.Write("\t\tOutput.Append(gs);\n"); + out.Write("\t}\n"); - out.Write("\tEndPrimitive();\n"); + + if (ApiType == API_OPENGL) + out.Write("\tEndPrimitive();\n"); + else + out.Write("\t\tOutput.RestartStrip();\n"); if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\t}\n"); -- cgit v1.2.3 From 4f6ce0f236226fed6677283359723911c329bc38 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 14 Nov 2014 12:39:25 +0100 Subject: D3D: Add geometry shader instancing support. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 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 3ebea24585..b75eddd87a 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -64,8 +64,16 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy } else // D3D { - out.Write("[maxvertexcount(6)]\n"); - out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output)\n{\n"); + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + { + out.Write("[maxvertexcount(3)]\n[instance(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output, in uint InstanceID : SV_GSInstanceID)\n{\n"); + } + else + { + out.Write("[maxvertexcount(6)]\n"); + out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output)\n{\n"); + } out.Write("\tGS_OUTPUT gs;\n"); } @@ -75,13 +83,19 @@ 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("\tint l = gl_InvocationID;\n"); + { + if (ApiType == API_OPENGL) + out.Write("\tint l = gl_InvocationID;\n"); + else + out.Write("\tint l = InstanceID;\n"); + } else out.Write("\tfor (int l = 0; l < %d; ++l) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); out.Write("\tfor (int i = 0; i < 3; ++i) {\n"); - out.Write("\t\tgs.layer = l;\n"); + // Select the output layer + out.Write("\t\tgs.layer = l;\n"); if (ApiType == API_OPENGL) out.Write("\t\tgl_Layer = l;\n"); @@ -118,7 +132,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (ApiType == API_OPENGL) out.Write("\tEndPrimitive();\n"); else - out.Write("\t\tOutput.RestartStrip();\n"); + out.Write("\tOutput.RestartStrip();\n"); if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\t}\n"); -- cgit v1.2.3 From ea2bcb44f0d860355fd60521d5fa9a37b6fb15a1 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 3 Dec 2014 22:35:34 +0100 Subject: Cosmetics --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index b75eddd87a..187af8b088 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -85,19 +85,19 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { if (ApiType == API_OPENGL) - out.Write("\tint l = gl_InvocationID;\n"); + out.Write("\tint layer = gl_InvocationID;\n"); else - out.Write("\tint l = InstanceID;\n"); + out.Write("\tint layer = InstanceID;\n"); } else - out.Write("\tfor (int l = 0; l < %d; ++l) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("\tfor (int layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); out.Write("\tfor (int i = 0; i < 3; ++i) {\n"); // Select the output layer - out.Write("\t\tgs.layer = l;\n"); + out.Write("\t\tgs.layer = layer;\n"); if (ApiType == API_OPENGL) - out.Write("\t\tgl_Layer = l;\n"); + out.Write("\t\tgl_Layer = layer;\n"); out.Write("\t\tf = o[i];\n"); out.Write("\t\tfloat4 pos = o[i].pos;\n"); @@ -111,8 +111,8 @@ 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 = 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\tf.clipPos.x = o[i].clipPos.x + " I_STEREOPARAMS"[layer] * (o[i].clipPos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\t\tpos.x = o[i].pos.x + " I_STEREOPARAMS"[layer] * (o[i].pos.w - " I_STEREOPARAMS"[2]);\n"); } out.Write("\t\tf.pos.x = pos.x;\n"); -- cgit v1.2.3 From cec5b0ce01abbcee654c7c8ca609cb66d5af4cf0 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 3 Dec 2014 22:35:34 +0100 Subject: ShaderGen: Remove the GS_OUTPUT struct for OpenGL. And remove the generator for it since it is no longer used outside of the geometry shader. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 29 ++++++++++++++++++--------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 187af8b088..57009aedaa 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -53,17 +53,22 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; GenerateVSOutputStruct(out, ApiType); - GenerateGSOutputStruct(out, ApiType); if (ApiType == API_OPENGL) { out.Write("centroid in VS_OUTPUT o[3];\n"); - out.Write("centroid out GS_OUTPUT gs;\n"); + out.Write("centroid out VS_OUTPUT vs;\n"); + out.Write("flat out int layer;\n"); out.Write("void main()\n{\n"); } else // D3D { + out.Write("struct GS_OUTPUT {\n"); + out.Write("\tVS_OUTPUT vs;\n"); + out.Write("\tuint layer : SV_RenderTargetArrayIndex;\n"); + out.Write("};\n"); + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { out.Write("[maxvertexcount(3)]\n[instance(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); @@ -85,19 +90,23 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { if (ApiType == API_OPENGL) - out.Write("\tint layer = gl_InvocationID;\n"); + out.Write("\tint eye = gl_InvocationID;\n"); else - out.Write("\tint layer = InstanceID;\n"); + out.Write("\tint eye = InstanceID;\n"); } else - out.Write("\tfor (int layer = 0; layer < %d; ++layer) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("\tfor (int eye = 0; eye < %d; ++eye) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); out.Write("\tfor (int i = 0; i < 3; ++i) {\n"); // Select the output layer - out.Write("\t\tgs.layer = layer;\n"); if (ApiType == API_OPENGL) - out.Write("\t\tgl_Layer = layer;\n"); + { + out.Write("\t\tgl_Layer = eye;\n"); + out.Write("\t\tlayer = eye;\n"); + } + else + out.Write("\t\tgs.layer = eye;\n"); out.Write("\t\tf = o[i];\n"); out.Write("\t\tfloat4 pos = o[i].pos;\n"); @@ -111,8 +120,8 @@ 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 = o[i].clipPos.x + " I_STEREOPARAMS"[layer] * (o[i].clipPos.w - " I_STEREOPARAMS"[2]);\n"); - out.Write("\t\tpos.x = o[i].pos.x + " I_STEREOPARAMS"[layer] * (o[i].pos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\t\tf.clipPos.x = o[i].clipPos.x + " I_STEREOPARAMS"[eye] * (o[i].clipPos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\t\tpos.x = o[i].pos.x + " I_STEREOPARAMS"[eye] * (o[i].pos.w - " I_STEREOPARAMS"[2]);\n"); } out.Write("\t\tf.pos.x = pos.x;\n"); @@ -120,7 +129,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (ApiType == API_OPENGL) out.Write("\t\tgl_Position = pos;\n"); - out.Write("\t\tgs.vs = f;\n"); + out.Write("\t\t%s = f;\n", (ApiType == API_OPENGL) ? "vs" : "gs.vs"); if (ApiType == API_OPENGL) out.Write("\t\tEmitVertex();\n"); -- cgit v1.2.3 From b406e4e1f2c696ba5f6bec04ea2e6a8cc03a02d1 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 14 Dec 2014 21:23:13 +0100 Subject: VideoCommon: Add a separate constants buffer for the geometry shader. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 9 +++++---- 1 file changed, 5 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 57009aedaa..2762dcd73b 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -43,11 +43,12 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy // uniforms if (ApiType == API_OPENGL) - out.Write("layout(std140%s) uniform VSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 2" : ""); + out.Write("layout(std140%s) uniform GSBlock {\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? ", binding = 3" : ""); else - out.Write("cbuffer VSBlock {\n"); - out.Write(s_shader_uniforms); - out.Write("};\n"); + out.Write("cbuffer GSBlock {\n"); + out.Write( + "\tfloat4 " I_STEREOPARAMS";\n" + "};\n"); uid_data->numTexGens = xfmem.numTexGen.numTexGens; uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; -- cgit v1.2.3 From aa4242fd9c807633f090baac2350f786a67ebe3d Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 14 Dec 2014 19:41:16 +0100 Subject: GeometryShaderGen: Pass the primitive type and always run the generator regardless of stereoscopy. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 2762dcd73b..3a2282521e 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -12,7 +12,7 @@ static char text[16384]; template -static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiType) +static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE ApiType) { // Non-uid template parameters will write to the dummy data (=> gets optimized out) geometry_shader_uid_data dummy_data; @@ -26,8 +26,7 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy if (is_writing_shadercode) text[sizeof(text) - 1] = 0x7C; // canary - out.Write("//Geometry Shader for 3D stereoscopy\n"); - + uid_data->primitive_type = primitive_type; uid_data->stereo = g_ActiveConfig.iStereoMode > 0; if (ApiType == API_OPENGL) { @@ -156,12 +155,12 @@ static inline void GenerateGeometryShader(T& out, u32 components, API_TYPE ApiTy } } -void GetGeometryShaderUid(GeometryShaderUid& object, u32 components, API_TYPE ApiType) +void GetGeometryShaderUid(GeometryShaderUid& object, u32 primitive_type, API_TYPE ApiType) { - GenerateGeometryShader(object, components, ApiType); + GenerateGeometryShader(object, primitive_type, ApiType); } -void GenerateGeometryShaderCode(ShaderCode& object, u32 components, API_TYPE ApiType) +void GenerateGeometryShaderCode(ShaderCode& object, u32 primitive_type, API_TYPE ApiType) { - GenerateGeometryShader(object, components, ApiType); + GenerateGeometryShader(object, primitive_type, ApiType); } -- cgit v1.2.3 From 332ba4b2100ec4dcda4b2e83eb5b0e2d21e6abc4 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 14 Dec 2014 21:44:33 +0100 Subject: GeometryShaderManager: Upload Line/Point width constants. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 5 ++++- 1 file changed, 4 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 3a2282521e..814ad9c075 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -47,9 +47,12 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("cbuffer GSBlock {\n"); out.Write( "\tfloat4 " I_STEREOPARAMS";\n" + "\tfloat4 " I_LINEPTWIDTH";\n" + "\tfloat4 " I_VIEWPORT";\n" + "\tuint " I_TEXOFFSETFLAGS"[8];\n" "};\n"); - uid_data->numTexGens = xfmem.numTexGen.numTexGens; + uid_data->numTexGens = bpmem.genMode.numtexgens; uid_data->pixel_lighting = g_ActiveConfig.bEnablePixelLighting; GenerateVSOutputStruct(out, ApiType); -- cgit v1.2.3 From 887c669c288a8aeb432e9b6e9cd0c781bd14faf5 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 14 Dec 2014 21:50:46 +0100 Subject: GeometryShaderGen: Redefine gl_InvocationID so we can use the same variable name in both backends. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 10 ++++------ 1 file changed, 4 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 814ad9c075..d0e9eb7144 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -59,6 +59,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (ApiType == API_OPENGL) { + if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("#define InstanceID gl_InvocationID\n"); + out.Write("centroid in VS_OUTPUT o[3];\n"); out.Write("centroid out VS_OUTPUT vs;\n"); out.Write("flat out int layer;\n"); @@ -91,12 +94,7 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A // 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) - { - if (ApiType == API_OPENGL) - out.Write("\tint eye = gl_InvocationID;\n"); - else - out.Write("\tint eye = InstanceID;\n"); - } + out.Write("\tint eye = InstanceID;\n"); else out.Write("\tfor (int eye = 0; eye < %d; ++eye) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); -- cgit v1.2.3 From 382e1c22db91d863b55d6223d4893cb629dab810 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 14 Dec 2014 22:27:09 +0100 Subject: GeometryShaderGen: Support multiple primitive types. And make more stereoscopy code optional. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 79 ++++++++++++++++++--------- 1 file changed, 52 insertions(+), 27 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index d0e9eb7144..ca4ef96a43 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -6,11 +6,26 @@ #include "VideoCommon/GeometryShaderGen.h" #include "VideoCommon/LightingShaderGen.h" +#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexShaderGen.h" #include "VideoCommon/VideoConfig.h" static char text[16384]; +static const char* primitives_ogl[] = +{ + "points", + "lines", + "triangles" +}; + +static const char* primitives_d3d[] = +{ + "point", + "line", + "triangle" +}; + template static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE ApiType) { @@ -27,15 +42,18 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A text[sizeof(text) - 1] = 0x7C; // canary uid_data->primitive_type = primitive_type; + const unsigned int vertex_in = primitive_type + 1; uid_data->stereo = g_ActiveConfig.iStereoMode > 0; + const unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4; + if (ApiType == API_OPENGL) { // Insert layout parameters if (g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("layout(triangles, invocations = %d) in;\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("layout(%s, invocations = %d) in;\n", primitives_ogl[primitive_type], 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); + out.Write("layout(%s) in;\n", primitives_ogl[primitive_type]); + out.Write("layout(triangle_strip, max_vertices = %d) out;\n", g_ActiveConfig.backend_info.bSupportsGSInstancing ? vertex_out : vertex_out * 2); } out.Write("%s", s_lighting_struct); @@ -62,9 +80,11 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("#define InstanceID gl_InvocationID\n"); - out.Write("centroid in VS_OUTPUT o[3];\n"); + out.Write("centroid in VS_OUTPUT o[%d];\n", vertex_in); out.Write("centroid out VS_OUTPUT vs;\n"); - out.Write("flat out int layer;\n"); + + if (g_ActiveConfig.iStereoMode > 0) + out.Write("flat out int layer;\n"); out.Write("void main()\n{\n"); } @@ -72,18 +92,21 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A { out.Write("struct GS_OUTPUT {\n"); out.Write("\tVS_OUTPUT vs;\n"); - out.Write("\tuint layer : SV_RenderTargetArrayIndex;\n"); + + if (g_ActiveConfig.iStereoMode > 0) + out.Write("\tuint layer : SV_RenderTargetArrayIndex;\n"); + out.Write("};\n"); + out.Write("[maxvertexcount(%d)]\n", vertex_out); if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { - out.Write("[maxvertexcount(3)]\n[instance(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output, in uint InstanceID : SV_GSInstanceID)\n{\n"); + out.Write("[instance(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream Output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in); } else { - out.Write("[maxvertexcount(6)]\n"); - out.Write("void main(triangle VS_OUTPUT o[3], inout TriangleStream Output)\n{\n"); + out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream Output)\n{\n", primitives_d3d[primitive_type], vertex_in); } out.Write("\tGS_OUTPUT gs;\n"); @@ -91,29 +114,32 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tVS_OUTPUT f;\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("\tint eye = InstanceID;\n"); - else - out.Write("\tfor (int eye = 0; eye < %d; ++eye) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - - out.Write("\tfor (int i = 0; i < 3; ++i) {\n"); - - // Select the output layer - if (ApiType == API_OPENGL) + if (g_ActiveConfig.iStereoMode > 0) { - out.Write("\t\tgl_Layer = eye;\n"); - out.Write("\t\tlayer = eye;\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("\tint eye = InstanceID;\n"); + else + out.Write("\tfor (int eye = 0; eye < %d; ++eye) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); } - else - out.Write("\t\tgs.layer = eye;\n"); + + out.Write("\tfor (int i = 0; i < %d; ++i) {\n", vertex_in); out.Write("\t\tf = o[i];\n"); out.Write("\t\tfloat4 pos = o[i].pos;\n"); if (g_ActiveConfig.iStereoMode > 0) { + // Select the output layer + if (ApiType == API_OPENGL) + { + out.Write("\t\tgl_Layer = eye;\n"); + out.Write("\t\tlayer = eye;\n"); + } + else + out.Write("\t\tgs.layer = eye;\n"); + // 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. @@ -123,10 +149,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A // This formula is based on page 13 of the "Nvidia 3D Vision Automatic, Best Practices Guide" out.Write("\t\tf.clipPos.x = o[i].clipPos.x + " I_STEREOPARAMS"[eye] * (o[i].clipPos.w - " I_STEREOPARAMS"[2]);\n"); out.Write("\t\tpos.x = o[i].pos.x + " I_STEREOPARAMS"[eye] * (o[i].pos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\t\tf.pos.x = pos.x;\n"); } - out.Write("\t\tf.pos.x = pos.x;\n"); - if (ApiType == API_OPENGL) out.Write("\t\tgl_Position = pos;\n"); -- cgit v1.2.3 From 55e60a9c2242713a93621ca1b618930e5c61aef0 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 15 Dec 2014 22:12:17 +0100 Subject: VideoCommon: Merge LineGeometryShader into GeometryShaderGen. This adds line-width emulation support to OpenGL. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 99 ++++++++++++++++++++------- 1 file changed, 74 insertions(+), 25 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index ca4ef96a43..ee6da0fe4d 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -4,6 +4,7 @@ #include +#include "VideoCommon/BPMemory.h" #include "VideoCommon/GeometryShaderGen.h" #include "VideoCommon/LightingShaderGen.h" #include "VideoCommon/VertexManagerBase.h" @@ -43,17 +44,22 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A uid_data->primitive_type = primitive_type; const unsigned int vertex_in = primitive_type + 1; - uid_data->stereo = g_ActiveConfig.iStereoMode > 0; const unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4; + uid_data->stereo = g_ActiveConfig.iStereoMode > 0; if (ApiType == API_OPENGL) { // Insert layout parameters if (g_ActiveConfig.backend_info.bSupportsGSInstancing) + { out.Write("layout(%s, invocations = %d) in;\n", primitives_ogl[primitive_type], g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("layout(triangle_strip, max_vertices = %d) out;\n", vertex_out); + } else + { out.Write("layout(%s) in;\n", primitives_ogl[primitive_type]); - out.Write("layout(triangle_strip, max_vertices = %d) out;\n", g_ActiveConfig.backend_info.bSupportsGSInstancing ? vertex_out : vertex_out * 2); + out.Write("layout(triangle_strip, max_vertices = %d) out;\n", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); + } } out.Write("%s", s_lighting_struct); @@ -98,15 +104,15 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("};\n"); - out.Write("[maxvertexcount(%d)]\n", vertex_out); if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { - out.Write("[instance(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream Output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in); + out.Write("[maxvertexcount(%d)]\n[instance(%d)]\n", vertex_out, g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in); } else { - out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream Output)\n{\n", primitives_d3d[primitive_type], vertex_in); + out.Write("[maxvertexcount(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); + out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output)\n{\n", primitives_d3d[primitive_type], vertex_in); } out.Write("\tGS_OUTPUT gs;\n"); @@ -114,6 +120,27 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tVS_OUTPUT f;\n"); + if (primitive_type == PRIMITIVE_LINES) + { + // GameCube/Wii's line drawing algorithm is a little quirky. It does not + // use the correct line caps. Instead, the line caps are vertical or + // horizontal depending the slope of the line. + + out.Write("\tfloat2 offset;\n"); + out.Write("\tfloat2 to = abs(o[1].pos.xy - o[0].pos.xy);\n"); + // FIXME: What does real hardware do when line is at a 45-degree angle? + // FIXME: Lines aren't drawn at the correct width. See Twilight Princess map. + out.Write("\tif (" I_VIEWPORT".y * to.y > " I_VIEWPORT".x * to.x) {\n"); + // Line is more tall. Extend geometry left and right. + // Lerp LineWidth/2 from [0..VpWidth] to [-1..1] + out.Write("\t\toffset = float2(" I_LINEPTWIDTH"[0] / " I_VIEWPORT".x, 0);\n"); + out.Write("\t} else {\n"); + // Line is more wide. Extend geometry up and down. + // Lerp LineWidth/2 from [0..VpHeight] to [1..-1] + out.Write("\t\toffset = float2(0, -" I_LINEPTWIDTH"[0] / " I_VIEWPORT".y);\n"); + out.Write("\t}\n"); + } + if (g_ActiveConfig.iStereoMode > 0) { // If the GPU supports invocation we don't need a for loop and can simply use the @@ -121,24 +148,22 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\tint eye = InstanceID;\n"); else - out.Write("\tfor (int eye = 0; eye < %d; ++eye) {\n", g_ActiveConfig.iStereoMode > 0 ? 2 : 1); + out.Write("\tfor (int eye = 0; eye < 2; ++eye) {\n"); } out.Write("\tfor (int i = 0; i < %d; ++i) {\n", vertex_in); - - out.Write("\t\tf = o[i];\n"); - out.Write("\t\tfloat4 pos = o[i].pos;\n"); + out.Write("\tVS_OUTPUT f = o[i];\n"); if (g_ActiveConfig.iStereoMode > 0) { // Select the output layer if (ApiType == API_OPENGL) { - out.Write("\t\tgl_Layer = eye;\n"); - out.Write("\t\tlayer = eye;\n"); + out.Write("\tgl_Layer = eye;\n"); + out.Write("\tlayer = eye;\n"); } else - out.Write("\t\tgs.layer = eye;\n"); + out.Write("\tgs.layer = eye;\n"); // 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 @@ -147,30 +172,40 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A // 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 = o[i].clipPos.x + " I_STEREOPARAMS"[eye] * (o[i].clipPos.w - " I_STEREOPARAMS"[2]);\n"); - out.Write("\t\tpos.x = o[i].pos.x + " I_STEREOPARAMS"[eye] * (o[i].pos.w - " I_STEREOPARAMS"[2]);\n"); - out.Write("\t\tf.pos.x = pos.x;\n"); + out.Write("\tf.clipPos.x += " I_STEREOPARAMS"[eye] * (o[i].clipPos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\tf.pos.x += " I_STEREOPARAMS"[eye] * (o[i].pos.w - " I_STEREOPARAMS"[2]);\n"); } - if (ApiType == API_OPENGL) - out.Write("\t\tgl_Position = pos;\n"); + if (primitive_type == PRIMITIVE_LINES) + { + out.Write("\tVS_OUTPUT l = f;\n"); + out.Write("\tVS_OUTPUT r = f;\n"); - out.Write("\t\t%s = f;\n", (ApiType == API_OPENGL) ? "vs" : "gs.vs"); + out.Write("\tl.pos.xy -= offset * l.pos.w;\n"); + out.Write("\tr.pos.xy += offset * r.pos.w;\n"); - if (ApiType == API_OPENGL) - out.Write("\t\tEmitVertex();\n"); + for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) + { + out.Write("\tr.tex%d.x += " I_LINEPTWIDTH"[2] * (" I_TEXOFFSETFLAGS"[%d] % 2);\n", i, i); + } + + EmitVertex(out, "l", ApiType); + EmitVertex(out, "r", ApiType); + } else - out.Write("\t\tOutput.Append(gs);\n"); + { + EmitVertex(out, "f", ApiType); + } out.Write("\t}\n"); if (ApiType == API_OPENGL) out.Write("\tEndPrimitive();\n"); else - out.Write("\tOutput.RestartStrip();\n"); + out.Write("\toutput.RestartStrip();\n"); - if (!g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("\t}\n"); + if (g_ActiveConfig.iStereoMode > 0 && !g_ActiveConfig.backend_info.bSupportsGSInstancing) + out.Write("\t}\n"); out.Write("}\n"); @@ -181,6 +216,20 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } } +template +static inline void EmitVertex(T& out, const char *vertex, API_TYPE ApiType) +{ + if (ApiType == API_OPENGL) + out.Write("\tgl_Position = %s.pos;\n", vertex); + + out.Write("\t%s = %s;\n", (ApiType == API_OPENGL) ? "vs" : "gs.vs", vertex); + + if (ApiType == API_OPENGL) + out.Write("\tEmitVertex();\n"); + else + out.Write("\toutput.Append(gs);\n"); +} + void GetGeometryShaderUid(GeometryShaderUid& object, u32 primitive_type, API_TYPE ApiType) { GenerateGeometryShader(object, primitive_type, ApiType); -- cgit v1.2.3 From 8ae738ff3076aa2b4cec254f3d5dcfe2fea95d88 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 15 Dec 2014 22:29:56 +0100 Subject: VideoCommon: Merge PointGeometryShader into GeometryShaderGen. This adds point-width emulation support to OpenGL. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 34 ++++++++++++++++++++++++++- 1 file changed, 33 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 ee6da0fe4d..fabd883ded 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -140,6 +140,12 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\t\toffset = float2(0, -" I_LINEPTWIDTH"[0] / " I_VIEWPORT".y);\n"); out.Write("\t}\n"); } + else if (primitive_type == PRIMITIVE_POINTS) + { + // Offset from center to upper right vertex + // Lerp PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1] + out.Write("float2 offset = float2(" I_LINEPTWIDTH"[1] / " I_VIEWPORT".x, -" I_LINEPTWIDTH"[1] / " I_VIEWPORT".y) * o[0].pos.w;\n"); + } if (g_ActiveConfig.iStereoMode > 0) { @@ -186,12 +192,38 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) { - out.Write("\tr.tex%d.x += " I_LINEPTWIDTH"[2] * (" I_TEXOFFSETFLAGS"[%d] % 2);\n", i, i); + out.Write("\tr.tex%d.x += " I_LINEPTWIDTH"[2] * (" I_TEXOFFSETFLAGS"[%d] & 0x01);\n", i, i); } EmitVertex(out, "l", ApiType); EmitVertex(out, "r", ApiType); } + else if (primitive_type == PRIMITIVE_POINTS) + { + out.Write("VS_OUTPUT ll = f;\n"); + out.Write("VS_OUTPUT lr = f;\n"); + out.Write("VS_OUTPUT ul = f;\n"); + out.Write("VS_OUTPUT ur = f;\n"); + + out.Write("ll.pos.xy += float2(-1,-1) * offset;\n"); + out.Write("lr.pos.xy += float2(1,-1) * offset;\n"); + out.Write("ul.pos.xy += float2(-1,1) * offset;\n"); + out.Write("ur.pos.xy += offset;\n"); + + out.Write("float2 texOffset = float2(" I_LINEPTWIDTH"[3], " I_LINEPTWIDTH"[3]);\n"); + + for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) + { + out.Write("ll.tex%d.xy += float2(0,1) * texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i); + out.Write("lr.tex%d.xy += texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i); + out.Write("ur.tex%d.xy += float2(1,0) * texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i); + } + + EmitVertex(out, "ll", ApiType); + EmitVertex(out, "lr", ApiType); + EmitVertex(out, "ul", ApiType); + EmitVertex(out, "ur", ApiType); + } else { EmitVertex(out, "f", ApiType); -- cgit v1.2.3 From 861fa1af2387567a00c77db8b78a3ac376fef863 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 15 Dec 2014 22:39:03 +0100 Subject: GeometryShaderGen: Declare a prototype for EmitVertex(). --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index fabd883ded..37f75ad0d0 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -27,6 +27,8 @@ static const char* primitives_d3d[] = "triangle" }; +template static inline void EmitVertex(T& out, const char *vertex, API_TYPE ApiType); + template static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE ApiType) { -- cgit v1.2.3 From 16af00d51568ddcb4301bffd490d26d342314bd7 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 15 Dec 2014 23:05:16 +0100 Subject: GeometryShaderGen: Use signed integers for the texture offset flags. --- 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 37f75ad0d0..a8bd784b1b 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -75,7 +75,7 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A "\tfloat4 " I_STEREOPARAMS";\n" "\tfloat4 " I_LINEPTWIDTH";\n" "\tfloat4 " I_VIEWPORT";\n" - "\tuint " I_TEXOFFSETFLAGS"[8];\n" + "\tint " I_TEXOFFSETFLAGS"[8];\n" "};\n"); uid_data->numTexGens = bpmem.genMode.numtexgens; -- cgit v1.2.3 From d115048615864591125cd1b918bdd923b5b63058 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Mon, 15 Dec 2014 23:20:56 +0100 Subject: GeometryShaderGen: Remove redundant declaration. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index a8bd784b1b..7e989e7b17 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -120,8 +120,6 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tGS_OUTPUT gs;\n"); } - out.Write("\tVS_OUTPUT f;\n"); - if (primitive_type == PRIMITIVE_LINES) { // GameCube/Wii's line drawing algorithm is a little quirky. It does not -- cgit v1.2.3 From 0ac710339100dc6dc2f1f4c094b372846decdce5 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 16 Dec 2014 00:21:07 +0100 Subject: GeometryShaderGen: Pack uniforms more tightly. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 48 ++++++++++++++++----------- 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 7e989e7b17..e10b919dd4 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -73,9 +73,8 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("cbuffer GSBlock {\n"); out.Write( "\tfloat4 " I_STEREOPARAMS";\n" - "\tfloat4 " I_LINEPTWIDTH";\n" - "\tfloat4 " I_VIEWPORT";\n" - "\tint " I_TEXOFFSETFLAGS"[8];\n" + "\tfloat4 " I_LINEPTPARAMS";\n" + "\tint4 " I_TEXOFFSET";\n" "};\n"); uid_data->numTexGens = bpmem.genMode.numtexgens; @@ -130,21 +129,21 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tfloat2 to = abs(o[1].pos.xy - o[0].pos.xy);\n"); // FIXME: What does real hardware do when line is at a 45-degree angle? // FIXME: Lines aren't drawn at the correct width. See Twilight Princess map. - out.Write("\tif (" I_VIEWPORT".y * to.y > " I_VIEWPORT".x * to.x) {\n"); + out.Write("\tif (" I_LINEPTPARAMS".y * to.y > " I_LINEPTPARAMS".x * to.x) {\n"); // Line is more tall. Extend geometry left and right. // Lerp LineWidth/2 from [0..VpWidth] to [-1..1] - out.Write("\t\toffset = float2(" I_LINEPTWIDTH"[0] / " I_VIEWPORT".x, 0);\n"); + out.Write("\t\toffset = float2(" I_LINEPTPARAMS".z / " I_LINEPTPARAMS".x, 0);\n"); out.Write("\t} else {\n"); // Line is more wide. Extend geometry up and down. // Lerp LineWidth/2 from [0..VpHeight] to [1..-1] - out.Write("\t\toffset = float2(0, -" I_LINEPTWIDTH"[0] / " I_VIEWPORT".y);\n"); + out.Write("\t\toffset = float2(0, -" I_LINEPTPARAMS".z / " I_LINEPTPARAMS".y);\n"); out.Write("\t}\n"); } else if (primitive_type == PRIMITIVE_POINTS) { // Offset from center to upper right vertex // Lerp PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1] - out.Write("float2 offset = float2(" I_LINEPTWIDTH"[1] / " I_VIEWPORT".x, -" I_LINEPTWIDTH"[1] / " I_VIEWPORT".y) * o[0].pos.w;\n"); + out.Write("float2 offset = float2(" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".x, -" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".y) * o[0].pos.w;\n"); } if (g_ActiveConfig.iStereoMode > 0) @@ -190,34 +189,43 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tl.pos.xy -= offset * l.pos.w;\n"); out.Write("\tr.pos.xy += offset * r.pos.w;\n"); + out.Write("\tif (" I_TEXOFFSET"[2] != 0) {\n"); + out.Write("\tfloat texOffset = 1.0 / float(" I_TEXOFFSET"[2]);\n"); + for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) { - out.Write("\tr.tex%d.x += " I_LINEPTWIDTH"[2] * (" I_TEXOFFSETFLAGS"[%d] & 0x01);\n", i, i); + out.Write("\tif (((" I_TEXOFFSET"[0] >> %d) & 0x1) != 0)\n", i); + out.Write("\t\tr.tex%d.x += texOffset;\n", i); } + out.Write("\t}\n"); EmitVertex(out, "l", ApiType); EmitVertex(out, "r", ApiType); } else if (primitive_type == PRIMITIVE_POINTS) { - out.Write("VS_OUTPUT ll = f;\n"); - out.Write("VS_OUTPUT lr = f;\n"); - out.Write("VS_OUTPUT ul = f;\n"); - out.Write("VS_OUTPUT ur = f;\n"); + out.Write("\tVS_OUTPUT ll = f;\n"); + out.Write("\tVS_OUTPUT lr = f;\n"); + out.Write("\tVS_OUTPUT ul = f;\n"); + out.Write("\tVS_OUTPUT ur = f;\n"); - out.Write("ll.pos.xy += float2(-1,-1) * offset;\n"); - out.Write("lr.pos.xy += float2(1,-1) * offset;\n"); - out.Write("ul.pos.xy += float2(-1,1) * offset;\n"); - out.Write("ur.pos.xy += offset;\n"); + out.Write("\tll.pos.xy += float2(-1,-1) * offset;\n"); + out.Write("\tlr.pos.xy += float2(1,-1) * offset;\n"); + out.Write("\tul.pos.xy += float2(-1,1) * offset;\n"); + out.Write("\tur.pos.xy += offset;\n"); - out.Write("float2 texOffset = float2(" I_LINEPTWIDTH"[3], " I_LINEPTWIDTH"[3]);\n"); + out.Write("\tif (" I_TEXOFFSET"[3] != 0) {\n"); + out.Write("\tfloat2 texOffset = float2(1.0 / float(" I_TEXOFFSET"[3]), 1.0 / float(" I_TEXOFFSET"[3]));\n"); for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i) { - out.Write("ll.tex%d.xy += float2(0,1) * texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i); - out.Write("lr.tex%d.xy += texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i); - out.Write("ur.tex%d.xy += float2(1,0) * texOffset * (" I_TEXOFFSETFLAGS"[%d] & 0x10);\n", i, i); + out.Write("\tif (((" I_TEXOFFSET"[1] >> %d) & 0x1) != 0) {\n", i); + out.Write("\t\tll.tex%d.xy += float2(0,1) * texOffset;\n", i); + out.Write("\t\tlr.tex%d.xy += texOffset;\n", i); + out.Write("\t\tur.tex%d.xy += float2(1,0) * texOffset;\n", i); + out.Write("\t}\n"); } + out.Write("\t}\n"); EmitVertex(out, "ll", ApiType); EmitVertex(out, "lr", ApiType); -- cgit v1.2.3 From f2e52b46c3293228759d2db373a6e11c5c4513cf Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 16 Dec 2014 16:53:49 +0100 Subject: GeometryShaderGen: Cosmetics. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 60 ++++++++++++++------------- 1 file changed, 31 insertions(+), 29 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index e10b919dd4..bf40056a8d 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -27,7 +27,7 @@ static const char* primitives_d3d[] = "triangle" }; -template static inline void EmitVertex(T& out, const char *vertex, API_TYPE ApiType); +template static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType); template static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE ApiType) @@ -124,20 +124,20 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A // GameCube/Wii's line drawing algorithm is a little quirky. It does not // use the correct line caps. Instead, the line caps are vertical or // horizontal depending the slope of the line. - - out.Write("\tfloat2 offset;\n"); - out.Write("\tfloat2 to = abs(o[1].pos.xy - o[0].pos.xy);\n"); - // FIXME: What does real hardware do when line is at a 45-degree angle? - // FIXME: Lines aren't drawn at the correct width. See Twilight Princess map. - out.Write("\tif (" I_LINEPTPARAMS".y * to.y > " I_LINEPTPARAMS".x * to.x) {\n"); - // Line is more tall. Extend geometry left and right. - // Lerp LineWidth/2 from [0..VpWidth] to [-1..1] - out.Write("\t\toffset = float2(" I_LINEPTPARAMS".z / " I_LINEPTPARAMS".x, 0);\n"); - out.Write("\t} else {\n"); - // Line is more wide. Extend geometry up and down. - // Lerp LineWidth/2 from [0..VpHeight] to [1..-1] - out.Write("\t\toffset = float2(0, -" I_LINEPTPARAMS".z / " I_LINEPTPARAMS".y);\n"); - out.Write("\t}\n"); + out.Write( + "\tfloat2 offset;\n" + "\tfloat2 to = abs(o[1].pos.xy - o[0].pos.xy);\n" + // FIXME: What does real hardware do when line is at a 45-degree angle? + // FIXME: Lines aren't drawn at the correct width. See Twilight Princess map. + "\tif (" I_LINEPTPARAMS".y * to.y > " I_LINEPTPARAMS".x * to.x) {\n" + // Line is more tall. Extend geometry left and right. + // Lerp LineWidth/2 from [0..VpWidth] to [-1..1] + "\t\toffset = float2(" I_LINEPTPARAMS".z / " I_LINEPTPARAMS".x, 0);\n" + "\t} else {\n" + // Line is more wide. Extend geometry up and down. + // Lerp LineWidth/2 from [0..VpHeight] to [1..-1] + "\t\toffset = float2(0, -" I_LINEPTPARAMS".z / " I_LINEPTPARAMS".y);\n" + "\t}\n"); } else if (primitive_type == PRIMITIVE_POINTS) { @@ -168,7 +168,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tlayer = eye;\n"); } else + { out.Write("\tgs.layer = eye;\n"); + } // 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 @@ -183,11 +185,11 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (primitive_type == PRIMITIVE_LINES) { - out.Write("\tVS_OUTPUT l = f;\n"); - out.Write("\tVS_OUTPUT r = f;\n"); + out.Write("\tVS_OUTPUT l = f;\n" + "\tVS_OUTPUT r = f;\n"); - out.Write("\tl.pos.xy -= offset * l.pos.w;\n"); - out.Write("\tr.pos.xy += offset * r.pos.w;\n"); + out.Write("\tl.pos.xy -= offset * l.pos.w;\n" + "\tr.pos.xy += offset * r.pos.w;\n"); out.Write("\tif (" I_TEXOFFSET"[2] != 0) {\n"); out.Write("\tfloat texOffset = 1.0 / float(" I_TEXOFFSET"[2]);\n"); @@ -204,15 +206,15 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } else if (primitive_type == PRIMITIVE_POINTS) { - out.Write("\tVS_OUTPUT ll = f;\n"); - out.Write("\tVS_OUTPUT lr = f;\n"); - out.Write("\tVS_OUTPUT ul = f;\n"); - out.Write("\tVS_OUTPUT ur = f;\n"); + out.Write("\tVS_OUTPUT ll = f;\n" + "\tVS_OUTPUT lr = f;\n" + "\tVS_OUTPUT ul = f;\n" + "\tVS_OUTPUT ur = f;\n"); - out.Write("\tll.pos.xy += float2(-1,-1) * offset;\n"); - out.Write("\tlr.pos.xy += float2(1,-1) * offset;\n"); - out.Write("\tul.pos.xy += float2(-1,1) * offset;\n"); - out.Write("\tur.pos.xy += offset;\n"); + out.Write("\tll.pos.xy += float2(-1,-1) * offset;\n" + "\tlr.pos.xy += float2(1,-1) * offset;\n" + "\tul.pos.xy += float2(-1,1) * offset;\n" + "\tur.pos.xy += offset;\n"); out.Write("\tif (" I_TEXOFFSET"[3] != 0) {\n"); out.Write("\tfloat2 texOffset = float2(1.0 / float(" I_TEXOFFSET"[3]), 1.0 / float(" I_TEXOFFSET"[3]));\n"); @@ -245,7 +247,7 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\toutput.RestartStrip();\n"); if (g_ActiveConfig.iStereoMode > 0 && !g_ActiveConfig.backend_info.bSupportsGSInstancing) - out.Write("\t}\n"); + out.Write("\t}\n"); out.Write("}\n"); @@ -257,7 +259,7 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } template -static inline void EmitVertex(T& out, const char *vertex, API_TYPE ApiType) +static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType) { if (ApiType == API_OPENGL) out.Write("\tgl_Position = %s.pos;\n", vertex); -- cgit v1.2.3 From bd6d22973381b43369670300a707e86084c040e0 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 16 Dec 2014 17:28:35 +0100 Subject: GeometryShader: Disable the geometry shader stage if it is a pass-through shader. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index bf40056a8d..3d478a6a4d 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -281,3 +281,9 @@ void GenerateGeometryShaderCode(ShaderCode& object, u32 primitive_type, API_TYPE { GenerateGeometryShader(object, primitive_type, ApiType); } + +bool IsPassthroughGeometryShader(GeometryShaderUid& object) +{ + geometry_shader_uid_data* uid_data = object.GetUidData(); + return uid_data->primitive_type == PRIMITIVE_TRIANGLES && !uid_data->stereo; +} -- cgit v1.2.3 From 782a5adb947ef5e4c961580047ff17aea70f3d0f Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Tue, 16 Dec 2014 23:52:42 +0100 Subject: VideoCommon: Pass interface blocks between shader stages to resolve naming conflicts. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 64 ++++++++++++++++++--------- 1 file changed, 42 insertions(+), 22 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 3d478a6a4d..4a6b4dce55 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -87,18 +87,24 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("#define InstanceID gl_InvocationID\n"); - out.Write("centroid in VS_OUTPUT o[%d];\n", vertex_in); - out.Write("centroid out VS_OUTPUT vs;\n"); + out.Write("in VertexData {\n"); + out.Write("\tcentroid VS_OUTPUT o;\n"); + out.Write("} vs[%d];\n", vertex_in); + + out.Write("out VertexData {\n"); + out.Write("\tcentroid VS_OUTPUT o;\n"); if (g_ActiveConfig.iStereoMode > 0) - out.Write("flat out int layer;\n"); + out.Write("\tflat int layer;\n"); + + out.Write("} ps;\n"); out.Write("void main()\n{\n"); } else // D3D { - out.Write("struct GS_OUTPUT {\n"); - out.Write("\tVS_OUTPUT vs;\n"); + out.Write("struct VertexData {\n"); + out.Write("\tVS_OUTPUT o;\n"); if (g_ActiveConfig.iStereoMode > 0) out.Write("\tuint layer : SV_RenderTargetArrayIndex;\n"); @@ -108,25 +114,36 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { out.Write("[maxvertexcount(%d)]\n[instance(%d)]\n", vertex_out, g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in); + out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in); } else { out.Write("[maxvertexcount(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); - out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output)\n{\n", primitives_d3d[primitive_type], vertex_in); + out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output)\n{\n", primitives_d3d[primitive_type], vertex_in); } - out.Write("\tGS_OUTPUT gs;\n"); + out.Write("\tVertexData ps;\n"); } if (primitive_type == PRIMITIVE_LINES) { + if (ApiType == API_OPENGL) + { + out.Write("\tVS_OUTPUT start = vs[0].o;\n"); + out.Write("\tVS_OUTPUT end = vs[1].o;\n"); + } + else + { + out.Write("\tVS_OUTPUT start = o[0];\n"); + out.Write("\tVS_OUTPUT end = o[1];\n"); + } + // GameCube/Wii's line drawing algorithm is a little quirky. It does not // use the correct line caps. Instead, the line caps are vertical or // horizontal depending the slope of the line. out.Write( "\tfloat2 offset;\n" - "\tfloat2 to = abs(o[1].pos.xy - o[0].pos.xy);\n" + "\tfloat2 to = abs(end.pos.xy - start.pos.xy);\n" // FIXME: What does real hardware do when line is at a 45-degree angle? // FIXME: Lines aren't drawn at the correct width. See Twilight Princess map. "\tif (" I_LINEPTPARAMS".y * to.y > " I_LINEPTPARAMS".x * to.x) {\n" @@ -141,9 +158,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 point = vs[0].o;\n"); + else + out.Write("\tVS_OUTPUT point = o[0];\n"); + // Offset from center to upper right vertex // Lerp PointSize/2 from [0,0..VpWidth,VpHeight] to [-1,1..1,-1] - out.Write("float2 offset = float2(" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".x, -" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".y) * o[0].pos.w;\n"); + out.Write("float2 offset = float2(" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".x, -" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".y) * point.pos.w;\n"); } if (g_ActiveConfig.iStereoMode > 0) @@ -157,20 +179,18 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } out.Write("\tfor (int i = 0; i < %d; ++i) {\n", vertex_in); - out.Write("\tVS_OUTPUT f = o[i];\n"); + + if (ApiType == API_OPENGL) + out.Write("\tVS_OUTPUT f = vs[i].o;\n"); + else + out.Write("\tVS_OUTPUT f = o[i];\n"); if (g_ActiveConfig.iStereoMode > 0) { // Select the output layer + out.Write("\tps.layer = eye;\n"); if (ApiType == API_OPENGL) - { out.Write("\tgl_Layer = eye;\n"); - out.Write("\tlayer = eye;\n"); - } - else - { - out.Write("\tgs.layer = eye;\n"); - } // 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 @@ -179,8 +199,8 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A // 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("\tf.clipPos.x += " I_STEREOPARAMS"[eye] * (o[i].clipPos.w - " I_STEREOPARAMS"[2]);\n"); - out.Write("\tf.pos.x += " I_STEREOPARAMS"[eye] * (o[i].pos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\tf.clipPos.x += " I_STEREOPARAMS"[eye] * (f.clipPos.w - " I_STEREOPARAMS"[2]);\n"); + out.Write("\tf.pos.x += " I_STEREOPARAMS"[eye] * (f.pos.w - " I_STEREOPARAMS"[2]);\n"); } if (primitive_type == PRIMITIVE_LINES) @@ -264,12 +284,12 @@ static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType) if (ApiType == API_OPENGL) out.Write("\tgl_Position = %s.pos;\n", vertex); - out.Write("\t%s = %s;\n", (ApiType == API_OPENGL) ? "vs" : "gs.vs", vertex); + out.Write("\tps.o = %s;\n", vertex); if (ApiType == API_OPENGL) out.Write("\tEmitVertex();\n"); else - out.Write("\toutput.Append(gs);\n"); + out.Write("\toutput.Append(ps);\n"); } void GetGeometryShaderUid(GeometryShaderUid& object, u32 primitive_type, API_TYPE ApiType) -- cgit v1.2.3 From e7e8a4f1cb3d1c7801c18f4d3ff5cae797d5f5b3 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Thu, 18 Dec 2014 19:53:53 +0100 Subject: GeometryShaderGen: Don't use the reserved keyword "point" in D3D. --- 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 4a6b4dce55..cabdfea191 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -159,13 +159,13 @@ 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 point = vs[0].o;\n"); + out.Write("\tVS_OUTPUT center = vs[0].o;\n"); else - out.Write("\tVS_OUTPUT point = o[0];\n"); + 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] - out.Write("float2 offset = float2(" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".x, -" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".y) * point.pos.w;\n"); + out.Write("\tfloat2 offset = float2(" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".x, -" I_LINEPTPARAMS".w / " I_LINEPTPARAMS".y) * center.pos.w;\n"); } if (g_ActiveConfig.iStereoMode > 0) -- cgit v1.2.3 From cdd9e0752216735d712c84d0f7308a1081682f8e Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 19 Dec 2014 10:51:00 +0100 Subject: VideoCommon: Add in/out qualifiers to centroid storage qualifier. Fixes shaders for GPUs that don't support GL_ARB_shading_language_420pack. --- 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 cabdfea191..bcd7758fba 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -88,11 +88,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 VS_OUTPUT o;\n"); + out.Write("\tcentroid in VS_OUTPUT o;\n"); out.Write("} vs[%d];\n", vertex_in); out.Write("out VertexData {\n"); - out.Write("\tcentroid VS_OUTPUT o;\n"); + out.Write("\tcentroid out VS_OUTPUT o;\n"); if (g_ActiveConfig.iStereoMode > 0) out.Write("\tflat int layer;\n"); -- cgit v1.2.3 From 925bbcb85bc8f0c92fa22a5011ff9861398ea7ad Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 19 Dec 2014 12:03:11 +0100 Subject: VideoCommon: Handle wireframe mode in the geometry shader. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 11 ++++++----- 1 file changed, 6 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 bcd7758fba..38be5193ca 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -49,18 +49,19 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A const unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4; uid_data->stereo = g_ActiveConfig.iStereoMode > 0; + uid_data->wireframe = g_ActiveConfig.bWireFrame; if (ApiType == API_OPENGL) { // Insert layout parameters if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { out.Write("layout(%s, invocations = %d) in;\n", primitives_ogl[primitive_type], g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - out.Write("layout(triangle_strip, max_vertices = %d) out;\n", vertex_out); + out.Write("layout(%s_strip, max_vertices = %d) out;\n", g_ActiveConfig.bWireFrame ? "line" : "triangle", vertex_out); } else { out.Write("layout(%s) in;\n", primitives_ogl[primitive_type]); - out.Write("layout(triangle_strip, max_vertices = %d) out;\n", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); + out.Write("layout(%s_strip, max_vertices = %d) out;\n", g_ActiveConfig.bWireFrame ? "line" : "triangle", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); } } @@ -114,12 +115,12 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A if (g_ActiveConfig.backend_info.bSupportsGSInstancing) { out.Write("[maxvertexcount(%d)]\n[instance(%d)]\n", vertex_out, g_ActiveConfig.iStereoMode > 0 ? 2 : 1); - out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in); + out.Write("void main(%s VS_OUTPUT o[%d], inout %sStream output, in uint InstanceID : SV_GSInstanceID)\n{\n", primitives_d3d[primitive_type], vertex_in, g_ActiveConfig.bWireFrame ? "Line" : "Triangle"); } else { out.Write("[maxvertexcount(%d)]\n", g_ActiveConfig.iStereoMode > 0 ? vertex_out * 2 : vertex_out); - out.Write("void main(%s VS_OUTPUT o[%d], inout TriangleStream output)\n{\n", primitives_d3d[primitive_type], vertex_in); + out.Write("void main(%s VS_OUTPUT o[%d], inout %sStream output)\n{\n", primitives_d3d[primitive_type], vertex_in, g_ActiveConfig.bWireFrame ? "Line" : "Triangle"); } out.Write("\tVertexData ps;\n"); @@ -305,5 +306,5 @@ void GenerateGeometryShaderCode(ShaderCode& object, u32 primitive_type, API_TYPE bool IsPassthroughGeometryShader(GeometryShaderUid& object) { geometry_shader_uid_data* uid_data = object.GetUidData(); - return uid_data->primitive_type == PRIMITIVE_TRIANGLES && !uid_data->stereo; + return uid_data->primitive_type == PRIMITIVE_TRIANGLES && !uid_data->stereo && !uid_data->wireframe; } -- cgit v1.2.3 From 1b9fe70d7c0b567c7930297af296e765e91bc02b Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 19 Dec 2014 13:10:06 +0100 Subject: VideoCommon: Make IsPassthrough() a function of the ShaderUid. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 38be5193ca..eaba7652d6 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -7,7 +7,6 @@ #include "VideoCommon/BPMemory.h" #include "VideoCommon/GeometryShaderGen.h" #include "VideoCommon/LightingShaderGen.h" -#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexShaderGen.h" #include "VideoCommon/VideoConfig.h" @@ -302,9 +301,3 @@ void GenerateGeometryShaderCode(ShaderCode& object, u32 primitive_type, API_TYPE { GenerateGeometryShader(object, primitive_type, ApiType); } - -bool IsPassthroughGeometryShader(GeometryShaderUid& object) -{ - geometry_shader_uid_data* uid_data = object.GetUidData(); - return uid_data->primitive_type == PRIMITIVE_TRIANGLES && !uid_data->stereo && !uid_data->wireframe; -} -- cgit v1.2.3 From 531b3941ff612f9cc8dcb4b1d7de6cbec3ff1c08 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 19 Dec 2014 14:09:16 +0100 Subject: GeometryShaderGen: Re-emit the first vertex when wireframe mode is enabled. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 40 +++++++++++++++++++-------- 1 file changed, 29 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 eaba7652d6..a85e36b9bc 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -26,7 +26,8 @@ static const char* primitives_d3d[] = "triangle" }; -template static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType); +template static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex = false); +template static inline void EndPrimitive(T& out, API_TYPE ApiType); template static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE ApiType) @@ -45,10 +46,13 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A uid_data->primitive_type = primitive_type; const unsigned int vertex_in = primitive_type + 1; - const unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4; + unsigned int vertex_out = primitive_type == PRIMITIVE_TRIANGLES ? 3 : 4; - uid_data->stereo = g_ActiveConfig.iStereoMode > 0; uid_data->wireframe = g_ActiveConfig.bWireFrame; + if (g_ActiveConfig.bWireFrame) + vertex_out++; + + uid_data->stereo = g_ActiveConfig.iStereoMode > 0; if (ApiType == API_OPENGL) { // Insert layout parameters @@ -178,6 +182,9 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A out.Write("\tfor (int eye = 0; eye < 2; ++eye) {\n"); } + if (g_ActiveConfig.bWireFrame) + out.Write("\tVS_OUTPUT first;\n"); + out.Write("\tfor (int i = 0; i < %d; ++i) {\n", vertex_in); if (ApiType == API_OPENGL) @@ -221,7 +228,7 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } out.Write("\t}\n"); - EmitVertex(out, "l", ApiType); + EmitVertex(out, "l", ApiType, true); EmitVertex(out, "r", ApiType); } else if (primitive_type == PRIMITIVE_POINTS) @@ -249,22 +256,19 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } out.Write("\t}\n"); - EmitVertex(out, "ll", ApiType); + EmitVertex(out, "ll", ApiType, true); EmitVertex(out, "lr", ApiType); EmitVertex(out, "ul", ApiType); EmitVertex(out, "ur", ApiType); } else { - EmitVertex(out, "f", ApiType); + EmitVertex(out, "f", ApiType, true); } out.Write("\t}\n"); - if (ApiType == API_OPENGL) - out.Write("\tEndPrimitive();\n"); - else - out.Write("\toutput.RestartStrip();\n"); + EndPrimitive(out, ApiType); if (g_ActiveConfig.iStereoMode > 0 && !g_ActiveConfig.backend_info.bSupportsGSInstancing) out.Write("\t}\n"); @@ -279,8 +283,11 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A } template -static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType) +static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType, bool first_vertex) { + if (g_ActiveConfig.bWireFrame && first_vertex) + out.Write("\tif (i == 0) first = %s;\n", vertex); + if (ApiType == API_OPENGL) out.Write("\tgl_Position = %s.pos;\n", vertex); @@ -291,6 +298,17 @@ static inline void EmitVertex(T& out, const char* vertex, API_TYPE ApiType) else out.Write("\toutput.Append(ps);\n"); } +template +static inline void EndPrimitive(T& out, API_TYPE ApiType) +{ + if (g_ActiveConfig.bWireFrame) + EmitVertex(out, "first", ApiType); + + if (ApiType == API_OPENGL) + out.Write("\tEndPrimitive();\n"); + else + out.Write("\toutput.RestartStrip();\n"); +} void GetGeometryShaderUid(GeometryShaderUid& object, u32 primitive_type, API_TYPE ApiType) { -- cgit v1.2.3 From 0d79e8f32b1dd3f03fdcb857cd7e5c9b7ce30dfe Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Fri, 19 Dec 2014 18:24:33 +0100 Subject: VideoCommon: Don't specify the redundant in/out qualifier if GL_ARB_shading_language_420pack is supported. Some driver developers interpreted "can" as "must" in the OpenGL specs. (I'm looking at you AMD) --- 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 bcd7758fba..f2b102038e 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -88,11 +88,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 in VS_OUTPUT o;\n"); + out.Write("\tcentroid %s VS_OUTPUT o;\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "in"); out.Write("} vs[%d];\n", vertex_in); out.Write("out VertexData {\n"); - out.Write("\tcentroid out VS_OUTPUT o;\n"); + out.Write("\tcentroid %s VS_OUTPUT o;\n", g_ActiveConfig.backend_info.bSupportsBindingLayout ? "" : "out"); if (g_ActiveConfig.iStereoMode > 0) out.Write("\tflat int layer;\n"); -- cgit v1.2.3 From 7eb353b3bd05d7a24362c58ac61dcc40a04c3deb Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sun, 21 Dec 2014 12:52:14 +0100 Subject: VideoCommon: Don't pass structs between shaders, use the interface blocks instead. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 36 ++++++++++++++++++++------- 1 file changed, 27 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 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"); -- cgit v1.2.3 From 1b771deb56ff0c7add39c7c93eeb322f3e384435 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sat, 3 Jan 2015 01:44:04 +1300 Subject: Move worldpos into it's own varying. Previously it was packed into spare slots in clippos.xy and normal.w, but it's ugly and more importantly it's causing bugs. This was discovered during the debugging of a zfreeze branch, which expected clippos.xy to be xy position coordinates in clipspace (as the name suggested). Turns out the stereoscopy shader had also run into this trap, modifying clippos.x (introducing errors with per-pixel lighting). This commit has been moved outside of the zfreeze PR for fast merging. --- Source/Core/VideoCommon/GeometryShaderGen.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'Source/Core/VideoCommon/GeometryShaderGen.cpp') diff --git a/Source/Core/VideoCommon/GeometryShaderGen.cpp b/Source/Core/VideoCommon/GeometryShaderGen.cpp index 0a49487bf8..9566e7e3a5 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -219,7 +219,6 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A // 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("\tf.clipPos.x += " I_STEREOPARAMS"[eye] * (f.clipPos.w - " I_STEREOPARAMS"[2]);\n"); out.Write("\tf.pos.x += " I_STEREOPARAMS"[eye] * (f.pos.w - " I_STEREOPARAMS"[2]);\n"); } -- cgit v1.2.3 From 8c55ec0d5182df964b635b4440020da5ef7f9965 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 31 Jan 2015 23:32:23 +0100 Subject: GeometryShaderGen: Perspective divide the line coordinates before comparing the angle. --- 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 9566e7e3a5..08090a5322 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -150,7 +150,7 @@ static inline void GenerateGeometryShader(T& out, u32 primitive_type, API_TYPE A // horizontal depending the slope of the line. out.Write( "\tfloat2 offset;\n" - "\tfloat2 to = abs(end.pos.xy - start.pos.xy);\n" + "\tfloat2 to = abs(end.pos.xy / end.pos.w - start.pos.xy / start.pos.w);\n" // FIXME: What does real hardware do when line is at a 45-degree angle? // FIXME: Lines aren't drawn at the correct width. See Twilight Princess map. "\tif (" I_LINEPTPARAMS".y * to.y > " I_LINEPTPARAMS".x * to.x) {\n" -- cgit v1.2.3 From cefcb0ace9d363b3679b4e93bcc9ec05f1e5f4f8 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Mon, 18 May 2015 01:08:10 +0200 Subject: Update license headers to GPLv2+ --- 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 08090a5322..01393037ca 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -1,5 +1,5 @@ // Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2+ // Refer to the license.txt file included. #include -- cgit v1.2.3 From 30ebb2459eb97ba544547183854775df8460b475 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Sun, 24 May 2015 06:55:12 +0200 Subject: Set copyright year to when a file was created --- 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 01393037ca..8462822511 100644 --- a/Source/Core/VideoCommon/GeometryShaderGen.cpp +++ b/Source/Core/VideoCommon/GeometryShaderGen.cpp @@ -1,4 +1,4 @@ -// Copyright 2013 Dolphin Emulator Project +// Copyright 2014 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. -- cgit v1.2.3