updated ebiten version from 2.7.9 to 2.9.9
This commit is contained in:
+79
-76
@@ -59,8 +59,6 @@ type compileState struct {
|
||||
|
||||
global block
|
||||
|
||||
varyingParsed bool
|
||||
|
||||
errs []string
|
||||
}
|
||||
|
||||
@@ -202,6 +200,7 @@ func Compile(src []byte, vertexEntry, fragmentEntry string, textureCount int) (*
|
||||
fragmentEntry: fragmentEntry,
|
||||
unit: unit,
|
||||
}
|
||||
s.ir.SourceHash = shaderir.CalcSourceHash(src)
|
||||
s.global.ir = &shaderir.Block{}
|
||||
s.parse(f)
|
||||
|
||||
@@ -291,18 +290,17 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
|
||||
// Parse function names so that any other function call the others.
|
||||
// The function data is provisional and will be updated soon.
|
||||
var vertexInParams []variable
|
||||
var vertexOutParams []variable
|
||||
var fragmentInParams []variable
|
||||
var fragmentOutParams []variable
|
||||
var fragmentReturnType shaderir.Type
|
||||
for _, d := range f.Decls {
|
||||
fd, ok := d.(*ast.FuncDecl)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
n := fd.Name.Name
|
||||
if n == cs.vertexEntry {
|
||||
continue
|
||||
}
|
||||
if n == cs.fragmentEntry {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, f := range cs.funcs {
|
||||
if f.name == n {
|
||||
@@ -312,6 +310,19 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
}
|
||||
|
||||
inParams, outParams, ret := cs.parseFuncParams(&cs.global, n, fd)
|
||||
|
||||
if n == cs.vertexEntry {
|
||||
vertexInParams = inParams
|
||||
vertexOutParams = outParams
|
||||
continue
|
||||
}
|
||||
if n == cs.fragmentEntry {
|
||||
fragmentInParams = inParams
|
||||
fragmentOutParams = outParams
|
||||
fragmentReturnType = ret
|
||||
continue
|
||||
}
|
||||
|
||||
var inT, outT []shaderir.Type
|
||||
for _, v := range inParams {
|
||||
inT = append(inT, v.typ)
|
||||
@@ -319,7 +330,6 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
for _, v := range outParams {
|
||||
outT = append(outT, v.typ)
|
||||
}
|
||||
|
||||
cs.funcs = append(cs.funcs, function{
|
||||
name: n,
|
||||
ir: shaderir.Func{
|
||||
@@ -332,6 +342,45 @@ func (cs *compileState) parse(f *ast.File) {
|
||||
})
|
||||
}
|
||||
|
||||
// Check varying variables.
|
||||
// In testings, there might not be vertex and fragment entry points.
|
||||
if len(vertexOutParams) > 0 && len(fragmentInParams) > 0 {
|
||||
for i, p := range vertexOutParams {
|
||||
if len(fragmentInParams) <= i {
|
||||
break
|
||||
}
|
||||
t := fragmentInParams[i].typ
|
||||
if !p.typ.Equal(&t) {
|
||||
name := fragmentInParams[i].name
|
||||
cs.addError(0, fmt.Sprintf("fragment argument %s must be %s but was %s", name, p.typ.String(), t.String()))
|
||||
}
|
||||
}
|
||||
|
||||
// The first out-param is treated as gl_Position in GLSL.
|
||||
if vertexOutParams[0].typ.Main != shaderir.Vec4 {
|
||||
cs.addError(0, "vertex entry point must have at least one returning vec4 value for a position")
|
||||
}
|
||||
if len(fragmentOutParams) != 0 || fragmentReturnType.Main != shaderir.Vec4 {
|
||||
cs.addError(0, "fragment entry point must have one returning vec4 value for a color")
|
||||
}
|
||||
}
|
||||
|
||||
if len(cs.errs) > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Set attribute and varying veraibles.
|
||||
for _, p := range vertexInParams {
|
||||
cs.ir.Attributes = append(cs.ir.Attributes, p.typ)
|
||||
}
|
||||
if len(vertexOutParams) > 0 {
|
||||
// TODO: Check that these params are not arrays or structs
|
||||
// The 0th argument is a special variable for position and is not included in varying variables.
|
||||
for _, p := range vertexOutParams[1:] {
|
||||
cs.ir.Varyings = append(cs.ir.Varyings, p.typ)
|
||||
}
|
||||
}
|
||||
|
||||
// Parse functions.
|
||||
for _, d := range f.Decls {
|
||||
if f, ok := d.(*ast.FuncDecl); ok {
|
||||
@@ -742,7 +791,13 @@ func (cs *compileState) parseFuncParams(block *block, fname string, d *ast.FuncD
|
||||
|
||||
// If there is only one returning value, it is treated as a returning value.
|
||||
// An array cannot be a returning value, especially for HLSL (#2923).
|
||||
if len(out) == 1 && out[0].name == "" && out[0].typ.Main != shaderir.Array {
|
||||
//
|
||||
// For the vertex entry, a parameter (variable) is used as a returning value.
|
||||
// For example, GLSL doesn't treat gl_Position as a returning value.
|
||||
// Thus, the returning value is not set for the vertex entry.
|
||||
// TODO: This can be resolved by having an indirect function like what the fragment entry already does.
|
||||
// See internal/shaderir/glsl.adjustProgram.
|
||||
if len(out) == 1 && out[0].name == "" && out[0].typ.Main != shaderir.Array && fname != cs.vertexEntry {
|
||||
ret = out[0].typ
|
||||
out = nil
|
||||
}
|
||||
@@ -765,77 +820,25 @@ func (cs *compileState) parseFunc(block *block, d *ast.FuncDecl) (function, bool
|
||||
}
|
||||
|
||||
inParams, outParams, returnType := cs.parseFuncParams(block, d.Name.Name, d)
|
||||
|
||||
checkVaryings := func(vs []variable) {
|
||||
if len(cs.ir.Varyings) != len(vs) {
|
||||
cs.addError(d.Pos(), "the number of vertex entry point's returning values and the number of fragment entry point's params must be the same")
|
||||
return
|
||||
if d.Name.Name == cs.fragmentEntry {
|
||||
if len(inParams) == 0 {
|
||||
inParams = append(inParams, variable{
|
||||
name: "_",
|
||||
typ: shaderir.Type{Main: shaderir.Vec4},
|
||||
})
|
||||
}
|
||||
for i, t := range cs.ir.Varyings {
|
||||
if t.Main != vs[i].typ.Main {
|
||||
cs.addError(d.Pos(), "vertex entry point's returning value types and fragment entry point's param types must match")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if block == &cs.global {
|
||||
switch d.Name.Name {
|
||||
case cs.vertexEntry:
|
||||
for _, v := range inParams {
|
||||
cs.ir.Attributes = append(cs.ir.Attributes, v.typ)
|
||||
}
|
||||
|
||||
// For the vertex entry, a parameter (variable) is used as a returning value.
|
||||
// For example, GLSL doesn't treat gl_Position as a returning value.
|
||||
// TODO: This can be resolved by having an indirect function like what the fragment entry already does.
|
||||
// See internal/shaderir/glsl.adjustProgram.
|
||||
if len(outParams) == 0 {
|
||||
outParams = append(outParams, variable{
|
||||
typ: shaderir.Type{Main: shaderir.Vec4},
|
||||
// The 0th inParams is a special variable for position and is not included in varying variables.
|
||||
if diff := len(cs.ir.Varyings) - (len(inParams) - 1); diff > 0 {
|
||||
// inParams is not enough when the vertex shader has more returning values than the fragment shader's arguments.
|
||||
orig := len(inParams) - 1
|
||||
for i := 0; i < diff; i++ {
|
||||
inParams = append(inParams, variable{
|
||||
name: "_",
|
||||
typ: cs.ir.Varyings[orig+i],
|
||||
})
|
||||
}
|
||||
|
||||
// The first out-param is treated as gl_Position in GLSL.
|
||||
if outParams[0].typ.Main != shaderir.Vec4 {
|
||||
cs.addError(d.Pos(), "vertex entry point must have at least one returning vec4 value for a position")
|
||||
return function{}, false
|
||||
}
|
||||
|
||||
if cs.varyingParsed {
|
||||
checkVaryings(outParams[1:])
|
||||
} else {
|
||||
for _, v := range outParams[1:] {
|
||||
// TODO: Check that these params are not arrays or structs
|
||||
cs.ir.Varyings = append(cs.ir.Varyings, v.typ)
|
||||
}
|
||||
}
|
||||
cs.varyingParsed = true
|
||||
case cs.fragmentEntry:
|
||||
if len(inParams) == 0 {
|
||||
cs.addError(d.Pos(), "fragment entry point must have at least one vec4 parameter for a position")
|
||||
return function{}, false
|
||||
}
|
||||
if inParams[0].typ.Main != shaderir.Vec4 {
|
||||
cs.addError(d.Pos(), "fragment entry point must have at least one vec4 parameter for a position")
|
||||
return function{}, false
|
||||
}
|
||||
|
||||
if len(outParams) != 0 || returnType.Main != shaderir.Vec4 {
|
||||
cs.addError(d.Pos(), "fragment entry point must have one returning vec4 value for a color")
|
||||
return function{}, false
|
||||
}
|
||||
|
||||
if cs.varyingParsed {
|
||||
checkVaryings(inParams[1:])
|
||||
} else {
|
||||
for _, v := range inParams[1:] {
|
||||
cs.ir.Varyings = append(cs.ir.Varyings, v.typ)
|
||||
}
|
||||
}
|
||||
cs.varyingParsed = true
|
||||
}
|
||||
}
|
||||
|
||||
b, ok := cs.parseBlock(block, d.Name.Name, d.Body.List, inParams, outParams, returnType, true)
|
||||
if !ok {
|
||||
return function{}, false
|
||||
|
||||
Reference in New Issue
Block a user