From 2707915376ccd86834d5e767044b0434939d9cfd Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 9 Aug 2020 20:12:56 +0900 Subject: [PATCH] shaderir/glsl, shaderir/metal: Bug fix: Wrong local variables with multiple 'for' statements --- internal/shaderir/glsl/glsl.go | 11 +--- internal/shaderir/ir_test.go | 95 ++++++++++++++++++++++++++++++++ internal/shaderir/metal/metal.go | 11 +--- 3 files changed, 101 insertions(+), 16 deletions(-) diff --git a/internal/shaderir/glsl/glsl.go b/internal/shaderir/glsl/glsl.go index fd6724720..6f6a28460 100644 --- a/internal/shaderir/glsl/glsl.go +++ b/internal/shaderir/glsl/glsl.go @@ -330,13 +330,6 @@ func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderi localVarIndex++ } - // For's variable is special and defiend in the for statement. - for _, s := range block.Stmts { - if s.Type == shaderir.For { - localVarIndex++ - } - } - var glslExpr func(e *shaderir.Expr) string glslExpr = func(e *shaderir.Expr) string { switch e.Type { @@ -447,7 +440,9 @@ func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderi end := constantToNumberLiteral(ct, s.ForEnd) t0, t1 := typeString(&t) lines = append(lines, fmt.Sprintf("%sfor (%s %s%s = %s; %s %s %s; %s) {", idt, t0, v, t1, init, v, op, end, delta)) - lines = append(lines, c.glslBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex)...) + // For's variable is special and defiend in the for statement. + // Add 1 to the number of the local variables. + lines = append(lines, c.glslBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex+1)...) lines = append(lines, fmt.Sprintf("%s}", idt)) case shaderir.Continue: lines = append(lines, idt+"continue;") diff --git a/internal/shaderir/ir_test.go b/internal/shaderir/ir_test.go index 84f2413cf..5fb9c56a0 100644 --- a/internal/shaderir/ir_test.go +++ b/internal/shaderir/ir_test.go @@ -757,6 +757,101 @@ void F0(float l0, float l1, thread float& l2) { int l4 = 0; l2 = l4; } +}`, + }, + { + Name: "For3", + Program: Program{ + Funcs: []Func{ + { + Index: 0, + InParams: []Type{ + {Main: Float}, + {Main: Float}, + }, + OutParams: []Type{ + {Main: Float}, + }, + Block: block( + nil, + forStmt( + 3, + 0, + 100, + LessThanOp, + 1, + block( + []Type{ + {Main: Int}, + }, + assignStmt( + localVariableExpr(2), + localVariableExpr(4), + ), + ), + ), + forStmt( + 3, + 0, + 100, + LessThanOp, + 1, + block( + []Type{ + {Main: Int}, + }, + assignStmt( + localVariableExpr(2), + localVariableExpr(4), + ), + ), + ), + ), + }, + }, + }, + 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++) { + int l4 = 0; + l2 = l4; + } + for (int l3 = 0; l3 < 100; l3++) { + int l4 = 0; + l2 = l4; + } +}`, + GlslFS: glslPrelude + ` +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++) { + int l4 = 0; + l2 = l4; + } + for (int l3 = 0; l3 < 100; l3++) { + int l4 = 0; + l2 = l4; + } +}`, + Metal: `#include + +using namespace metal; + +constexpr sampler texture_sampler{filter::nearest}; + +void F0(float l0, float l1, thread float& l2); + +void F0(float l0, float l1, thread float& l2) { + for (int l3 = 0; l3 < 100; l3++) { + int l4 = 0; + l2 = l4; + } + for (int l3 = 0; l3 < 100; l3++) { + int l4 = 0; + l2 = l4; + } }`, }, { diff --git a/internal/shaderir/metal/metal.go b/internal/shaderir/metal/metal.go index 9cec7d0de..f9712dcd8 100644 --- a/internal/shaderir/metal/metal.go +++ b/internal/shaderir/metal/metal.go @@ -327,13 +327,6 @@ func (c *compileContext) metalBlock(p *shaderir.Program, topBlock, block *shader localVarIndex++ } - // For's variable is special and defiend in the for statement. - for _, s := range block.Stmts { - if s.Type == shaderir.For { - localVarIndex++ - } - } - var metalExpr func(e *shaderir.Expr) string metalExpr = func(e *shaderir.Expr) string { switch e.Type { @@ -455,7 +448,9 @@ func (c *compileContext) metalBlock(p *shaderir.Program, topBlock, block *shader end := constantToNumberLiteral(ct, s.ForEnd) ts := typeString(&t, false, false) lines = append(lines, fmt.Sprintf("%sfor (%s %s = %s; %s %s %s; %s) {", idt, ts, v, init, v, op, end, delta)) - lines = append(lines, c.metalBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex)...) + // For's variable is special and defiend in the for statement. + // Add 1 to the number of the local variables. + lines = append(lines, c.metalBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex+1)...) lines = append(lines, fmt.Sprintf("%s}", idt)) case shaderir.Continue: lines = append(lines, idt+"continue;")