diff --git a/internal/shaderir/glsl.go b/internal/shaderir/glsl.go index 749a0a459..efc884a25 100644 --- a/internal/shaderir/glsl.go +++ b/internal/shaderir/glsl.go @@ -27,8 +27,7 @@ precision highp float; #define lowp #define mediump #define highp -#endif -` +#endif` func isValidSwizzling(s string) bool { if len(s) < 1 || 4 < len(s) { @@ -88,17 +87,22 @@ func (p *Program) Glsl() (vertexShader, fragmentShader string) { // Vertex func var vslines []string { - for i, t := range p.Uniforms { - vslines = append(vslines, fmt.Sprintf("uniform %s;", p.glslVarDecl(&t, fmt.Sprintf("U%d", i)))) - } - for i := 0; i < p.TextureNum; i++ { - vslines = append(vslines, fmt.Sprintf("uniform sampler2D T%d;", i)) - } - for i, t := range p.Attributes { - vslines = append(vslines, fmt.Sprintf("attribute %s;", p.glslVarDecl(&t, fmt.Sprintf("A%d", i)))) - } - for i, t := range p.Varyings { - vslines = append(vslines, fmt.Sprintf("varying %s;", p.glslVarDecl(&t, fmt.Sprintf("V%d", i)))) + if len(p.Uniforms) > 0 || p.TextureNum > 0 || len(p.Attributes) > 0 || len(p.Varyings) > 0 { + if len(vslines) > 0 && vslines[len(vslines)-1] != "" { + vslines = append(vslines, "") + } + for i, t := range p.Uniforms { + vslines = append(vslines, fmt.Sprintf("uniform %s;", p.glslVarDecl(&t, fmt.Sprintf("U%d", i)))) + } + for i := 0; i < p.TextureNum; i++ { + vslines = append(vslines, fmt.Sprintf("uniform sampler2D T%d;", i)) + } + for i, t := range p.Attributes { + vslines = append(vslines, fmt.Sprintf("attribute %s;", p.glslVarDecl(&t, fmt.Sprintf("A%d", i)))) + } + for i, t := range p.Varyings { + vslines = append(vslines, fmt.Sprintf("varying %s;", p.glslVarDecl(&t, fmt.Sprintf("V%d", i)))) + } } if len(p.Funcs) > 0 { if len(vslines) > 0 && vslines[len(vslines)-1] != "" { @@ -128,14 +132,19 @@ func (p *Program) Glsl() (vertexShader, fragmentShader string) { // Fragment func var fslines []string { - for i, t := range p.Uniforms { - fslines = append(fslines, fmt.Sprintf("uniform %s;", p.glslVarDecl(&t, fmt.Sprintf("U%d", i)))) - } - for i := 0; i < p.TextureNum; i++ { - fslines = append(fslines, fmt.Sprintf("uniform sampler2D T%d;", i)) - } - for i, t := range p.Varyings { - fslines = append(fslines, fmt.Sprintf("varying %s;", p.glslVarDecl(&t, fmt.Sprintf("V%d", i)))) + if len(p.Uniforms) > 0 || p.TextureNum > 0 || len(p.Varyings) > 0 { + if len(fslines) > 0 && fslines[len(fslines)-1] != "" { + fslines = append(fslines, "") + } + for i, t := range p.Uniforms { + fslines = append(fslines, fmt.Sprintf("uniform %s;", p.glslVarDecl(&t, fmt.Sprintf("U%d", i)))) + } + for i := 0; i < p.TextureNum; i++ { + fslines = append(fslines, fmt.Sprintf("uniform sampler2D T%d;", i)) + } + for i, t := range p.Varyings { + fslines = append(fslines, fmt.Sprintf("varying %s;", p.glslVarDecl(&t, fmt.Sprintf("V%d", i)))) + } } if len(p.Funcs) > 0 { if len(fslines) > 0 && fslines[len(fslines)-1] != "" { @@ -162,22 +171,42 @@ func (p *Program) Glsl() (vertexShader, fragmentShader string) { } } + var tmpvslines []string + tmpfslines := strings.Split(GlslFragmentPrelude, "\n") + + // Struct types are determined after converting the program. var stlines []string - for i, t := range p.structTypes { - stlines = append(stlines, fmt.Sprintf("struct S%d {", i)) - for j, st := range t.Sub { - stlines = append(stlines, fmt.Sprintf("\t%s;", p.glslVarDecl(&st, fmt.Sprintf("M%d", j)))) + if len(p.structTypes) > 0 { + for i, t := range p.structTypes { + stlines = append(stlines, fmt.Sprintf("struct S%d {", i)) + for j, st := range t.Sub { + stlines = append(stlines, fmt.Sprintf("\t%s;", p.glslVarDecl(&st, fmt.Sprintf("M%d", j)))) + } + stlines = append(stlines, "};") } - stlines = append(stlines, "};") + + if len(tmpvslines) > 0 { + tmpvslines = append(tmpvslines, "") + } + tmpvslines = append(stlines, tmpvslines...) + + if len(tmpfslines) > 0 { + tmpfslines = append(tmpfslines, "") + } + copied := make([]string, len(stlines)) + copy(copied, stlines) + tmpfslines = append(tmpfslines, copied...) } - vslines = append(stlines, vslines...) + if len(tmpvslines) > 0 && len(vslines) > 0 { + tmpvslines = append(tmpvslines, "") + } + vslines = append(tmpvslines, vslines...) - tmp := make([]string, len(stlines)) - copy(tmp, stlines) - fslines = append(tmp, fslines...) - - fslines = append(strings.Split(GlslFragmentPrelude, "\n"), fslines...) + if len(tmpfslines) > 0 && len(fslines) > 0 { + tmpfslines = append(tmpfslines, "") + } + fslines = append(tmpfslines, fslines...) return strings.Join(vslines, "\n") + "\n", strings.Join(fslines, "\n") + "\n" } diff --git a/internal/shaderir/ir_test.go b/internal/shaderir/ir_test.go index 5a04817ec..4f8b14847 100644 --- a/internal/shaderir/ir_test.go +++ b/internal/shaderir/ir_test.go @@ -149,6 +149,8 @@ func fieldSelectorExpr(a, b Expr) Expr { } func TestOutput(t *testing.T) { + prelude := GlslFragmentPrelude + "\n" + tests := []struct { Name string Program Program @@ -169,7 +171,7 @@ func TestOutput(t *testing.T) { }, }, GlslVS: `uniform float U0;`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` uniform float U0;`, }, { @@ -187,11 +189,13 @@ uniform float U0;`, GlslVS: `struct S0 { float M0; }; + uniform S0 U0;`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` struct S0 { float M0; }; + uniform S0 U0;`, }, { @@ -210,7 +214,7 @@ uniform S0 U0;`, GlslVS: `uniform float U0; attribute vec2 A0; varying vec3 V0;`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` uniform float U0; varying vec3 V0;`, }, @@ -227,7 +231,7 @@ varying vec3 V0;`, void F0(void) { }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(void); void F0(void) { @@ -254,7 +258,7 @@ void F0(void) { void F0(in float l0, in vec2 l1, in vec4 l2, out mat4 l3) { }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in float l0, in vec2 l1, in vec4 l2, out mat4 l3); void F0(in float l0, in vec2 l1, in vec4 l2, out mat4 l3) { @@ -284,7 +288,7 @@ void F0(in float l0, in vec2 l1, in vec4 l2, out mat4 l3) { float F0(in float l0) { return l0; }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` float F0(in float l0); float F0(in float l0) { @@ -316,7 +320,7 @@ void F0(in float l0, out float l1) { mat4 l2 = mat4(0); mat4 l3 = mat4(0); }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in float l0, out float l1); void F0(in float l0, out float l1) { @@ -363,7 +367,7 @@ void F0(in float l0, out float l1) { mat4 l5 = mat4(0); } }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in float l0, out float l1); void F0(in float l0, out float l1) { @@ -407,7 +411,7 @@ void F0(in float l0, out float l1) { void F0(in float l0, in float l1, out float l2) { l2 = (l0) + (l1); }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in float l0, in float l1, out float l2); void F0(in float l0, in float l1, out float l2) { @@ -447,7 +451,7 @@ void F0(in float l0, in float l1, out float l2) { void F0(in bool l0, in float l1, in float l2, out float l3) { l3 = (l0) ? (l1) : (l2); }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in bool l0, in float l1, in float l2, out float l3); void F0(in bool l0, in float l1, in float l2, out float l3) { @@ -492,7 +496,7 @@ void F0(in float l0, in float l1, out vec2 l2) { F1(); l2 = F2(l0, l1); }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in float l0, in float l1, out vec2 l2); void F0(in float l0, in float l1, out vec2 l2) { @@ -532,7 +536,7 @@ void F0(in float l0, in float l1, out vec2 l2) { void F0(in float l0, in float l1, out float l2) { l2 = min(l0, l1); }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in float l0, in float l1, out float l2); void F0(in float l0, in float l1, out float l2) { @@ -569,7 +573,7 @@ void F0(in float l0, in float l1, out float l2) { void F0(in vec4 l0, out vec2 l1) { l1 = (l0).xz; }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in vec4 l0, out vec2 l1); void F0(in vec4 l0, out vec2 l1) { @@ -625,7 +629,7 @@ void F0(in float l0, in float l1, out float l2) { l2 = l1; } }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in float l0, in float l1, out float l2); void F0(in float l0, in float l1, out float l2) { @@ -676,7 +680,7 @@ void F0(in float l0, in float l1, out float l2) { l2 = l0; } }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` void F0(in float l0, in float l1, out float l2); void F0(in float l0, in float l1, out float l2) { @@ -730,7 +734,7 @@ void main(void) { V0 = A1; V1 = A2; }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` uniform float U0; varying float V0; varying vec2 V1;`, @@ -800,7 +804,7 @@ void main(void) { V0 = A1; V1 = A2; }`, - GlslFS: GlslFragmentPrelude + ` + GlslFS: prelude + ` uniform float U0; varying float V0; varying vec2 V1; @@ -815,20 +819,23 @@ void main(void) { }, } for _, tc := range tests { - vs, fs := tc.Program.Glsl() - { - got := vs - want := tc.GlslVS + "\n" - if got != want { - t.Errorf("%s: got: %s, want: %s", tc.Name, got, want) + tc := tc + t.Run(tc.Name, func(t *testing.T) { + vs, fs := tc.Program.Glsl() + { + got := vs + want := tc.GlslVS + "\n" + if got != want { + t.Errorf("%s vertex: got: %s, want: %s", tc.Name, got, want) + } } - } - { - got := fs - want := tc.GlslFS + "\n" - if got != want { - t.Errorf("%s: got: %s, want: %s", tc.Name, got, want) + { + got := fs + want := tc.GlslFS + "\n" + if got != want { + t.Errorf("%s fragment: got: %s, want: %s", tc.Name, got, want) + } } - } + }) } }