From a43efb66b2c7e7745ad437e179dfe427cc91657e Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 27 Jul 2020 23:51:05 +0900 Subject: [PATCH] shaderir: Bug fix: Function prototypes were required for GLSL Fixes #1267 --- internal/shader/testdata/assign.expected.vs | 2 + .../testdata/assign_multiple.expected.vs | 3 + internal/shader/testdata/blocks.expected.vs | 2 + internal/shader/testdata/blocks2.expected.vs | 2 + internal/shader/testdata/bool.expected.vs | 2 + internal/shader/testdata/call.expected.vs | 3 + .../shader/testdata/call_multiple.expected.vs | 3 + .../testdata/call_multiple_nested.expected.vs | 3 + internal/shader/testdata/define.expected.vs | 2 + internal/shader/testdata/define2.expected.vs | 3 + .../testdata/define_multiple.expected.vs | 3 + .../shader/testdata/define_type.expected.vs | 2 + internal/shader/testdata/for.expected.vs | 2 + internal/shader/testdata/for2.expected.vs | 2 + internal/shader/testdata/func.expected.vs | 2 + .../shader/testdata/func_body.expected.vs | 2 + .../shader/testdata/func_multiple.expected.vs | 2 + internal/shader/testdata/if.expected.vs | 2 + internal/shader/testdata/if_else.expected.vs | 2 + internal/shader/testdata/if_init.expected.vs | 2 + internal/shader/testdata/inc.expected.vs | 2 + .../shader/testdata/issue1236.expected.vs | 2 + internal/shader/testdata/number.expected.vs | 5 + .../shader/testdata/number_binary.expected.vs | 3 + .../shader/testdata/number_unary.expected.vs | 3 + internal/shader/testdata/var.expected.vs | 2 + internal/shader/testdata/var2.expected.vs | 2 + .../shader/testdata/var_multiple.expected.vs | 4 + internal/shaderir/glsl.go | 28 +++++- internal/shaderir/ir_test.go | 96 ++++++++++++++----- 30 files changed, 165 insertions(+), 28 deletions(-) diff --git a/internal/shader/testdata/assign.expected.vs b/internal/shader/testdata/assign.expected.vs index b4ba11f6b..9efbf9885 100644 --- a/internal/shader/testdata/assign.expected.vs +++ b/internal/shader/testdata/assign.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec2 l0, out vec4 l1); + void F0(in vec2 l0, out vec4 l1) { float l2 = float(0); l2 = 0.0; diff --git a/internal/shader/testdata/assign_multiple.expected.vs b/internal/shader/testdata/assign_multiple.expected.vs index 283278260..35f03727a 100644 --- a/internal/shader/testdata/assign_multiple.expected.vs +++ b/internal/shader/testdata/assign_multiple.expected.vs @@ -1,3 +1,6 @@ +void F0(in vec2 l0, out vec4 l1); +void F1(out float l0, out float l1); + void F0(in vec2 l0, out vec4 l1) { float l2 = float(0); float l3 = float(0); diff --git a/internal/shader/testdata/blocks.expected.vs b/internal/shader/testdata/blocks.expected.vs index 2a026d189..b0c11bfe0 100644 --- a/internal/shader/testdata/blocks.expected.vs +++ b/internal/shader/testdata/blocks.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec2 l0, out vec4 l1); + void F0(in vec2 l0, out vec4 l1) { vec4 l2 = vec4(0); { diff --git a/internal/shader/testdata/blocks2.expected.vs b/internal/shader/testdata/blocks2.expected.vs index cc8c008bb..1e1dbd57e 100644 --- a/internal/shader/testdata/blocks2.expected.vs +++ b/internal/shader/testdata/blocks2.expected.vs @@ -1,3 +1,5 @@ +void F0(out vec2 l0); + void F0(out vec2 l0) { bool l1 = false; l1 = true; diff --git a/internal/shader/testdata/bool.expected.vs b/internal/shader/testdata/bool.expected.vs index 4724a44bf..886c85177 100644 --- a/internal/shader/testdata/bool.expected.vs +++ b/internal/shader/testdata/bool.expected.vs @@ -1,3 +1,5 @@ +void F0(out bool l0); + void F0(out bool l0) { l0 = true; return; diff --git a/internal/shader/testdata/call.expected.vs b/internal/shader/testdata/call.expected.vs index 5bc75dc0b..e0fe54104 100644 --- a/internal/shader/testdata/call.expected.vs +++ b/internal/shader/testdata/call.expected.vs @@ -1,3 +1,6 @@ +void F0(in vec2 l0, out vec2 l1); +void F1(in vec2 l0, out vec2 l1); + void F0(in vec2 l0, out vec2 l1) { vec2 l2 = vec2(0); F1(l0, l2); diff --git a/internal/shader/testdata/call_multiple.expected.vs b/internal/shader/testdata/call_multiple.expected.vs index 6297371dc..cec73210d 100644 --- a/internal/shader/testdata/call_multiple.expected.vs +++ b/internal/shader/testdata/call_multiple.expected.vs @@ -1,3 +1,6 @@ +void F0(in vec2 l0, out vec2 l1); +void F1(in float l0, out float l1, out float l2); + void F0(in vec2 l0, out vec2 l1) { float l2 = float(0); float l3 = float(0); diff --git a/internal/shader/testdata/call_multiple_nested.expected.vs b/internal/shader/testdata/call_multiple_nested.expected.vs index 3af08078a..c7b2ba95d 100644 --- a/internal/shader/testdata/call_multiple_nested.expected.vs +++ b/internal/shader/testdata/call_multiple_nested.expected.vs @@ -1,3 +1,6 @@ +void F0(in vec2 l0); +void F1(in float l0, in float l1, out float l2, out float l3); + void F0(in vec2 l0) { float l1 = float(0); float l2 = float(0); diff --git a/internal/shader/testdata/define.expected.vs b/internal/shader/testdata/define.expected.vs index 871bd197f..7e48ae6d4 100644 --- a/internal/shader/testdata/define.expected.vs +++ b/internal/shader/testdata/define.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec2 l0, out vec4 l1); + void F0(in vec2 l0, out vec4 l1) { vec4 l2 = vec4(0); l2 = vec4(l0, 0.0, 1.0); diff --git a/internal/shader/testdata/define2.expected.vs b/internal/shader/testdata/define2.expected.vs index e1f67f63a..c0980aafb 100644 --- a/internal/shader/testdata/define2.expected.vs +++ b/internal/shader/testdata/define2.expected.vs @@ -1,3 +1,6 @@ +void F0(out vec2 l0); +void F1(out vec2 l0); + void F0(out vec2 l0) { vec2 l1 = vec2(0); vec2 l2 = vec2(0); diff --git a/internal/shader/testdata/define_multiple.expected.vs b/internal/shader/testdata/define_multiple.expected.vs index 6676720bb..c7d936ac0 100644 --- a/internal/shader/testdata/define_multiple.expected.vs +++ b/internal/shader/testdata/define_multiple.expected.vs @@ -1,3 +1,6 @@ +void F0(in vec2 l0, out vec4 l1); +void F1(out float l0, out float l1); + void F0(in vec2 l0, out vec4 l1) { float l2 = float(0); float l3 = float(0); diff --git a/internal/shader/testdata/define_type.expected.vs b/internal/shader/testdata/define_type.expected.vs index 9669be327..ce6eb64e4 100644 --- a/internal/shader/testdata/define_type.expected.vs +++ b/internal/shader/testdata/define_type.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec2 l0, out vec4 l1); + void F0(in vec2 l0, out vec4 l1) { vec4 l2 = vec4(0); l2 = (vec4(0.0)) * (vec4(0.0)); diff --git a/internal/shader/testdata/for.expected.vs b/internal/shader/testdata/for.expected.vs index 1c575cb3d..9cb3f640c 100644 --- a/internal/shader/testdata/for.expected.vs +++ b/internal/shader/testdata/for.expected.vs @@ -1,3 +1,5 @@ +void F0(out vec2 l0); + void F0(out vec2 l0) { vec2 l1 = vec2(0); vec2 l3 = vec2(0); diff --git a/internal/shader/testdata/for2.expected.vs b/internal/shader/testdata/for2.expected.vs index 1dffd9e53..0fa15b435 100644 --- a/internal/shader/testdata/for2.expected.vs +++ b/internal/shader/testdata/for2.expected.vs @@ -1,3 +1,5 @@ +void F0(out vec2 l0); + void F0(out vec2 l0) { vec2 l1 = vec2(0); vec2 l3 = vec2(0); diff --git a/internal/shader/testdata/func.expected.vs b/internal/shader/testdata/func.expected.vs index 1caab6b77..7aff03283 100644 --- a/internal/shader/testdata/func.expected.vs +++ b/internal/shader/testdata/func.expected.vs @@ -1,2 +1,4 @@ +void F0(in vec2 l0, out vec4 l1); + void F0(in vec2 l0, out vec4 l1) { } diff --git a/internal/shader/testdata/func_body.expected.vs b/internal/shader/testdata/func_body.expected.vs index 2447550ab..9a9a0a32f 100644 --- a/internal/shader/testdata/func_body.expected.vs +++ b/internal/shader/testdata/func_body.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec2 l0, out vec4 l1); + void F0(in vec2 l0, out vec4 l1) { l1 = vec4(l0, 0.0, 1.0); return; diff --git a/internal/shader/testdata/func_multiple.expected.vs b/internal/shader/testdata/func_multiple.expected.vs index 81d83fd84..61ddb6372 100644 --- a/internal/shader/testdata/func_multiple.expected.vs +++ b/internal/shader/testdata/func_multiple.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec4 l0, out float l1, out float l2, out float l3, out float l4); + void F0(in vec4 l0, out float l1, out float l2, out float l3, out float l4) { l1 = (l0).x; l2 = (l0).y; diff --git a/internal/shader/testdata/if.expected.vs b/internal/shader/testdata/if.expected.vs index 87e49908e..d91f6cea8 100644 --- a/internal/shader/testdata/if.expected.vs +++ b/internal/shader/testdata/if.expected.vs @@ -1,3 +1,5 @@ +void F0(out vec2 l0); + void F0(out vec2 l0) { bool l1 = false; l1 = true; diff --git a/internal/shader/testdata/if_else.expected.vs b/internal/shader/testdata/if_else.expected.vs index 50f85f4f2..e3cc97175 100644 --- a/internal/shader/testdata/if_else.expected.vs +++ b/internal/shader/testdata/if_else.expected.vs @@ -1,3 +1,5 @@ +void F0(out vec2 l0); + void F0(out vec2 l0) { bool l1 = false; l1 = true; diff --git a/internal/shader/testdata/if_init.expected.vs b/internal/shader/testdata/if_init.expected.vs index f8624dcf6..ff15f6c8d 100644 --- a/internal/shader/testdata/if_init.expected.vs +++ b/internal/shader/testdata/if_init.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec2 l0, out vec2 l1); + void F0(in vec2 l0, out vec2 l1) { vec2 l2 = vec2(0); l2 = vec2(0.0); diff --git a/internal/shader/testdata/inc.expected.vs b/internal/shader/testdata/inc.expected.vs index 2532b1288..ecd439d66 100644 --- a/internal/shader/testdata/inc.expected.vs +++ b/internal/shader/testdata/inc.expected.vs @@ -1,3 +1,5 @@ +void F0(out vec2 l0); + void F0(out vec2 l0) { int l1 = 0; int l2 = 0; diff --git a/internal/shader/testdata/issue1236.expected.vs b/internal/shader/testdata/issue1236.expected.vs index 72da70085..39e0c3a6e 100644 --- a/internal/shader/testdata/issue1236.expected.vs +++ b/internal/shader/testdata/issue1236.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec4 l0, out vec4 l1); + void F0(in vec4 l0, out vec4 l1) { vec4 l2 = vec4(0); l2 = (mat4(1.0)) * (l0); diff --git a/internal/shader/testdata/number.expected.vs b/internal/shader/testdata/number.expected.vs index 29c5561e6..14afc5772 100644 --- a/internal/shader/testdata/number.expected.vs +++ b/internal/shader/testdata/number.expected.vs @@ -1,3 +1,8 @@ +void F0(out vec2 l0); +void F1(out vec2 l0); +void F2(out float l0); +void F3(out int l0); + void F0(out vec2 l0) { float l1 = float(0); int l2 = 0; diff --git a/internal/shader/testdata/number_binary.expected.vs b/internal/shader/testdata/number_binary.expected.vs index 2edd6c11f..30cb9d236 100644 --- a/internal/shader/testdata/number_binary.expected.vs +++ b/internal/shader/testdata/number_binary.expected.vs @@ -1,3 +1,6 @@ +void F0(out vec4 l0); +void F1(out vec4 l0); + void F0(out vec4 l0) { int l1 = 0; float l2 = float(0); diff --git a/internal/shader/testdata/number_unary.expected.vs b/internal/shader/testdata/number_unary.expected.vs index 23731211e..43ac16eb0 100644 --- a/internal/shader/testdata/number_unary.expected.vs +++ b/internal/shader/testdata/number_unary.expected.vs @@ -1,3 +1,6 @@ +void F0(out vec4 l0); +void F1(out vec4 l0); + void F0(out vec4 l0) { int l1 = 0; int l2 = 0; diff --git a/internal/shader/testdata/var.expected.vs b/internal/shader/testdata/var.expected.vs index 871bd197f..7e48ae6d4 100644 --- a/internal/shader/testdata/var.expected.vs +++ b/internal/shader/testdata/var.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec2 l0, out vec4 l1); + void F0(in vec2 l0, out vec4 l1) { vec4 l2 = vec4(0); l2 = vec4(l0, 0.0, 1.0); diff --git a/internal/shader/testdata/var2.expected.vs b/internal/shader/testdata/var2.expected.vs index 1f1609ac0..db5a2a0e3 100644 --- a/internal/shader/testdata/var2.expected.vs +++ b/internal/shader/testdata/var2.expected.vs @@ -1,3 +1,5 @@ +void F0(in vec2 l0, out vec4 l1); + void F0(in vec2 l0, out vec4 l1) { vec4 l2 = vec4(0); vec4 l3 = vec4(0); diff --git a/internal/shader/testdata/var_multiple.expected.vs b/internal/shader/testdata/var_multiple.expected.vs index 62d89b6a3..b3db596e0 100644 --- a/internal/shader/testdata/var_multiple.expected.vs +++ b/internal/shader/testdata/var_multiple.expected.vs @@ -1,3 +1,7 @@ +void F0(in vec2 l0, out vec4 l1); +void F1(in vec2 l0, out vec4 l1); +void F2(out vec2 l0, out vec2 l1); + void F0(in vec2 l0, out vec4 l1) { vec2 l2 = vec2(0); vec2 l3 = vec2(0); diff --git a/internal/shaderir/glsl.go b/internal/shaderir/glsl.go index 8b18672a7..e39701882 100644 --- a/internal/shaderir/glsl.go +++ b/internal/shaderir/glsl.go @@ -91,11 +91,19 @@ func (p *Program) Glsl() (vertexShader, fragmentShader string) { 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 = append(vslines, "") + } + } + for _, f := range p.Funcs { + vslines = append(vslines, p.glslFunc(&f, true)...) + } for _, f := range p.Funcs { if len(vslines) > 0 { vslines = append(vslines, "") } - vslines = append(vslines, p.glslFunc(&f)...) + vslines = append(vslines, p.glslFunc(&f, false)...) } if len(p.VertexFunc.Block.Stmts) > 0 { @@ -124,7 +132,13 @@ func (p *Program) Glsl() (vertexShader, fragmentShader string) { if len(fslines) > 0 { fslines = append(fslines, "") } - fslines = append(fslines, p.glslFunc(&f)...) + fslines = append(fslines, p.glslFunc(&f, true)...) + } + for _, f := range p.Funcs { + if len(fslines) > 0 { + fslines = append(fslines, "") + } + fslines = append(fslines, p.glslFunc(&f, false)...) } if len(p.FragmentFunc.Block.Stmts) > 0 { @@ -211,7 +225,7 @@ func (p *Program) glslVarInit(t *Type) string { } } -func (p *Program) glslFunc(f *Func) []string { +func (p *Program) glslFunc(f *Func, prototype bool) []string { var args []string var idx int for _, t := range f.InParams { @@ -227,8 +241,14 @@ func (p *Program) glslFunc(f *Func) []string { argsstr = strings.Join(args, ", ") } + sig := fmt.Sprintf("%s F%d(%s)", p.glslType(&f.Return), f.Index, argsstr) + var lines []string - lines = append(lines, fmt.Sprintf("%s F%d(%s) {", p.glslType(&f.Return), f.Index, argsstr)) + if prototype { + lines = append(lines, fmt.Sprintf("%s;", sig)) + return lines + } + lines = append(lines, fmt.Sprintf("%s {", sig)) lines = append(lines, p.glslBlock(&f.Block, &f.Block, 0, idx)...) lines = append(lines, "}") diff --git a/internal/shaderir/ir_test.go b/internal/shaderir/ir_test.go index 3671bd186..c8d71e231 100644 --- a/internal/shaderir/ir_test.go +++ b/internal/shaderir/ir_test.go @@ -220,9 +220,13 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(void) { + GlslVS: `void F0(void); + +void F0(void) { }`, - GlslFS: `void F0(void) { + GlslFS: `void F0(void); + +void F0(void) { }`, }, { @@ -242,9 +246,13 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in float l0, in vec2 l1, in vec4 l2, out mat4 l3) { + GlslVS: `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) { }`, - GlslFS: `void F0(in float l0, in vec2 l1, in vec4 l2, out mat4 l3) { + GlslFS: `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) { }`, }, { @@ -266,10 +274,14 @@ varying vec3 V0;`, }, }, }, - GlslVS: `float F0(in float l0) { + GlslVS: `float F0(in float l0); + +float F0(in float l0) { return l0; }`, - GlslFS: `float F0(in float l0) { + GlslFS: `float F0(in float l0); + +float F0(in float l0) { return l0; }`, }, @@ -292,11 +304,15 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in float l0, out float l1) { + GlslVS: `void F0(in float l0, out float l1); + +void F0(in float l0, out float l1) { mat4 l2 = mat4(0); mat4 l3 = mat4(0); }`, - GlslFS: `void F0(in float l0, out float l1) { + GlslFS: `void F0(in float l0, out float l1); + +void F0(in float l0, out float l1) { mat4 l2 = mat4(0); mat4 l3 = mat4(0); }`, @@ -330,7 +346,9 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in float l0, out float l1) { + GlslVS: `void F0(in float l0, out float l1); + +void F0(in float l0, out float l1) { mat4 l2 = mat4(0); mat4 l3 = mat4(0); { @@ -338,7 +356,9 @@ varying vec3 V0;`, mat4 l5 = mat4(0); } }`, - GlslFS: `void F0(in float l0, out float l1) { + GlslFS: `void F0(in float l0, out float l1); + +void F0(in float l0, out float l1) { mat4 l2 = mat4(0); mat4 l3 = mat4(0); { @@ -374,10 +394,14 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in float l0, in float l1, out float l2) { + GlslVS: `void F0(in float l0, in float l1, out float l2); + +void F0(in float l0, in float l1, out float l2) { l2 = (l0) + (l1); }`, - GlslFS: `void F0(in float l0, in float l1, out float l2) { + GlslFS: `void F0(in float l0, in float l1, out float l2); + +void F0(in float l0, in float l1, out float l2) { l2 = (l0) + (l1); }`, }, @@ -409,10 +433,14 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in bool l0, in float l1, in float l2, out float l3) { + GlslVS: `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) { l3 = (l0) ? (l1) : (l2); }`, - GlslFS: `void F0(in bool l0, in float l1, in float l2, out float l3) { + GlslFS: `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) { l3 = (l0) ? (l1) : (l2); }`, }, @@ -448,11 +476,15 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in float l0, in float l1, out vec2 l2) { + GlslVS: `void F0(in float l0, in float l1, out vec2 l2); + +void F0(in float l0, in float l1, out vec2 l2) { F1(); l2 = F2(l0, l1); }`, - GlslFS: `void F0(in float l0, in float l1, out vec2 l2) { + GlslFS: `void F0(in float l0, in float l1, out vec2 l2); + +void F0(in float l0, in float l1, out vec2 l2) { F1(); l2 = F2(l0, l1); }`, @@ -484,10 +516,14 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in float l0, in float l1, out float l2) { + GlslVS: `void F0(in float l0, in float l1, out float l2); + +void F0(in float l0, in float l1, out float l2) { l2 = min(l0, l1); }`, - GlslFS: `void F0(in float l0, in float l1, out float l2) { + GlslFS: `void F0(in float l0, in float l1, out float l2); + +void F0(in float l0, in float l1, out float l2) { l2 = min(l0, l1); }`, }, @@ -516,10 +552,14 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in vec4 l0, out vec2 l1) { + GlslVS: `void F0(in vec4 l0, out vec2 l1); + +void F0(in vec4 l0, out vec2 l1) { l1 = (l0).xz; }`, - GlslFS: `void F0(in vec4 l0, out vec2 l1) { + GlslFS: `void F0(in vec4 l0, out vec2 l1); + +void F0(in vec4 l0, out vec2 l1) { l1 = (l0).xz; }`, }, @@ -563,14 +603,18 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in float l0, in float l1, out float l2) { + GlslVS: `void F0(in float l0, in float l1, out float l2); + +void F0(in float l0, in float l1, out float l2) { if ((l0) == (0.0)) { l2 = l0; } else { l2 = l1; } }`, - GlslFS: `void F0(in float l0, in float l1, out float l2) { + GlslFS: `void F0(in float l0, in float l1, out float l2); + +void F0(in float l0, in float l1, out float l2) { if ((l0) == (0.0)) { l2 = l0; } else { @@ -611,12 +655,16 @@ varying vec3 V0;`, }, }, }, - GlslVS: `void F0(in float l0, in float l1, out float l2) { + GlslVS: `void F0(in float l0, in float l1, out float l2); + +void F0(in float l0, in float l1, out float l2) { for (int l3 = 0; l3 < 100; l3++) { l2 = l0; } }`, - GlslFS: `void F0(in float l0, in float l1, out float l2) { + GlslFS: `void F0(in float l0, in float l1, out float l2); + +void F0(in float l0, in float l1, out float l2) { for (int l3 = 0; l3 < 100; l3++) { l2 = l0; }