shader: Implement swapping variables

Fixes #1248
This commit is contained in:
Hajime Hoshi 2020-08-16 18:40:43 +09:00
parent 05a1c2faa1
commit a9b94a183b
3 changed files with 68 additions and 5 deletions

View File

@ -42,7 +42,6 @@ func (cs *compileState) parseStmt(block *block, fname string, stmt ast.Stmt, inP
}
stmts = append(stmts, ss...)
case token.ASSIGN:
// TODO: What about the statement `a,b = b,a?`
if len(stmt.Lhs) != len(stmt.Rhs) && len(stmt.Rhs) != 1 {
cs.addError(stmt.Pos(), fmt.Sprintf("single-value context and multiple-value context cannot be mixed"))
return nil, false
@ -498,10 +497,39 @@ func (cs *compileState) assign(block *block, pos token.Pos, lhs, rhs []ast.Expr,
}
}
stmts = append(stmts, shaderir.Stmt{
Type: shaderir.Assign,
Exprs: []shaderir.Expr{l[0], r[0]},
})
if len(lhs) == 1 {
stmts = append(stmts, shaderir.Stmt{
Type: shaderir.Assign,
Exprs: []shaderir.Expr{l[0], r[0]},
})
} else {
// For variable swapping, use temporary variables.
block.vars = append(block.vars, variable{
typ: origts[0],
})
idx := len(block.vars) - 1
stmts = append(stmts,
shaderir.Stmt{
Type: shaderir.Assign,
Exprs: []shaderir.Expr{
{
Type: shaderir.LocalVariable,
Index: idx,
},
r[0],
},
},
shaderir.Stmt{
Type: shaderir.Assign,
Exprs: []shaderir.Expr{
l[0],
{
Type: shaderir.LocalVariable,
Index: idx,
},
},
})
}
} else {
if i == 0 {
var ss []shaderir.Stmt

View File

@ -0,0 +1,26 @@
void F0(out vec2 l0);
void F0(out vec2 l0) {
vec2 l1 = vec2(0);
vec2 l2 = vec2(0);
vec2 l3 = vec2(0);
vec2 l4 = vec2(0);
vec2 l5 = vec2(0);
vec2 l6 = vec2(0);
vec2 l7 = vec2(0);
vec2 l8 = vec2(0);
vec2 l9 = vec2(0);
vec2 l10 = vec2(0);
l3 = l2;
l1 = l3;
l4 = l1;
l2 = l4;
l8 = l6;
l5 = l8;
l9 = l7;
l6 = l9;
l10 = l5;
l7 = l10;
l0 = l1;
return;
}

9
internal/shader/testdata/issue1248.go vendored Normal file
View File

@ -0,0 +1,9 @@
package main
func Foo() vec2 {
var a, b vec2
a, b = b, a
var c, d, e vec2
c, d, e = d, e, c
return a
}