]> git.tdb.fi Git - libs/gl.git/commitdiff
Add a unit test framework and some tests for the GLSL compiler
authorMikko Rasa <tdb@tdb.fi>
Wed, 3 Mar 2021 23:44:59 +0000 (01:44 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 4 Mar 2021 11:46:15 +0000 (13:46 +0200)
Some of the tests fail due to bugs in the compiler.

24 files changed:
.gitignore
tests/Build [new file with mode: 0644]
tests/glsl/constant_condition_removal.glsl [new file with mode: 0644]
tests/glsl/expression_inline.glsl [new file with mode: 0644]
tests/glsl/expression_inline_iteration.glsl [new file with mode: 0644]
tests/glsl/expression_inline_precedence.glsl [new file with mode: 0644]
tests/glsl/function_inline.glsl [new file with mode: 0644]
tests/glsl/function_inline_in_condition.glsl [new file with mode: 0644]
tests/glsl/function_inline_in_iteration.glsl [new file with mode: 0644]
tests/glsl/function_inline_name_conflict.glsl [new file with mode: 0644]
tests/glsl/function_inline_reorder.glsl [new file with mode: 0644]
tests/glsl/geometry_interface_block.glsl [new file with mode: 0644]
tests/glsl/geometry_passthrough.glsl [new file with mode: 0644]
tests/glsl/glslcompiler.cpp [new file with mode: 0644]
tests/glsl/interface_block.glsl [new file with mode: 0644]
tests/glsl/member_assignment.glsl [new file with mode: 0644]
tests/glsl/multiline_function_inline.glsl [new file with mode: 0644]
tests/glsl/multiple_emitvertex.glsl [new file with mode: 0644]
tests/glsl/named_interface_block.glsl [new file with mode: 0644]
tests/glsl/passthrough.glsl [new file with mode: 0644]
tests/glsl/redundant_geometry_gl_position.glsl [new file with mode: 0644]
tests/glsl/redundant_gl_position.glsl [new file with mode: 0644]
tests/glsl/unused_function_removal.glsl [new file with mode: 0644]
tests/glsl/unused_variable_removal.glsl [new file with mode: 0644]

index cff6fec50fccf0ed2270736f5e607ef36fd2bd6a..676eb92d3aaf623550040fe6ae4888bc5b0c5694 100644 (file)
@@ -8,5 +8,6 @@ temp
 /mesh2c
 /mspgl.pc
 /shaders
+/tests/glsltest
 /texturing
 /viewer
diff --git a/tests/Build b/tests/Build
new file mode 100644 (file)
index 0000000..85dced1
--- /dev/null
@@ -0,0 +1,16 @@
+package "mspgl-tests"
+{
+       require "mspcore";
+       require "mspgl";
+       require "msptest";
+       require "sigc++-2.0";
+
+       program "glsltest"
+       {
+               source "glsl";
+               build_info
+               {
+                       standard CXX "c++11";
+               };
+       };
+};
diff --git a/tests/glsl/constant_condition_removal.glsl b/tests/glsl/constant_condition_removal.glsl
new file mode 100644 (file)
index 0000000..08a61fd
--- /dev/null
@@ -0,0 +1,36 @@
+const bool use_color = false;
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in vec4 color;
+void main()
+{
+       gl_Position = position;
+       passthrough;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+       if(use_color)
+               frag_color = color;
+       else
+               frag_color = vec4(1.0);
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+}
+*/
+
+/* Expected output: fragment
+layout(location=0) out vec4 frag_color;
+void main()
+{
+       frag_color = vec4(1.0);
+}
+*/
diff --git a/tests/glsl/expression_inline.glsl b/tests/glsl/expression_inline.glsl
new file mode 100644 (file)
index 0000000..a730e7d
--- /dev/null
@@ -0,0 +1,15 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+       vec4 p = position*2.0-1.0;
+       gl_Position = p;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position*2.0-1.0;
+}
+*/
diff --git a/tests/glsl/expression_inline_iteration.glsl b/tests/glsl/expression_inline_iteration.glsl
new file mode 100644 (file)
index 0000000..20136ca
--- /dev/null
@@ -0,0 +1,35 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in vec3 direction;
+void main()
+{
+       vec4 p = position.xyz;
+       int step = -1;
+       for(int i=0; i<10; ++i)
+       {
+               float scale = 2.0;
+               p += direction*scale;
+               if(p.z<0)
+                       break;
+               step = i;
+       }
+       gl_Position = position+vec4(step, 0.0, 0.0, 0.0);
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in vec3 direction;
+void main()
+{
+       vec4 p = position.xyz;
+       int step = -1;
+       for(int i=0; i<10; ++i)
+       {
+               p += direction*2.0;
+               if(p.z<0)
+                       break;
+               step = i;
+       }
+       gl_Position = position+vec4(step, 0.0, 0.0, 0.0);
+}
+*/
diff --git a/tests/glsl/expression_inline_precedence.glsl b/tests/glsl/expression_inline_precedence.glsl
new file mode 100644 (file)
index 0000000..9f37c83
--- /dev/null
@@ -0,0 +1,22 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in float v;
+void main()
+{
+       float a = v.x-v.y;
+       float b = v.z-v.w;
+       float c = v.x-v.y;
+       float d = v.z-v.w;
+       float e = a-b;
+       float f = c*d;
+       gl_Position = position*(e+f);
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in float v;
+void main()
+{
+       gl_Position = position*((v.x-v.y-(v.z-v.w))+(v.x-v.y)*(v.z-v.w));
+}
+*/
diff --git a/tests/glsl/function_inline.glsl b/tests/glsl/function_inline.glsl
new file mode 100644 (file)
index 0000000..d1920f2
--- /dev/null
@@ -0,0 +1,18 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+vec4 func()
+{
+       return position;
+}
+void main()
+{
+       gl_Position = func();
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+}
+*/
diff --git a/tests/glsl/function_inline_in_condition.glsl b/tests/glsl/function_inline_in_condition.glsl
new file mode 100644 (file)
index 0000000..796f888
--- /dev/null
@@ -0,0 +1,24 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in float scale;
+float func()
+{
+       float s = scale*2.0;
+       return s*s;
+}
+void main()
+{
+       if(func()>1.0)
+               gl_Position = position;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in float scale;
+void main()
+{
+       float s = scale*2.0;
+       if(s*s>1.0)
+               gl_Position = position;
+}
+*/
diff --git a/tests/glsl/function_inline_in_iteration.glsl b/tests/glsl/function_inline_in_iteration.glsl
new file mode 100644 (file)
index 0000000..a98a453
--- /dev/null
@@ -0,0 +1,28 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in float scale;
+float func()
+{
+       float s = scale*2.0;
+       return s*s;
+}
+void main()
+{
+       float p = 1.0;
+       for(float i=func(); i<10.0; i+=2.0)
+               p += i;
+       gl_Position = position*p;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in float scale;
+void main()
+{
+       float p = 1.0;
+       float s = scale*2.0;
+       for(float i=s*s; i<10.0; i+=2.0)
+               p += i;
+       gl_Position = position*p;
+}
+*/
diff --git a/tests/glsl/function_inline_name_conflict.glsl b/tests/glsl/function_inline_name_conflict.glsl
new file mode 100644 (file)
index 0000000..93c4eca
--- /dev/null
@@ -0,0 +1,24 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in float scale;
+float func()
+{
+       float s = scale*2.0;
+       return s*s;
+}
+void main()
+{
+       float s = scale+1.0;
+       gl_Position = position*func()*s*s;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in float scale;
+void main()
+{
+       float s = scale+1.0;
+       float _func_s = scale*2.0;
+       gl_Position = position*_func_s*_func_s*s*s;
+}
+*/
diff --git a/tests/glsl/function_inline_reorder.glsl b/tests/glsl/function_inline_reorder.glsl
new file mode 100644 (file)
index 0000000..3e445ce
--- /dev/null
@@ -0,0 +1,19 @@
+#pragma MSP stage(vertex)
+vec4 func();
+void main()
+{
+       gl_Position = func();
+}
+layout(location=0) in vec4 position;
+vec4 func()
+{
+       return position;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+}
+*/
diff --git a/tests/glsl/geometry_interface_block.glsl b/tests/glsl/geometry_interface_block.glsl
new file mode 100644 (file)
index 0000000..3934dd1
--- /dev/null
@@ -0,0 +1,85 @@
+uniform sampler2D tex;
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+out VertexOut
+{
+       vec2 texcoord;
+} vs_out;
+void main()
+{
+       vs_out.texcoord = position.xy*0.5+0.5;
+       gl_Position = position;
+}
+
+#pragma MSP stage(geometry)
+layout(triangles) in;
+layout(triangles, max_vertices=3) out;
+out GeometryOut
+{
+       vec2 texcoord;
+} gs_out;
+void main()
+{
+       for(int i=0; i<3; ++i)
+       {
+               gs_out.texcoord = vs_out[i].texcoord;
+               passthrough[i];
+               EmitVertex();
+       }
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+       frag_color = texture(tex, gs_out.texcoord);
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+out VertexOut
+{
+       vec2 texcoord;
+} vs_out;
+void main()
+{
+       vs_out.texcoord = position.xy*0.5+0.5;
+       gl_Position = position;
+}
+*/
+
+/* Expected output: geometry
+layout(triangles) in;
+layout(triangles, max_vertices=3) out;
+out GeometryOut
+{
+       vec2 texcoord;
+} gs_out;
+in VertexOut
+{
+       vec2 texcoord;
+} vs_out[];
+void main()
+{
+       for(int i = 0; i<3; ++i)
+       {
+               gs_out.texcoord = vs_out[i].texcoord;
+               gl_Position = gl_in[i].gl_Position;
+               EmitVertex();
+       }
+}
+*/
+
+/* Expected output: fragment
+uniform sampler2D tex;
+layout(location=0) out vec4 frag_color;
+in GeometryOut
+{
+       vec2 texcoord;
+} gs_out;
+void main()
+{
+       frag_color = texture(tex, gs_out.texcoord);
+}
+*/
diff --git a/tests/glsl/geometry_passthrough.glsl b/tests/glsl/geometry_passthrough.glsl
new file mode 100644 (file)
index 0000000..2004358
--- /dev/null
@@ -0,0 +1,64 @@
+uniform sampler2D tex;
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+       out vec2 texcoord = position.xy*0.5+0.5;
+       gl_Position = position;
+}
+
+#pragma MSP stage(geometry)
+layout(triangles) in;
+layout(triangles, max_vertices=3) out;
+void main()
+{
+       for(int i=0; i<3; ++i)
+       {
+               passthrough[i];
+               EmitVertex();
+       }
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+       frag_color = texture(tex, texcoord);
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+out vec2 texcoord;
+void main()
+{
+       texcoord = position.xy*0.5+0.5;
+       gl_Position = position;
+}
+*/
+
+/* Expected output: geometry
+layout(triangles) in;
+layout(triangles, max_vertices=3) out;
+in vec2 texcoord[];
+out vec2 _gs_out_texcoord;
+void main()
+{
+       for(int i = 0; i<3; ++i)
+       {
+               gl_Position = gl_in[i].gl_Position;
+               _gs_out_texcoord = texcoord[i];
+               EmitVertex();
+       }
+}
+*/
+
+/* Expected output: fragment
+uniform sampler2D tex;
+layout(location=0) out vec4 frag_color;
+in vec2 _gs_out_texcoord;
+void main()
+{
+       frag_color = texture(tex, _gs_out_texcoord);
+}
+*/
diff --git a/tests/glsl/glslcompiler.cpp b/tests/glsl/glslcompiler.cpp
new file mode 100644 (file)
index 0000000..57911cc
--- /dev/null
@@ -0,0 +1,134 @@
+#include <msp/core/algorithm.h>
+#include <msp/fs/dir.h>
+#include <msp/fs/utils.h>
+#include <msp/gl/glsl/compiler.h>
+#include <msp/gl/glsl/glsl_error.h>
+#include <msp/gl/glsl/tokenizer.h>
+#include <msp/strings/utils.h>
+#include <msp/test/test.h>
+
+#include <msp/io/print.h>
+
+class GlslCompilerTest: public Msp::Test::RegisteredTest<GlslCompilerTest>
+{
+private:
+       struct TestCase
+       {
+               std::string name;
+               std::string source;
+               std::map<Msp::GL::SL::Stage::Type, std::string> expected_output;
+       };
+
+       std::list<TestCase> test_cases;
+
+public:
+       GlslCompilerTest();
+
+       static const char *get_name() { return "GLSL compiler"; }
+
+private:
+       const TestCase &load_test_case(const std::string &);
+
+       void run_test_case(const TestCase *);
+};
+
+using namespace std;
+using namespace Msp;
+
+GlslCompilerTest::GlslCompilerTest()
+{
+       FS::Path tests_dir = "glsl";
+       list<string> test_files = FS::list_filtered(tests_dir, "\\.glsl$");
+       test_files.sort();
+       for(const auto &fn: test_files)
+               load_test_case((tests_dir/fn).str());
+
+       for(const auto &tc: test_cases)
+               add(&GlslCompilerTest::run_test_case, &tc, tc.name);
+}
+
+const GlslCompilerTest::TestCase &GlslCompilerTest::load_test_case(const string &fn)
+{
+       IO::BufferedFile file(fn);
+       TestCase test_case;
+       test_case.name = FS::basename(fn);
+       string *target = &test_case.source;
+       while(!file.eof())
+       {
+               string line;
+               if(!file.getline(line))
+                       break;
+
+               if(line=="*/")
+                       continue;
+
+               string::size_type expected = line.find("Expected output:");
+               if(expected!=string::npos)
+               {
+                       string stage = strip(line.substr(expected+16));
+                       if(stage=="vertex")
+                               target = &test_case.expected_output[GL::SL::Stage::VERTEX];
+                       else if(stage=="geometry")
+                               target = &test_case.expected_output[GL::SL::Stage::GEOMETRY];
+                       else if(stage=="fragment")
+                               target = &test_case.expected_output[GL::SL::Stage::FRAGMENT];
+                       else
+                               throw runtime_error("Unknown stage "+stage);
+                       continue;
+               }
+
+               *target += line;
+               *target += '\n';
+       }
+       test_cases.push_back(test_case);
+
+       return test_cases.back();
+}
+
+void GlslCompilerTest::run_test_case(const TestCase *test_case)
+{
+       GL::SL::Compiler compiler(GL::SL::Features::all());
+       compiler.set_source(test_case->source, "<test>");
+       compiler.compile(GL::SL::Compiler::PROGRAM);
+
+       auto stages = compiler.get_stages();
+       for(auto s: stages)
+       {
+               auto i = test_case->expected_output.find(s);
+               if(i==test_case->expected_output.end())
+                       fail(format("Compiler produced extra stage %s", GL::SL::Stage::get_stage_name(s)));
+
+               string output = compiler.get_stage_glsl(s);
+               debug(format("Output for stage %s:", GL::SL::Stage::get_stage_name(s)));
+               auto lines = split_fields(output, '\n');
+               for(unsigned j=0; j<lines.size(); ++j)
+                       debug(format("%3d: %s", j+1, lines[j]));
+
+               GL::SL::Tokenizer tokenizer;
+               tokenizer.begin("<output>", output);
+
+               GL::SL::Tokenizer expected_tkn;
+               expected_tkn.begin("<expected>", i->second);
+
+               while(1)
+               {
+                       string token = expected_tkn.parse_token();
+
+                       try
+                       {
+                               tokenizer.expect(token);
+                       }
+                       catch(const GL::SL::invalid_shader_source &exc)
+                       {
+                               fail(exc.what());
+                       }
+
+                       if(token.empty())
+                               break;
+               }
+       }
+
+       for(const auto &s: test_case->expected_output)
+               if(find(stages, s.first)==stages.end())
+                       fail(format("Compiler didn't produce stage %s", GL::SL::Stage::get_stage_name(s.first)));
+}
diff --git a/tests/glsl/interface_block.glsl b/tests/glsl/interface_block.glsl
new file mode 100644 (file)
index 0000000..41d7a63
--- /dev/null
@@ -0,0 +1,45 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in vec4 color;
+out VertexOut
+{
+       vec4 out_color;
+};
+void main()
+{
+       gl_Position = position;
+       out_color = color;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+       frag_color = out_color;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in vec4 color;
+out VertexOut
+{
+       vec4 out_color;
+};
+void main()
+{
+       gl_Position = position;
+       out_color = color;
+}
+*/
+
+/* Expected output: fragment
+layout(location=0) out vec4 frag_color;
+in VertexOut
+{
+       vec4 out_color;
+};
+void main()
+{
+       frag_color = out_color;
+}
+*/
diff --git a/tests/glsl/member_assignment.glsl b/tests/glsl/member_assignment.glsl
new file mode 100644 (file)
index 0000000..8444cfc
--- /dev/null
@@ -0,0 +1,22 @@
+#pragma MSP stage(vertex)
+void main()
+{
+       vec4 p;
+       p.x = 1.0;
+       p.y = 0.0;
+       p.z = 2.0;
+       p.w = 1.0;
+       gl_Position = p;
+}
+
+/* Expected output: vertex
+void main()
+{
+       vec4 p;
+       p.x = 1.0;
+       p.y = 0.0;
+       p.z = 2.0;
+       p.w = 1.0;
+       gl_Position = p;
+}
+*/
diff --git a/tests/glsl/multiline_function_inline.glsl b/tests/glsl/multiline_function_inline.glsl
new file mode 100644 (file)
index 0000000..e8f05bd
--- /dev/null
@@ -0,0 +1,22 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in float scale;
+vec4 func()
+{
+       float s = scale*2.0;
+       return position*s*s;
+}
+void main()
+{
+       gl_Position = func();
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in float scale;
+void main()
+{
+       float s = scale*2.0;
+       gl_Position = position*s*s;
+}
+*/
diff --git a/tests/glsl/multiple_emitvertex.glsl b/tests/glsl/multiple_emitvertex.glsl
new file mode 100644 (file)
index 0000000..06c129d
--- /dev/null
@@ -0,0 +1,68 @@
+uniform sampler2D tex;
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+       out vec2 texcoord = position.xy*0.5+0.5;
+       gl_Position = position;
+}
+
+#pragma MSP stage(geometry)
+layout(triangles) in;
+layout(triangles, max_vertices=3) out;
+void main()
+{
+       passthrough[0];
+       EmitVertex();
+       passthrough[1];
+       EmitVertex();
+       passthrough[2];
+       EmitVertex();
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+       frag_color = texture(tex, texcoord);
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+out vec2 texcoord;
+void main()
+{
+       texcoord = position.xy*0.5+0.5;
+       gl_Position = position;
+}
+*/
+
+/* Expected output: geometry
+layout(triangles) in;
+layout(triangles, max_vertices=3) out;
+in vec2 texcoord[];
+out vec2 _gs_out_texcoord;
+void main()
+{
+       gl_Position = gl_in[0].gl_Position;
+       _gs_out_texcoord = texcoord[0];
+       EmitVertex();
+       gl_Position = gl_in[1].gl_Position;
+       _gs_out_texcoord = texcoord[1];
+       EmitVertex();
+       gl_Position = gl_in[2].gl_Position;
+       _gs_out_texcoord = texcoord[2];
+       EmitVertex();
+}
+*/
+
+/* Expected output: fragment
+uniform sampler2D tex;
+layout(location=0) out vec4 frag_color;
+in vec2 _gs_out_texcoord;
+void main()
+{
+       frag_color = texture(tex, _gs_out_texcoord);
+}
+*/
diff --git a/tests/glsl/named_interface_block.glsl b/tests/glsl/named_interface_block.glsl
new file mode 100644 (file)
index 0000000..9d734bd
--- /dev/null
@@ -0,0 +1,45 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in vec4 color;
+out VertexOut
+{
+       vec4 color;
+} vs_out;
+void main()
+{
+       gl_Position = position;
+       vs_out.color = color;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+       frag_color = vs_out.color;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in vec4 color;
+out VertexOut
+{
+       vec4 color;
+} vs_out;
+void main()
+{
+       gl_Position = position;
+       vs_out.color = color;
+}
+*/
+
+/* Expected output: fragment
+layout(location=0) out vec4 frag_color;
+in VertexOut
+{
+       vec4 color;
+} vs_out;
+void main()
+{
+       frag_color = vs_out.color;
+}
+*/
diff --git a/tests/glsl/passthrough.glsl b/tests/glsl/passthrough.glsl
new file mode 100644 (file)
index 0000000..4017e49
--- /dev/null
@@ -0,0 +1,35 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in vec4 color;
+void main()
+{
+       gl_Position = position;
+       passthrough;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) out vec4 frag_color;
+void main()
+{
+       frag_color = color;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+layout(location=1) in vec4 color;
+out vec4 _vs_out_color;
+void main()
+{
+       gl_Position = position;
+       _vs_out_color = color;
+}
+*/
+
+/* Expected output: fragment
+layout(location=0) out vec4 frag_color;
+in vec4 _vs_out_color;
+void main()
+{
+       frag_color = _vs_out_color;
+}
+*/
diff --git a/tests/glsl/redundant_geometry_gl_position.glsl b/tests/glsl/redundant_geometry_gl_position.glsl
new file mode 100644 (file)
index 0000000..99d4330
--- /dev/null
@@ -0,0 +1,41 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+       gl_Position = position;
+}
+
+#pragma MSP stage(geometry)
+layout(triangles) in;
+layout(triangles, max_vertices=3) out;
+void main()
+{
+       for(int i=0; i<3; ++i)
+       {
+               passthrough[i];
+               gl_Position = gl_in[i].gl_Position;
+               EmitVertex();
+       }
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+}
+*/
+
+/* Expected output: geometry
+layout(triangles) in;
+layout(triangles, max_vertices=3) out;
+void main()
+{
+       for(int i = 0; i<3; ++i)
+       {
+               gl_Position = gl_in[i].gl_Position;
+               EmitVertex();
+       }
+}
+*/
diff --git a/tests/glsl/redundant_gl_position.glsl b/tests/glsl/redundant_gl_position.glsl
new file mode 100644 (file)
index 0000000..3ac4534
--- /dev/null
@@ -0,0 +1,15 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+       gl_Position = position;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+}
+*/
diff --git a/tests/glsl/unused_function_removal.glsl b/tests/glsl/unused_function_removal.glsl
new file mode 100644 (file)
index 0000000..67541de
--- /dev/null
@@ -0,0 +1,18 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+float func()
+{
+       return 3.0;
+}
+void main()
+{
+       gl_Position = position;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+}
+*/
diff --git a/tests/glsl/unused_variable_removal.glsl b/tests/glsl/unused_variable_removal.glsl
new file mode 100644 (file)
index 0000000..a295dc7
--- /dev/null
@@ -0,0 +1,16 @@
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+layout(location=1) in vec4 color;
+void main()
+{
+       out vec2 texcoord = position.xy*0.5+0.5;
+       gl_Position = position;
+}
+
+/* Expected output: vertex
+layout(location=0) in vec4 position;
+void main()
+{
+       gl_Position = position;
+}
+*/