mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
shaderir: Use pointers for Block
This commit is contained in:
parent
07514a37c8
commit
ee9257e626
@ -92,7 +92,7 @@ type block struct {
|
||||
pos token.Pos
|
||||
outer *block
|
||||
|
||||
ir shaderir.Block
|
||||
ir *shaderir.Block
|
||||
}
|
||||
|
||||
func (b *block) findLocalVariable(name string) (int, shaderir.Type, bool) {
|
||||
@ -140,6 +140,7 @@ func Compile(fs *token.FileSet, f *ast.File, vertexEntry, fragmentEntry string,
|
||||
vertexEntry: vertexEntry,
|
||||
fragmentEntry: fragmentEntry,
|
||||
}
|
||||
s.global.ir = &shaderir.Block{}
|
||||
s.parse(f)
|
||||
|
||||
if len(s.errs) > 0 {
|
||||
@ -221,6 +222,7 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
Index: len(cs.funcs),
|
||||
InParams: inT,
|
||||
OutParams: outT,
|
||||
Block: &shaderir.Block{},
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -657,7 +659,9 @@ func (cs *compileState) parseBlock(outer *block, stmts []ast.Stmt, inParams, out
|
||||
block := &block{
|
||||
vars: vars,
|
||||
outer: outer,
|
||||
ir: &shaderir.Block{},
|
||||
}
|
||||
|
||||
defer func() {
|
||||
var offset int
|
||||
if outer == &cs.global {
|
||||
|
@ -103,7 +103,7 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
||||
}
|
||||
stmts = append(stmts, shaderir.Stmt{
|
||||
Type: shaderir.BlockStmt,
|
||||
Blocks: []shaderir.Block{
|
||||
Blocks: []*shaderir.Block{
|
||||
b.ir,
|
||||
},
|
||||
})
|
||||
@ -261,7 +261,7 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
||||
|
||||
stmts = append(stmts, shaderir.Stmt{
|
||||
Type: shaderir.For,
|
||||
Blocks: []shaderir.Block{bodyir},
|
||||
Blocks: []*shaderir.Block{bodyir},
|
||||
ForVarType: vartype,
|
||||
ForVarIndex: varidx,
|
||||
ForInit: init,
|
||||
@ -281,7 +281,7 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
||||
|
||||
stmts = append(stmts, shaderir.Stmt{
|
||||
Type: shaderir.BlockStmt,
|
||||
Blocks: []shaderir.Block{b.ir},
|
||||
Blocks: []*shaderir.Block{b.ir},
|
||||
})
|
||||
return stmts, true
|
||||
}
|
||||
@ -300,7 +300,7 @@ func (cs *compileState) parseStmt(block *block, stmt ast.Stmt, inParams []variab
|
||||
}
|
||||
stmts = append(stmts, ss...)
|
||||
|
||||
var bs []shaderir.Block
|
||||
var bs []*shaderir.Block
|
||||
b, ok := cs.parseBlock(block, stmt.Body.List, inParams, nil)
|
||||
if !ok {
|
||||
return nil, false
|
||||
|
@ -88,10 +88,10 @@ func Compile(p *shaderir.Program) (vertexShader, fragmentShader string) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(p.VertexFunc.Block.Stmts) > 0 {
|
||||
if p.VertexFunc.Block != nil && len(p.VertexFunc.Block.Stmts) > 0 {
|
||||
vslines = append(vslines, "")
|
||||
vslines = append(vslines, "void main(void) {")
|
||||
vslines = append(vslines, c.glslBlock(p, &p.VertexFunc.Block, &p.VertexFunc.Block, 0, 0)...)
|
||||
vslines = append(vslines, c.glslBlock(p, p.VertexFunc.Block, p.VertexFunc.Block, 0, 0)...)
|
||||
vslines = append(vslines, "}")
|
||||
}
|
||||
}
|
||||
@ -126,10 +126,10 @@ func Compile(p *shaderir.Program) (vertexShader, fragmentShader string) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(p.FragmentFunc.Block.Stmts) > 0 {
|
||||
if p.FragmentFunc.Block != nil && len(p.FragmentFunc.Block.Stmts) > 0 {
|
||||
fslines = append(fslines, "")
|
||||
fslines = append(fslines, "void main(void) {")
|
||||
fslines = append(fslines, c.glslBlock(p, &p.FragmentFunc.Block, &p.FragmentFunc.Block, 0, 0)...)
|
||||
fslines = append(fslines, c.glslBlock(p, p.FragmentFunc.Block, p.FragmentFunc.Block, 0, 0)...)
|
||||
fslines = append(fslines, "}")
|
||||
}
|
||||
}
|
||||
@ -239,7 +239,7 @@ func (c *compileContext) glslFunc(p *shaderir.Program, f *shaderir.Func, prototy
|
||||
return lines
|
||||
}
|
||||
lines = append(lines, fmt.Sprintf("%s {", sig))
|
||||
lines = append(lines, c.glslBlock(p, &f.Block, &f.Block, 0, idx)...)
|
||||
lines = append(lines, c.glslBlock(p, f.Block, f.Block, 0, idx)...)
|
||||
lines = append(lines, "}")
|
||||
|
||||
return lines
|
||||
@ -275,7 +275,7 @@ func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string {
|
||||
|
||||
func localVariableName(p *shaderir.Program, topBlock *shaderir.Block, idx int) string {
|
||||
switch topBlock {
|
||||
case &p.VertexFunc.Block:
|
||||
case p.VertexFunc.Block:
|
||||
na := len(p.Attributes)
|
||||
nv := len(p.Varyings)
|
||||
switch {
|
||||
@ -288,7 +288,7 @@ func localVariableName(p *shaderir.Program, topBlock *shaderir.Block, idx int) s
|
||||
default:
|
||||
return fmt.Sprintf("l%d", idx-(na+nv+1))
|
||||
}
|
||||
case &p.FragmentFunc.Block:
|
||||
case p.FragmentFunc.Block:
|
||||
nv := len(p.Varyings)
|
||||
switch {
|
||||
case idx == 0:
|
||||
@ -306,6 +306,10 @@ func localVariableName(p *shaderir.Program, topBlock *shaderir.Block, idx int) s
|
||||
}
|
||||
|
||||
func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderir.Block, level int, localVarIndex int) []string {
|
||||
if block == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
idt := strings.Repeat("\t", level+1)
|
||||
|
||||
var lines []string
|
||||
@ -383,17 +387,17 @@ func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderi
|
||||
lines = append(lines, fmt.Sprintf("%s%s;", idt, glslExpr(&s.Exprs[0])))
|
||||
case shaderir.BlockStmt:
|
||||
lines = append(lines, idt+"{")
|
||||
lines = append(lines, c.glslBlock(p, topBlock, &s.Blocks[0], level+1, localVarIndex)...)
|
||||
lines = append(lines, c.glslBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex)...)
|
||||
lines = append(lines, idt+"}")
|
||||
case shaderir.Assign:
|
||||
// TODO: Give an appropriate context
|
||||
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, glslExpr(&s.Exprs[0]), glslExpr(&s.Exprs[1])))
|
||||
case shaderir.If:
|
||||
lines = append(lines, fmt.Sprintf("%sif (%s) {", idt, glslExpr(&s.Exprs[0])))
|
||||
lines = append(lines, c.glslBlock(p, topBlock, &s.Blocks[0], level+1, localVarIndex)...)
|
||||
lines = append(lines, c.glslBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex)...)
|
||||
if len(s.Blocks) > 1 {
|
||||
lines = append(lines, fmt.Sprintf("%s} else {", idt))
|
||||
lines = append(lines, c.glslBlock(p, topBlock, &s.Blocks[1], level+1, localVarIndex)...)
|
||||
lines = append(lines, c.glslBlock(p, topBlock, s.Blocks[1], level+1, localVarIndex)...)
|
||||
}
|
||||
lines = append(lines, fmt.Sprintf("%s}", idt))
|
||||
case shaderir.For:
|
||||
@ -436,7 +440,7 @@ 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)...)
|
||||
lines = append(lines, c.glslBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex)...)
|
||||
lines = append(lines, fmt.Sprintf("%s}", idt))
|
||||
case shaderir.Continue:
|
||||
lines = append(lines, idt+"continue;")
|
||||
|
@ -20,10 +20,11 @@ import (
|
||||
|
||||
. "github.com/hajimehoshi/ebiten/internal/shaderir"
|
||||
"github.com/hajimehoshi/ebiten/internal/shaderir/glsl"
|
||||
"github.com/hajimehoshi/ebiten/internal/shaderir/metal"
|
||||
)
|
||||
|
||||
func block(localVars []Type, stmts ...Stmt) Block {
|
||||
return Block{
|
||||
func block(localVars []Type, stmts ...Stmt) *Block {
|
||||
return &Block{
|
||||
LocalVars: localVars,
|
||||
Stmts: stmts,
|
||||
}
|
||||
@ -36,10 +37,10 @@ func exprStmt(expr Expr) Stmt {
|
||||
}
|
||||
}
|
||||
|
||||
func blockStmt(block Block) Stmt {
|
||||
func blockStmt(block *Block) Stmt {
|
||||
return Stmt{
|
||||
Type: BlockStmt,
|
||||
Blocks: []Block{block},
|
||||
Blocks: []*Block{block},
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,18 +58,18 @@ func assignStmt(lhs Expr, rhs Expr) Stmt {
|
||||
}
|
||||
}
|
||||
|
||||
func ifStmt(cond Expr, block Block, elseBlock Block) Stmt {
|
||||
func ifStmt(cond Expr, block *Block, elseBlock *Block) Stmt {
|
||||
return Stmt{
|
||||
Type: If,
|
||||
Exprs: []Expr{cond},
|
||||
Blocks: []Block{block, elseBlock},
|
||||
Blocks: []*Block{block, elseBlock},
|
||||
}
|
||||
}
|
||||
|
||||
func forStmt(index, init, end int, op Op, delta int, block Block) Stmt {
|
||||
func forStmt(index, init, end int, op Op, delta int, block *Block) Stmt {
|
||||
return Stmt{
|
||||
Type: For,
|
||||
Blocks: []Block{block},
|
||||
Blocks: []*Block{block},
|
||||
ForVarType: Type{Main: Int},
|
||||
ForVarIndex: index,
|
||||
ForInit: constant.MakeInt64(int64(init)),
|
||||
@ -837,6 +838,7 @@ void main(void) {
|
||||
t.Errorf("%s fragment: got: %s, want: %s", tc.Name, got, want)
|
||||
}
|
||||
}
|
||||
metal.Compile(&tc.Program, "Vertex", "Fragment")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(p.VertexFunc.Block.Stmts) > 0 {
|
||||
if p.VertexFunc.Block != nil && len(p.VertexFunc.Block.Stmts) > 0 {
|
||||
lines = append(lines, "")
|
||||
lines = append(lines,
|
||||
fmt.Sprintf("vertex Varyings %s(", vertex),
|
||||
@ -111,14 +111,14 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
||||
}
|
||||
lines[len(lines)-1] += ") {"
|
||||
lines = append(lines, fmt.Sprintf("\tVaryings %s = {};", vertexOut))
|
||||
lines = append(lines, c.metalBlock(p, &p.VertexFunc.Block, &p.VertexFunc.Block, 0, 0)...)
|
||||
lines = append(lines, c.metalBlock(p, p.VertexFunc.Block, p.VertexFunc.Block, 0, 0)...)
|
||||
if last := fmt.Sprintf("\treturn %s;", vertexOut); lines[len(lines)-1] != last {
|
||||
lines = append(lines, last)
|
||||
}
|
||||
lines = append(lines, "}")
|
||||
}
|
||||
|
||||
if len(p.FragmentFunc.Block.Stmts) > 0 {
|
||||
if p.FragmentFunc.Block != nil && len(p.FragmentFunc.Block.Stmts) > 0 {
|
||||
lines = append(lines, "")
|
||||
lines = append(lines,
|
||||
fmt.Sprintf("fragment float4 %s(", fragment),
|
||||
@ -133,7 +133,7 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
||||
}
|
||||
lines[len(lines)-1] += ") {"
|
||||
lines = append(lines, fmt.Sprintf("\tfloat4 %s = float4(0);", fragmentOut))
|
||||
lines = append(lines, c.metalBlock(p, &p.FragmentFunc.Block, &p.FragmentFunc.Block, 0, 0)...)
|
||||
lines = append(lines, c.metalBlock(p, p.FragmentFunc.Block, p.FragmentFunc.Block, 0, 0)...)
|
||||
if last := fmt.Sprintf("\treturn %s;", fragmentOut); lines[len(lines)-1] != last {
|
||||
lines = append(lines, last)
|
||||
}
|
||||
@ -245,7 +245,7 @@ func (c *compileContext) metalFunc(p *shaderir.Program, f *shaderir.Func, protot
|
||||
return lines
|
||||
}
|
||||
lines = append(lines, fmt.Sprintf("%s {", sig))
|
||||
lines = append(lines, c.metalBlock(p, &f.Block, &f.Block, 0, idx)...)
|
||||
lines = append(lines, c.metalBlock(p, f.Block, f.Block, 0, idx)...)
|
||||
lines = append(lines, "}")
|
||||
|
||||
return lines
|
||||
@ -281,7 +281,7 @@ func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string {
|
||||
|
||||
func localVariableName(p *shaderir.Program, topBlock *shaderir.Block, idx int) string {
|
||||
switch topBlock {
|
||||
case &p.VertexFunc.Block:
|
||||
case p.VertexFunc.Block:
|
||||
na := len(p.Attributes)
|
||||
nv := len(p.Varyings)
|
||||
switch {
|
||||
@ -294,7 +294,7 @@ func localVariableName(p *shaderir.Program, topBlock *shaderir.Block, idx int) s
|
||||
default:
|
||||
return fmt.Sprintf("l%d", idx-(na+nv+1))
|
||||
}
|
||||
case &p.FragmentFunc.Block:
|
||||
case p.FragmentFunc.Block:
|
||||
nv := len(p.Varyings)
|
||||
switch {
|
||||
case idx == 0:
|
||||
@ -312,6 +312,10 @@ func localVariableName(p *shaderir.Program, topBlock *shaderir.Block, idx int) s
|
||||
}
|
||||
|
||||
func (c *compileContext) metalBlock(p *shaderir.Program, topBlock, block *shaderir.Block, level int, localVarIndex int) []string {
|
||||
if block == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
idt := strings.Repeat("\t", level+1)
|
||||
|
||||
var lines []string
|
||||
@ -391,17 +395,17 @@ func (c *compileContext) metalBlock(p *shaderir.Program, topBlock, block *shader
|
||||
lines = append(lines, fmt.Sprintf("%s%s;", idt, metalExpr(&s.Exprs[0])))
|
||||
case shaderir.BlockStmt:
|
||||
lines = append(lines, idt+"{")
|
||||
lines = append(lines, c.metalBlock(p, topBlock, &s.Blocks[0], level+1, localVarIndex)...)
|
||||
lines = append(lines, c.metalBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex)...)
|
||||
lines = append(lines, idt+"}")
|
||||
case shaderir.Assign:
|
||||
// TODO: Give an appropriate context
|
||||
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, metalExpr(&s.Exprs[0]), metalExpr(&s.Exprs[1])))
|
||||
case shaderir.If:
|
||||
lines = append(lines, fmt.Sprintf("%sif (%s) {", idt, metalExpr(&s.Exprs[0])))
|
||||
lines = append(lines, c.metalBlock(p, topBlock, &s.Blocks[0], level+1, localVarIndex)...)
|
||||
lines = append(lines, c.metalBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex)...)
|
||||
if len(s.Blocks) > 1 {
|
||||
lines = append(lines, fmt.Sprintf("%s} else {", idt))
|
||||
lines = append(lines, c.metalBlock(p, topBlock, &s.Blocks[1], level+1, localVarIndex)...)
|
||||
lines = append(lines, c.metalBlock(p, topBlock, s.Blocks[1], level+1, localVarIndex)...)
|
||||
}
|
||||
lines = append(lines, fmt.Sprintf("%s}", idt))
|
||||
case shaderir.For:
|
||||
@ -444,7 +448,7 @@ 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)...)
|
||||
lines = append(lines, c.metalBlock(p, topBlock, s.Blocks[0], level+1, localVarIndex)...)
|
||||
lines = append(lines, fmt.Sprintf("%s}", idt))
|
||||
case shaderir.Continue:
|
||||
lines = append(lines, idt+"continue;")
|
||||
@ -452,9 +456,9 @@ func (c *compileContext) metalBlock(p *shaderir.Program, topBlock, block *shader
|
||||
lines = append(lines, idt+"break;")
|
||||
case shaderir.Return:
|
||||
switch {
|
||||
case topBlock == &p.VertexFunc.Block:
|
||||
case topBlock == p.VertexFunc.Block:
|
||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, vertexOut))
|
||||
case topBlock == &p.FragmentFunc.Block:
|
||||
case topBlock == p.FragmentFunc.Block:
|
||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, fragmentOut))
|
||||
case len(s.Exprs) == 0:
|
||||
lines = append(lines, idt+"return;")
|
||||
|
@ -36,7 +36,7 @@ type Func struct {
|
||||
InParams []Type
|
||||
OutParams []Type
|
||||
Return Type
|
||||
Block Block
|
||||
Block *Block
|
||||
}
|
||||
|
||||
// VertexFunc takes pseudo params, and the number if len(attributes) + len(varyings) + 1.
|
||||
@ -45,7 +45,7 @@ type Func struct {
|
||||
// If len(attributes) + 1 <= index < len(attributes) + len(varyings) + 1, the params are out-params and represent
|
||||
// varying variables.
|
||||
type VertexFunc struct {
|
||||
Block Block
|
||||
Block *Block
|
||||
}
|
||||
|
||||
// FragmentFunc takes pseudo params, and the number is len(varyings) + 2.
|
||||
@ -53,7 +53,7 @@ type VertexFunc struct {
|
||||
// If index == len(varyings), the param represents (index-1)th verying variable.
|
||||
// If index == len(varyings)+1, the param is an out-param representing the color of the pixel (gl_FragColor in GLSL).
|
||||
type FragmentFunc struct {
|
||||
Block Block
|
||||
Block *Block
|
||||
}
|
||||
|
||||
type Block struct {
|
||||
@ -64,7 +64,7 @@ type Block struct {
|
||||
type Stmt struct {
|
||||
Type StmtType
|
||||
Exprs []Expr
|
||||
Blocks []Block
|
||||
Blocks []*Block
|
||||
ForVarType Type
|
||||
ForVarIndex int
|
||||
ForInit constant.Value
|
||||
|
@ -173,7 +173,7 @@ var (
|
||||
},
|
||||
}
|
||||
defaultVertexFunc = shaderir.VertexFunc{
|
||||
Block: shaderir.Block{
|
||||
Block: &shaderir.Block{
|
||||
Stmts: []shaderir.Stmt{
|
||||
{
|
||||
Type: shaderir.Assign,
|
||||
@ -279,7 +279,7 @@ func ShaderProgramFill(r, g, b, a byte) shaderir.Program {
|
||||
|
||||
p := defaultProgram()
|
||||
p.FragmentFunc = shaderir.FragmentFunc{
|
||||
Block: shaderir.Block{
|
||||
Block: &shaderir.Block{
|
||||
Stmts: []shaderir.Stmt{
|
||||
{
|
||||
Type: shaderir.Assign,
|
||||
@ -413,7 +413,7 @@ func ShaderProgramImages(imageNum int) shaderir.Program {
|
||||
})
|
||||
|
||||
p.FragmentFunc = shaderir.FragmentFunc{
|
||||
Block: shaderir.Block{
|
||||
Block: &shaderir.Block{
|
||||
LocalVars: []shaderir.Type{
|
||||
{Main: shaderir.Vec4},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user