mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 19:28:57 +01:00
shaderir/glsl, shaderir/metal: Refactoring
This commit is contained in:
parent
337f44c916
commit
e1ae9bdde0
@ -273,68 +273,35 @@ func constantToNumberLiteral(t shaderir.ConstType, v constant.Value) string {
|
|||||||
return fmt.Sprintf("?(unexpected literal: %s)", v)
|
return fmt.Sprintf("?(unexpected literal: %s)", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func descendantLocalVars(block, target *shaderir.Block) ([]shaderir.Type, bool) {
|
func localVariableName(p *shaderir.Program, topBlock, block *shaderir.Block, idx int) string {
|
||||||
if block == target {
|
|
||||||
return block.LocalVars, true
|
|
||||||
}
|
|
||||||
|
|
||||||
var ts []shaderir.Type
|
|
||||||
for _, s := range block.Stmts {
|
|
||||||
for _, b := range s.Blocks {
|
|
||||||
if ts2, found := descendantLocalVars(b, target); found {
|
|
||||||
n := b.LocalVarIndexOffset - block.LocalVarIndexOffset
|
|
||||||
ts = append(ts, block.LocalVars[:n]...)
|
|
||||||
ts = append(ts, ts2...)
|
|
||||||
return ts, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func localVariableType(p *shaderir.Program, topBlock, block *shaderir.Block, absidx int) shaderir.Type {
|
|
||||||
var ts []shaderir.Type
|
|
||||||
for _, f := range p.Funcs {
|
|
||||||
if f.Block == topBlock {
|
|
||||||
ts = append(f.InParams, f.OutParams...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ts2, _ := descendantLocalVars(topBlock, block)
|
|
||||||
ts = append(ts, ts2...)
|
|
||||||
return ts[absidx]
|
|
||||||
}
|
|
||||||
|
|
||||||
func localVariable(p *shaderir.Program, topBlock, block *shaderir.Block, idx int) (string, shaderir.Type) {
|
|
||||||
switch topBlock {
|
switch topBlock {
|
||||||
case p.VertexFunc.Block:
|
case p.VertexFunc.Block:
|
||||||
na := len(p.Attributes)
|
na := len(p.Attributes)
|
||||||
nv := len(p.Varyings)
|
nv := len(p.Varyings)
|
||||||
switch {
|
switch {
|
||||||
case idx < na:
|
case idx < na:
|
||||||
return fmt.Sprintf("A%d", idx), p.Attributes[idx]
|
return fmt.Sprintf("A%d", idx)
|
||||||
case idx == na:
|
case idx == na:
|
||||||
return "gl_Position", shaderir.Type{Main: shaderir.Vec4}
|
return "gl_Position"
|
||||||
case idx < na+nv+1:
|
case idx < na+nv+1:
|
||||||
return fmt.Sprintf("V%d", idx-na-1), p.Varyings[idx-na-1]
|
return fmt.Sprintf("V%d", idx-na-1)
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx-(na+nv+1)), localVariableType(p, topBlock, block, idx-(na+nv+1))
|
return fmt.Sprintf("l%d", idx-(na+nv+1))
|
||||||
}
|
}
|
||||||
case p.FragmentFunc.Block:
|
case p.FragmentFunc.Block:
|
||||||
nv := len(p.Varyings)
|
nv := len(p.Varyings)
|
||||||
switch {
|
switch {
|
||||||
case idx == 0:
|
case idx == 0:
|
||||||
return "gl_FragCoord", shaderir.Type{Main: shaderir.Vec4}
|
return "gl_FragCoord"
|
||||||
case idx < nv+1:
|
case idx < nv+1:
|
||||||
return fmt.Sprintf("V%d", idx-1), p.Varyings[idx-1]
|
return fmt.Sprintf("V%d", idx-1)
|
||||||
case idx == nv+1:
|
case idx == nv+1:
|
||||||
return "gl_FragColor", shaderir.Type{Main: shaderir.Vec4}
|
return "gl_FragColor"
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx-(nv+2)), localVariableType(p, topBlock, block, idx-(nv+2))
|
return fmt.Sprintf("l%d", idx-(nv+2))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx), localVariableType(p, topBlock, block, idx)
|
return fmt.Sprintf("l%d", idx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +314,8 @@ func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderi
|
|||||||
|
|
||||||
var lines []string
|
var lines []string
|
||||||
for i := range block.LocalVars {
|
for i := range block.LocalVars {
|
||||||
name, t := localVariable(p, topBlock, block, block.LocalVarIndexOffset+i)
|
name := localVariableName(p, topBlock, block, block.LocalVarIndexOffset+i)
|
||||||
|
t := p.LocalVariableType(topBlock, block, block.LocalVarIndexOffset+i)
|
||||||
switch t.Main {
|
switch t.Main {
|
||||||
case shaderir.Array:
|
case shaderir.Array:
|
||||||
lines = append(lines, fmt.Sprintf("%s%s;", idt, c.glslVarDecl(p, &t, name)))
|
lines = append(lines, fmt.Sprintf("%s%s;", idt, c.glslVarDecl(p, &t, name)))
|
||||||
@ -372,8 +340,7 @@ func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderi
|
|||||||
case shaderir.TextureVariable:
|
case shaderir.TextureVariable:
|
||||||
return fmt.Sprintf("T%d", e.Index)
|
return fmt.Sprintf("T%d", e.Index)
|
||||||
case shaderir.LocalVariable:
|
case shaderir.LocalVariable:
|
||||||
n, _ := localVariable(p, topBlock, block, e.Index)
|
return localVariableName(p, topBlock, block, e.Index)
|
||||||
return n
|
|
||||||
case shaderir.StructMember:
|
case shaderir.StructMember:
|
||||||
return fmt.Sprintf("M%d", e.Index)
|
return fmt.Sprintf("M%d", e.Index)
|
||||||
case shaderir.BuiltinFuncExpr:
|
case shaderir.BuiltinFuncExpr:
|
||||||
@ -426,7 +393,7 @@ func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderi
|
|||||||
lhs := s.Exprs[0]
|
lhs := s.Exprs[0]
|
||||||
rhs := s.Exprs[1]
|
rhs := s.Exprs[1]
|
||||||
if lhs.Type == shaderir.LocalVariable {
|
if lhs.Type == shaderir.LocalVariable {
|
||||||
if _, t := localVariable(p, topBlock, block, lhs.Index); t.Main == shaderir.Array {
|
if t := p.LocalVariableType(topBlock, block, lhs.Index); t.Main == shaderir.Array {
|
||||||
for i := 0; i < t.Length; i++ {
|
for i := 0; i < t.Length; i++ {
|
||||||
lines = append(lines, fmt.Sprintf("%[1]s%[2]s[%[3]d] = %[4]s[%[3]d];", idt, glslExpr(&lhs), i, glslExpr(&rhs)))
|
lines = append(lines, fmt.Sprintf("%[1]s%[2]s[%[3]d] = %[4]s[%[3]d];", idt, glslExpr(&lhs), i, glslExpr(&rhs)))
|
||||||
}
|
}
|
||||||
@ -451,7 +418,7 @@ func (c *compileContext) glslBlock(p *shaderir.Program, topBlock, block *shaderi
|
|||||||
ct = shaderir.ConstTypeFloat
|
ct = shaderir.ConstTypeFloat
|
||||||
}
|
}
|
||||||
|
|
||||||
v, _ := localVariable(p, topBlock, block, s.ForVarIndex)
|
v := localVariableName(p, topBlock, block, s.ForVarIndex)
|
||||||
var delta string
|
var delta string
|
||||||
switch val, _ := constant.Float64Val(s.ForDelta); val {
|
switch val, _ := constant.Float64Val(s.ForDelta); val {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -311,6 +311,20 @@ func localVariableName(p *shaderir.Program, topBlock *shaderir.Block, idx int) s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *compileContext) initVariable(p *shaderir.Program, topBlock, block *shaderir.Block, index int, decl bool, level int) []string {
|
||||||
|
idt := strings.Repeat("\t", level+1)
|
||||||
|
t := p.LocalVariableType(topBlock, block, index)
|
||||||
|
|
||||||
|
var lines []string
|
||||||
|
name := localVariableName(p, topBlock, index)
|
||||||
|
if decl {
|
||||||
|
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, c.metalVarDecl(p, &t, name, false, false), c.metalVarInit(p, &t)))
|
||||||
|
} else {
|
||||||
|
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, name, c.metalVarInit(p, &t)))
|
||||||
|
}
|
||||||
|
return lines
|
||||||
|
}
|
||||||
|
|
||||||
func (c *compileContext) metalBlock(p *shaderir.Program, topBlock, block *shaderir.Block, level int) []string {
|
func (c *compileContext) metalBlock(p *shaderir.Program, topBlock, block *shaderir.Block, level int) []string {
|
||||||
if block == nil {
|
if block == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -322,8 +336,7 @@ func (c *compileContext) metalBlock(p *shaderir.Program, topBlock, block *shader
|
|||||||
for i, t := range block.LocalVars {
|
for i, t := range block.LocalVars {
|
||||||
// The type is None e.g., when the variable is a for-loop counter.
|
// The type is None e.g., when the variable is a for-loop counter.
|
||||||
if t.Main != shaderir.None {
|
if t.Main != shaderir.None {
|
||||||
name := localVariableName(p, topBlock, block.LocalVarIndexOffset+i)
|
lines = append(lines, c.initVariable(p, topBlock, block, block.LocalVarIndexOffset+i, true, level)...)
|
||||||
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, c.metalVarDecl(p, &t, name, false, false), c.metalVarInit(p, &t)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,3 +120,69 @@ const (
|
|||||||
Array
|
Array
|
||||||
Struct
|
Struct
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func descendantLocalVars(block, target *Block) ([]Type, bool) {
|
||||||
|
if block == target {
|
||||||
|
return block.LocalVars, true
|
||||||
|
}
|
||||||
|
|
||||||
|
var ts []Type
|
||||||
|
for _, s := range block.Stmts {
|
||||||
|
for _, b := range s.Blocks {
|
||||||
|
if ts2, found := descendantLocalVars(b, target); found {
|
||||||
|
n := b.LocalVarIndexOffset - block.LocalVarIndexOffset
|
||||||
|
ts = append(ts, block.LocalVars[:n]...)
|
||||||
|
ts = append(ts, ts2...)
|
||||||
|
return ts, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func localVariableType(p *Program, topBlock, block *Block, absidx int) Type {
|
||||||
|
// TODO: Rename this function (truly-local variable?)
|
||||||
|
var ts []Type
|
||||||
|
for _, f := range p.Funcs {
|
||||||
|
if f.Block == topBlock {
|
||||||
|
ts = append(f.InParams, f.OutParams...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts2, _ := descendantLocalVars(topBlock, block)
|
||||||
|
ts = append(ts, ts2...)
|
||||||
|
return ts[absidx]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Program) LocalVariableType(topBlock, block *Block, idx int) Type {
|
||||||
|
switch topBlock {
|
||||||
|
case p.VertexFunc.Block:
|
||||||
|
na := len(p.Attributes)
|
||||||
|
nv := len(p.Varyings)
|
||||||
|
switch {
|
||||||
|
case idx < na:
|
||||||
|
return p.Attributes[idx]
|
||||||
|
case idx == na:
|
||||||
|
return Type{Main: Vec4}
|
||||||
|
case idx < na+nv+1:
|
||||||
|
return p.Varyings[idx-na-1]
|
||||||
|
default:
|
||||||
|
return localVariableType(p, topBlock, block, idx-(na+nv+1))
|
||||||
|
}
|
||||||
|
case p.FragmentFunc.Block:
|
||||||
|
nv := len(p.Varyings)
|
||||||
|
switch {
|
||||||
|
case idx == 0:
|
||||||
|
return Type{Main: Vec4}
|
||||||
|
case idx < nv+1:
|
||||||
|
return p.Varyings[idx-1]
|
||||||
|
case idx == nv+1:
|
||||||
|
return Type{Main: Vec4}
|
||||||
|
default:
|
||||||
|
return localVariableType(p, topBlock, block, idx-(nv+2))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return localVariableType(p, topBlock, block, idx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user