shader: Add tests for uniform variables

This commit is contained in:
Hajime Hoshi 2020-05-31 01:56:07 +09:00
parent e7323e04bf
commit 1ede103ce6
2 changed files with 27 additions and 146 deletions

View File

@ -46,16 +46,10 @@ type function struct {
type compileState struct { type compileState struct {
fs *token.FileSet fs *token.FileSet
result *shaderir.Program ir shaderir.Program
// position is the field name of VertexOut that represents a vertex position (gl_Position in GLSL). // uniforms is a collection of uniform variable names.
position variable uniforms []string
// varyings is a collection of varying variables.
varyings []variable
// uniforms is a collection of uniform variables.
uniforms []variable
global block global block
@ -90,7 +84,7 @@ func Compile(src []byte) (*shaderir.Program, error) {
// TODO: Resolve constants // TODO: Resolve constants
// TODO: Make a call graph and reorder the elements. // TODO: Make a call graph and reorder the elements.
return s.result, nil return &s.ir, nil
} }
func (s *compileState) addError(pos token.Pos, str string) { func (s *compileState) addError(pos token.Pos, str string) {
@ -135,7 +129,8 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl, global bool) {
cs.addError(s.Names[i].Pos(), fmt.Sprintf("global variables must be exposed: %s", v.name)) cs.addError(s.Names[i].Pos(), fmt.Sprintf("global variables must be exposed: %s", v.name))
} }
// TODO: Check RHS // TODO: Check RHS
cs.uniforms = append(cs.uniforms, v) cs.uniforms = append(cs.uniforms, v.name)
cs.ir.Uniforms = append(cs.ir.Uniforms, v.typ.ir)
} }
} }
case token.IMPORT: case token.IMPORT:
@ -150,24 +145,6 @@ func (cs *compileState) parseDecl(b *block, d ast.Decl, global bool) {
} }
} }
func (cs *compileState) parseStruct(t *ast.TypeSpec) {
s, ok := t.Type.(*ast.StructType)
if !ok {
cs.addError(t.Type.Pos(), fmt.Sprintf("%s must be a struct but not", t.Name))
return
}
for _, f := range s.Fields.List {
t := cs.parseType(f.Type)
for _, n := range f.Names {
cs.varyings = append(cs.varyings, variable{
name: n.Name,
typ: t,
})
}
}
}
func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) []variable { func (s *compileState) parseVariable(block *block, vs *ast.ValueSpec) []variable {
var t typ var t typ
if vs.Type != nil { if vs.Type != nil {
@ -324,10 +301,11 @@ func (s *compileState) detectType(b *block, expr ast.Expr) typ {
} }
} }
if e.Kind == token.INT { if e.Kind == token.INT {
s.addError(expr.Pos(), fmt.Sprintf("integer literal is not implemented yet: %s", e.Value)) return typ{
} else { ir: shaderir.Type{Main: shaderir.Int},
s.addError(expr.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value)) }
} }
s.addError(expr.Pos(), fmt.Sprintf("unexpected literal: %s", e.Value))
return typ{} return typ{}
case *ast.CompositeLit: case *ast.CompositeLit:
return s.parseType(e.Type) return s.parseType(e.Type)
@ -339,9 +317,9 @@ func (s *compileState) detectType(b *block, expr ast.Expr) typ {
} }
} }
if b == &s.global { if b == &s.global {
for _, v := range s.uniforms { for i, v := range s.uniforms {
if v.name == n { if v == n {
return v.typ return typ{ir: s.ir.Uniforms[i]}
} }
} }
} }

View File

@ -27,116 +27,19 @@ func TestDump(t *testing.T) {
VS string VS string
FS string FS string
}{ }{
/*{ {
Name: "general", Name: "uniforms",
Src: `package main Src: `package main
type VertexOut struct { var (
Position vec4 ` + "`kage:\"position\"`" + ` Foo vec2
TexCoord vec2 Boo vec4
Color vec4 )`,
} VS: `uniform vec2 U0;
uniform vec4 U1;`,
var Foo float FS: `uniform vec2 U0;
var ( uniform vec4 U1;`,
Bar vec2 },
Baz, Quux vec3
)
const C1 float = 1
const C2, C3 float = 2, 3
func F1(a, b vec2) vec4 {
var c0 vec2 = a
var c1, c2 = c0, 1.0
c1.x = c2.x
c3 := vec4{c0, c1}
return c2
}
`,
Dump: `var Bar uniform vec2
var Baz uniform vec3
var Foo uniform float
var Quux uniform vec3
type VertexOut struct {
Position vec4
TexCoord vec2
Color vec4
}
const C1 float = 1
const C2 float = 2
const C3 float = 3
func F1(a vec2, b vec2) (_ vec4) {
var c0 vec2 = a
var c1 vec2 = c0
var c2 vec2 = 1.0
var c3 vec4
c1.x = c2.x
c3 = vec4{c0, c1}
return c2
}
`,
},
{
Name: "AutoType",
Src: `package main
var V0 = 0.0
func F() {
v1 := V0
}
`,
Dump: `var V0 uniform float
func F() {
var v1 float
v1 = V0
}
`,
},
{
Name: "AutoType2",
Src: `package main
var V0 = 0.0
func F() {
v1 := V0
{
v2 := v1
}
}
`,
Dump: `var V0 uniform float
func F() {
var v1 float
v1 = V0
{
var v2 float
v2 = v1
}
}
`,
},*/
/*{
Name: "Struct",
Src: `package main
type S struct {
M0 float
M1, M2 vec2
M3, M4, M5 vec3
}
`,
Dump: `var V0 uniform float
type S struct {
M0 float
M1 vec2
M2 vec2
M3 vec3
M4 vec3
M5 vec3
}
`,
},*/
} }
for _, tc := range tests { for _, tc := range tests {
s, err := Compile([]byte(tc.Src)) s, err := Compile([]byte(tc.Src))
@ -145,10 +48,10 @@ func TestDump(t *testing.T) {
continue continue
} }
vs, fs := s.Glsl() vs, fs := s.Glsl()
if got, want := vs, tc.VS; got != want { if got, want := vs, tc.VS+"\n"; got != want {
t.Errorf("%s: got: %v, want: %v", tc.Name, got, want) t.Errorf("%s: got: %v, want: %v", tc.Name, got, want)
} }
if got, want := fs, tc.FS; got != want { if got, want := fs, tc.FS+"\n"; got != want {
t.Errorf("%s: got: %v, want: %v", tc.Name, got, want) t.Errorf("%s: got: %v, want: %v", tc.Name, got, want)
} }
} }