shader: Implement multiple out params

This commit is contained in:
Hajime Hoshi 2020-05-31 19:20:53 +09:00
parent afd114e606
commit 5de0493294
2 changed files with 47 additions and 11 deletions

View File

@ -217,13 +217,12 @@ func (cs *compileState) parseFunc(d *ast.FuncDecl, block *block) function {
return function{} return function{}
} }
var vars []variable
var inT []shaderir.Type var inT []shaderir.Type
var inParams []variable
for _, f := range d.Type.Params.List { for _, f := range d.Type.Params.List {
t := cs.parseType(f.Type) t := cs.parseType(f.Type)
for _, n := range f.Names { for _, n := range f.Names {
vars = append(vars, variable{ inParams = append(inParams, variable{
name: n.Name, name: n.Name,
typ: t, typ: t,
}) })
@ -232,18 +231,19 @@ func (cs *compileState) parseFunc(d *ast.FuncDecl, block *block) function {
} }
var outT []shaderir.Type var outT []shaderir.Type
var outParams []variable
if d.Type.Results != nil { if d.Type.Results != nil {
for _, f := range d.Type.Results.List { for _, f := range d.Type.Results.List {
t := cs.parseType(f.Type) t := cs.parseType(f.Type)
if len(f.Names) == 0 { if len(f.Names) == 0 {
vars = append(vars, variable{ outParams = append(outParams, variable{
name: "", name: "",
typ: t, typ: t,
}) })
outT = append(outT, t.ir) outT = append(outT, t.ir)
} else { } else {
for _, n := range f.Names { for _, n := range f.Names {
vars = append(vars, variable{ outParams = append(outParams, variable{
name: n.Name, name: n.Name,
typ: t, typ: t,
}) })
@ -253,7 +253,7 @@ func (cs *compileState) parseFunc(d *ast.FuncDecl, block *block) function {
} }
} }
b := cs.parseBlock(block, d.Body, vars) b := cs.parseBlock(block, d.Body, inParams, outParams)
return function{ return function{
name: d.Name.Name, name: d.Name.Name,
@ -267,9 +267,12 @@ func (cs *compileState) parseFunc(d *ast.FuncDecl, block *block) function {
} }
} }
func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, locals []variable) *block { func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, inParams, outParams []variable) *block {
vars := make([]variable, 0, len(inParams)+len(outParams))
vars = append(vars, inParams...)
vars = append(vars, outParams...)
block := &block{ block := &block{
vars: locals, vars: vars,
outer: outer, outer: outer,
} }
@ -310,14 +313,14 @@ func (cs *compileState) parseBlock(outer *block, b *ast.BlockStmt, locals []vari
case *ast.DeclStmt: case *ast.DeclStmt:
cs.parseDecl(block, l.Decl, false) cs.parseDecl(block, l.Decl, false)
case *ast.ReturnStmt: case *ast.ReturnStmt:
for _, r := range l.Results { for i, r := range l.Results {
e := cs.parseExpr(block, r) e := cs.parseExpr(block, r)
block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{ block.ir.Stmts = append(block.ir.Stmts, shaderir.Stmt{
Type: shaderir.Assign, Type: shaderir.Assign,
Exprs: []shaderir.Expr{ Exprs: []shaderir.Expr{
{ {
Type: shaderir.LocalVariable, Type: shaderir.LocalVariable,
Index: 1, // TODO: Fix this Index: len(inParams) + i,
}, },
e, e,
}, },
@ -442,6 +445,17 @@ func (cs *compileState) parseExpr(block *block, expr ast.Expr) shaderir.Expr {
} }
} }
cs.addError(e.Pos(), fmt.Sprintf("unexpected identifier: %s", e.Name)) cs.addError(e.Pos(), fmt.Sprintf("unexpected identifier: %s", e.Name))
case *ast.SelectorExpr:
return shaderir.Expr{
Type: shaderir.FieldSelector,
Exprs: []shaderir.Expr{
cs.parseExpr(block, e.X),
{
Type: shaderir.SwizzlingExpr,
Swizzling: e.Sel.Name,
},
},
}
default: default:
cs.addError(e.Pos(), fmt.Sprintf("expression not implemented: %#v", e)) cs.addError(e.Pos(), fmt.Sprintf("expression not implemented: %#v", e))
} }

View File

@ -56,7 +56,7 @@ func Foo(foo vec2) vec4 {
Src: `package main Src: `package main
func Foo(foo vec2) vec4 { func Foo(foo vec2) vec4 {
return vec4(foo, 0, 1); return vec4(foo, 0, 1)
}`, }`,
VS: `void F0(in vec2 l0, out vec4 l1) { VS: `void F0(in vec2 l0, out vec4 l1) {
l1 = vec4(l0, 0, 1); l1 = vec4(l0, 0, 1);
@ -65,6 +65,28 @@ func Foo(foo vec2) vec4 {
FS: `void F0(in vec2 l0, out vec4 l1) { FS: `void F0(in vec2 l0, out vec4 l1) {
l1 = vec4(l0, 0, 1); l1 = vec4(l0, 0, 1);
return; return;
}`,
},
{
Name: "func multiple out params",
Src: `package main
func Foo(foo vec4) (float, float, float, float) {
return foo.x, foo.y, foo.z, foo.w
}`,
VS: `void F0(in vec4 l0, out float l1, out float l2, out float l3, out float l4) {
l1 = (l0).x;
l2 = (l0).y;
l3 = (l0).z;
l4 = (l0).w;
return;
}`,
FS: `void F0(in vec4 l0, out float l1, out float l2, out float l3, out float l4) {
l1 = (l0).x;
l2 = (l0).y;
l3 = (l0).z;
l4 = (l0).w;
return;
}`, }`,
}, },
} }