From 385ff8efdfe6bb3bf2e469b04b32d0c9bba24f81 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 13 Jul 2020 22:49:11 +0900 Subject: [PATCH] shader: Bug fix: Wrong local variable names at for-loop Fixes #1245 --- .../shader/testdata/issue1245.expected.fs | 8 ++ .../shader/testdata/issue1245.expected.vs | 10 +++ internal/shader/testdata/issue1245.go | 17 +++++ internal/shaderir/glsl.go | 75 ++++++++++--------- 4 files changed, 74 insertions(+), 36 deletions(-) create mode 100644 internal/shader/testdata/issue1245.expected.fs create mode 100644 internal/shader/testdata/issue1245.expected.vs create mode 100644 internal/shader/testdata/issue1245.go diff --git a/internal/shader/testdata/issue1245.expected.fs b/internal/shader/testdata/issue1245.expected.fs new file mode 100644 index 000000000..526590953 --- /dev/null +++ b/internal/shader/testdata/issue1245.expected.fs @@ -0,0 +1,8 @@ +void main(void) { + vec4 l0 = vec4(0); + for (int l1 = 0; l1 < 4; l1++) { + (l0).x = ((l0).x) + ((l1) * (1.000000000e-02)); + } + gl_FragColor = l0; + return; +} diff --git a/internal/shader/testdata/issue1245.expected.vs b/internal/shader/testdata/issue1245.expected.vs new file mode 100644 index 000000000..3231f8a88 --- /dev/null +++ b/internal/shader/testdata/issue1245.expected.vs @@ -0,0 +1,10 @@ +attribute vec2 A0; + +void main(void) { + vec4 l0 = vec4(0); + for (int l1 = 0; l1 < 4; l1++) { + (l0).x = ((l0).x) + ((l1) * (1.000000000e-02)); + } + gl_Position = l0; + return; +} diff --git a/internal/shader/testdata/issue1245.go b/internal/shader/testdata/issue1245.go new file mode 100644 index 000000000..25f8a3962 --- /dev/null +++ b/internal/shader/testdata/issue1245.go @@ -0,0 +1,17 @@ +package main + +func Vertex(position vec2) vec4 { + var v vec4 + for i := 0; i < 4.0; i++ { + v.x += i * 0.01 + } + return v +} + +func Fragment(position vec4) vec4 { + var v vec4 + for i := 0; i < 4.0; i++ { + v.x += i * 0.01 + } + return v +} diff --git a/internal/shaderir/glsl.go b/internal/shaderir/glsl.go index 03e2f01f2..38141eeb9 100644 --- a/internal/shaderir/glsl.go +++ b/internal/shaderir/glsl.go @@ -260,6 +260,38 @@ func constantToNumberLiteral(t ConstType, v constant.Value) string { return fmt.Sprintf("?(unexpected literal: %s)", v) } +func (p *Program) localVariableName(topBlock *Block, idx int) string { + switch topBlock { + case &p.VertexFunc.Block: + na := len(p.Attributes) + nv := len(p.Varyings) + switch { + case idx < na: + return fmt.Sprintf("A%d", idx) + case idx == na: + return "gl_Position" + case idx < na+nv+1: + return fmt.Sprintf("V%d", idx-na-1) + default: + return fmt.Sprintf("l%d", idx-(na+nv+1)) + } + case &p.FragmentFunc.Block: + nv := len(p.Varyings) + switch { + case idx == 0: + return "gl_FragCoord" + case idx < nv+1: + return fmt.Sprintf("V%d", idx-1) + case idx == nv+1: + return "gl_FragColor" + default: + return fmt.Sprintf("l%d", idx-(nv+2)) + } + default: + return fmt.Sprintf("l%d", idx) + } +} + func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int) []string { idt := strings.Repeat("\t", level+1) @@ -282,36 +314,7 @@ func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int case TextureVariable: return fmt.Sprintf("T%d", e.Index) case LocalVariable: - idx := e.Index - switch topBlock { - case &p.VertexFunc.Block: - na := len(p.Attributes) - nv := len(p.Varyings) - switch { - case idx < na: - return fmt.Sprintf("A%d", idx) - case idx == na: - return "gl_Position" - case idx < na+nv+1: - return fmt.Sprintf("V%d", idx-na-1) - default: - return fmt.Sprintf("l%d", idx-(na+nv+1)) - } - case &p.FragmentFunc.Block: - nv := len(p.Varyings) - switch { - case idx == 0: - return "gl_FragCoord" - case idx < nv+1: - return fmt.Sprintf("V%d", idx-1) - case idx == nv+1: - return "gl_FragColor" - default: - return fmt.Sprintf("l%d", idx-(nv+2)) - } - default: - return fmt.Sprintf("l%d", idx) - } + return p.localVariableName(topBlock, e.Index) case StructMember: return fmt.Sprintf("M%d", e.Index) case BuiltinFuncExpr: @@ -380,22 +383,22 @@ func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int ct = ConstTypeFloat } - v := s.ForVarIndex + v := p.localVariableName(topBlock, s.ForVarIndex) var delta string switch val, _ := constant.Float64Val(s.ForDelta); val { case 0: delta = fmt.Sprintf("?(unexpected delta: %v)", s.ForDelta) case 1: - delta = fmt.Sprintf("l%d++", v) + delta = fmt.Sprintf("%s++", v) case -1: - delta = fmt.Sprintf("l%d--", v) + delta = fmt.Sprintf("%s--", v) default: d := s.ForDelta if val > 0 { - delta = fmt.Sprintf("l%d += %s", v, constantToNumberLiteral(ct, d)) + delta = fmt.Sprintf("%s += %s", v, constantToNumberLiteral(ct, d)) } else { d = constant.UnaryOp(token.SUB, d, 0) - delta = fmt.Sprintf("l%d -= %s", v, constantToNumberLiteral(ct, d)) + delta = fmt.Sprintf("%s -= %s", v, constantToNumberLiteral(ct, d)) } } var op string @@ -409,7 +412,7 @@ func (p *Program) glslBlock(topBlock, block *Block, level int, localVarIndex int t := s.ForVarType.Main init := constantToNumberLiteral(ct, s.ForInit) end := constantToNumberLiteral(ct, s.ForEnd) - lines = append(lines, fmt.Sprintf("%sfor (%s l%d = %s; l%d %s %s; %s) {", idt, t.Glsl(), v, init, v, op, end, delta)) + lines = append(lines, fmt.Sprintf("%sfor (%s %s = %s; %s %s %s; %s) {", idt, t.Glsl(), v, init, v, op, end, delta)) lines = append(lines, p.glslBlock(topBlock, &s.Blocks[0], level+1, localVarIndex)...) lines = append(lines, fmt.Sprintf("%s}", idt)) case Continue: