mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 18:58:54 +01:00
internal/shader: use a return statement in a fragment shader entrypoint
Updates #2247
This commit is contained in:
parent
bf4648eb35
commit
b211b79a5c
@ -704,6 +704,8 @@ func (cs *compileState) parseFunc(block *block, d *ast.FuncDecl) (function, bool
|
|||||||
|
|
||||||
// For the vertex entry, a parameter (variable) is used as a returning value.
|
// 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.
|
// 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 {
|
if len(outParams) == 0 {
|
||||||
outParams = append(outParams, variable{
|
outParams = append(outParams, variable{
|
||||||
typ: shaderir.Type{Main: shaderir.Vec4},
|
typ: shaderir.Type{Main: shaderir.Vec4},
|
||||||
@ -735,14 +737,7 @@ func (cs *compileState) parseFunc(block *block, d *ast.FuncDecl) (function, bool
|
|||||||
return function{}, false
|
return function{}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// For the fragment entry, a parameter (variable) is used as a returning value.
|
if len(outParams) != 0 || returnType.Main != shaderir.Vec4 {
|
||||||
// For example, GLSL doesn't treat gl_FragColor as a returning value.
|
|
||||||
if len(outParams) == 0 {
|
|
||||||
outParams = append(outParams, variable{
|
|
||||||
typ: shaderir.Type{Main: shaderir.Vec4},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if len(outParams) != 1 || outParams[0].typ.Main != shaderir.Vec4 {
|
|
||||||
cs.addError(d.Pos(), fmt.Sprintf("fragment entry point must have one returning vec4 value for a color"))
|
cs.addError(d.Pos(), fmt.Sprintf("fragment entry point must have one returning vec4 value for a color"))
|
||||||
return function{}, false
|
return function{}, false
|
||||||
}
|
}
|
||||||
|
37
internal/shader/testdata/for5.expected.fs
vendored
37
internal/shader/testdata/for5.expected.fs
vendored
@ -3,34 +3,31 @@ uniform float U1;
|
|||||||
uniform float U2;
|
uniform float U2;
|
||||||
|
|
||||||
int F0(in int l0);
|
int F0(in int l0);
|
||||||
void F1(in vec4 l0, out vec4 l1);
|
vec4 F1(in vec4 l0);
|
||||||
|
|
||||||
int F0(in int l0) {
|
int F0(in int l0) {
|
||||||
return l0;
|
return l0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void F1(in vec4 l0, out vec4 l1) {
|
vec4 F1(in vec4 l0) {
|
||||||
int l2 = 0;
|
int l1 = 0;
|
||||||
int l4 = 0;
|
int l3 = 0;
|
||||||
l2 = 0;
|
l1 = 0;
|
||||||
for (int l3 = 0; l3 < 10; l3++) {
|
for (int l2 = 0; l2 < 10; l2++) {
|
||||||
int l4 = 0;
|
int l3 = 0;
|
||||||
l4 = F0(l3);
|
l3 = F0(l2);
|
||||||
l2 = (l2) + (l4);
|
l1 = (l1) + (l3);
|
||||||
for (int l5 = 0; l5 < 10; l5++) {
|
for (int l4 = 0; l4 < 10; l4++) {
|
||||||
int l6 = 0;
|
int l5 = 0;
|
||||||
l6 = F0(l5);
|
l5 = F0(l4);
|
||||||
l2 = (l2) + (l6);
|
l1 = (l1) + (l5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l4 = 0;
|
l3 = 0;
|
||||||
l2 = (l2) + (l4);
|
l1 = (l1) + (l3);
|
||||||
l1 = vec4(l2);
|
return vec4(l1);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 l0 = vec4(0);
|
gl_FragColor = F1(gl_FragCoord);
|
||||||
F1(gl_FragCoord, l0);
|
|
||||||
gl_FragColor = l0;
|
|
||||||
}
|
}
|
||||||
|
14
internal/shader/testdata/issue1238.expected.fs
vendored
14
internal/shader/testdata/issue1238.expected.fs
vendored
@ -1,16 +1,12 @@
|
|||||||
void F0(in vec4 l0, out vec4 l1);
|
vec4 F0(in vec4 l0);
|
||||||
|
|
||||||
void F0(in vec4 l0, out vec4 l1) {
|
vec4 F0(in vec4 l0) {
|
||||||
if (true) {
|
if (true) {
|
||||||
l1 = l0;
|
return l0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
l1 = l0;
|
return l0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 l0 = vec4(0);
|
gl_FragColor = F0(gl_FragCoord);
|
||||||
F0(gl_FragCoord, l0);
|
|
||||||
gl_FragColor = l0;
|
|
||||||
}
|
}
|
||||||
|
17
internal/shader/testdata/issue1245.expected.fs
vendored
17
internal/shader/testdata/issue1245.expected.fs
vendored
@ -1,16 +1,13 @@
|
|||||||
void F0(in vec4 l0, out vec4 l1);
|
vec4 F0(in vec4 l0);
|
||||||
|
|
||||||
void F0(in vec4 l0, out vec4 l1) {
|
vec4 F0(in vec4 l0) {
|
||||||
vec4 l2 = vec4(0);
|
vec4 l1 = vec4(0);
|
||||||
for (float l3 = 0.0; l3 < 4.0; l3++) {
|
for (float l2 = 0.0; l2 < 4.0; l2++) {
|
||||||
(l2).x = ((l2).x) + ((l3) * (1.0000000000e-02));
|
(l1).x = ((l1).x) + ((l2) * (1.0000000000e-02));
|
||||||
}
|
}
|
||||||
l1 = l2;
|
return l1;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 l0 = vec4(0);
|
gl_FragColor = F0(gl_FragCoord);
|
||||||
F0(gl_FragCoord, l0);
|
|
||||||
gl_FragColor = l0;
|
|
||||||
}
|
}
|
||||||
|
11
internal/shader/testdata/issue1701.expected.fs
vendored
11
internal/shader/testdata/issue1701.expected.fs
vendored
@ -1,6 +1,6 @@
|
|||||||
void F2(void);
|
void F2(void);
|
||||||
void F3(void);
|
void F3(void);
|
||||||
void F5(in vec4 l0, out vec4 l1);
|
vec4 F5(in vec4 l0);
|
||||||
|
|
||||||
void F2(void) {
|
void F2(void) {
|
||||||
}
|
}
|
||||||
@ -9,14 +9,11 @@ void F3(void) {
|
|||||||
F2();
|
F2();
|
||||||
}
|
}
|
||||||
|
|
||||||
void F5(in vec4 l0, out vec4 l1) {
|
vec4 F5(in vec4 l0) {
|
||||||
F3();
|
F3();
|
||||||
l1 = vec4(0.0);
|
return vec4(0.0);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 l0 = vec4(0);
|
gl_FragColor = F5(gl_FragCoord);
|
||||||
F5(gl_FragCoord, l0);
|
|
||||||
gl_FragColor = l0;
|
|
||||||
}
|
}
|
||||||
|
@ -2,15 +2,12 @@ uniform vec2 U0;
|
|||||||
varying vec2 V0;
|
varying vec2 V0;
|
||||||
varying vec4 V1;
|
varying vec4 V1;
|
||||||
|
|
||||||
void F0(in vec4 l0, in vec2 l1, in vec4 l2, out vec4 l3);
|
vec4 F0(in vec4 l0, in vec2 l1, in vec4 l2);
|
||||||
|
|
||||||
void F0(in vec4 l0, in vec2 l1, in vec4 l2, out vec4 l3) {
|
vec4 F0(in vec4 l0, in vec2 l1, in vec4 l2) {
|
||||||
l3 = vec4((l0).x, (l1).y, (l2).z, 1.0);
|
return vec4((l0).x, (l1).y, (l2).z, 1.0);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 l0 = vec4(0);
|
gl_FragColor = F0(gl_FragCoord, V0, V1);
|
||||||
F0(gl_FragCoord, V0, V1, l0);
|
|
||||||
gl_FragColor = l0;
|
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,5 @@ vertex Varyings Vertex(
|
|||||||
fragment float4 Fragment(
|
fragment float4 Fragment(
|
||||||
Varyings varyings [[stage_in]],
|
Varyings varyings [[stage_in]],
|
||||||
constant float2& U0 [[buffer(1)]]) {
|
constant float2& U0 [[buffer(1)]]) {
|
||||||
float4 out = float4(0);
|
return float4((varyings.Position).x, (varyings.M0).y, (varyings.M1).z, 1.0);
|
||||||
out = float4((varyings.Position).x, (varyings.M0).y, (varyings.M1).z, 1.0);
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
@ -430,13 +430,8 @@ func (c *compileContext) localVariableName(p *shaderir.Program, topBlock *shader
|
|||||||
return "gl_FragCoord"
|
return "gl_FragCoord"
|
||||||
case idx < nv+1:
|
case idx < nv+1:
|
||||||
return fmt.Sprintf("V%d", idx-1)
|
return fmt.Sprintf("V%d", idx-1)
|
||||||
case idx == nv+1:
|
|
||||||
if c.version == GLSLVersionES300 {
|
|
||||||
return "fragColor"
|
|
||||||
}
|
|
||||||
return "gl_FragColor"
|
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx-(nv+2))
|
return fmt.Sprintf("l%d", idx-(nv+1))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx)
|
return fmt.Sprintf("l%d", idx)
|
||||||
@ -613,13 +608,22 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
|
|||||||
case shaderir.Break:
|
case shaderir.Break:
|
||||||
lines = append(lines, idt+"break;")
|
lines = append(lines, idt+"break;")
|
||||||
case shaderir.Return:
|
case shaderir.Return:
|
||||||
if len(s.Exprs) == 0 {
|
switch {
|
||||||
|
case topBlock == p.FragmentFunc.Block:
|
||||||
|
token := "gl_FragColor"
|
||||||
|
if c.version == GLSLVersionES300 {
|
||||||
|
token = "fragColor"
|
||||||
|
}
|
||||||
|
lines = append(lines, fmt.Sprintf("%s%s = %s;", idt, token, expr(&s.Exprs[0])))
|
||||||
|
// The 'return' statement is not required so far, as the fragment entrypoint has only one sentence so far. See adjustProgram implementation.
|
||||||
|
case len(s.Exprs) == 0:
|
||||||
lines = append(lines, idt+"return;")
|
lines = append(lines, idt+"return;")
|
||||||
} else {
|
default:
|
||||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
|
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
|
||||||
}
|
}
|
||||||
case shaderir.Discard:
|
case shaderir.Discard:
|
||||||
lines = append(lines, idt+"discard;")
|
// 'discard' is invoked only in the fragment shader entry point.
|
||||||
|
lines = append(lines, idt+"discard;", idt+"return vec4(0.0);")
|
||||||
default:
|
default:
|
||||||
lines = append(lines, fmt.Sprintf("%s?(unexpected stmt: %d)", idt, s.Type))
|
lines = append(lines, fmt.Sprintf("%s?(unexpected stmt: %d)", idt, s.Type))
|
||||||
}
|
}
|
||||||
@ -661,17 +665,14 @@ func adjustProgram(p *shaderir.Program) *shaderir.Program {
|
|||||||
}
|
}
|
||||||
copy(inParams[1:], newP.Varyings)
|
copy(inParams[1:], newP.Varyings)
|
||||||
|
|
||||||
outParams := make([]shaderir.Type, 1)
|
|
||||||
outParams[0] = shaderir.Type{
|
|
||||||
Main: shaderir.Vec4, // gl_FragColor
|
|
||||||
}
|
|
||||||
|
|
||||||
newP.Funcs = append(newP.Funcs, shaderir.Func{
|
newP.Funcs = append(newP.Funcs, shaderir.Func{
|
||||||
Index: funcIdx,
|
Index: funcIdx,
|
||||||
InParams: inParams,
|
InParams: inParams,
|
||||||
OutParams: outParams,
|
OutParams: nil,
|
||||||
Return: shaderir.Type{},
|
Return: shaderir.Type{
|
||||||
Block: newP.FragmentFunc.Block,
|
Main: shaderir.Vec4,
|
||||||
|
},
|
||||||
|
Block: newP.FragmentFunc.Block,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Create an AST to call the new function.
|
// Create an AST to call the new function.
|
||||||
@ -687,45 +688,24 @@ func adjustProgram(p *shaderir.Program) *shaderir.Program {
|
|||||||
Index: i,
|
Index: i,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
call = append(call, shaderir.Expr{
|
|
||||||
Type: shaderir.LocalVariable,
|
|
||||||
Index: 1 + len(newP.Varyings) + 1, // l0 as an out parameter.
|
|
||||||
})
|
|
||||||
|
|
||||||
// Replace the entry point with just calling the new function.
|
// Replace the entry point with just calling the new function.
|
||||||
stmts := []shaderir.Stmt{
|
stmts := []shaderir.Stmt{
|
||||||
{
|
{
|
||||||
Type: shaderir.ExprStmt,
|
// Return: This will be replaced with assignment to gl_FragColor.
|
||||||
|
Type: shaderir.Return,
|
||||||
Exprs: []shaderir.Expr{
|
Exprs: []shaderir.Expr{
|
||||||
|
// The function call
|
||||||
{
|
{
|
||||||
Type: shaderir.Call,
|
Type: shaderir.Call,
|
||||||
Exprs: call,
|
Exprs: call,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Type: shaderir.Assign,
|
|
||||||
Exprs: []shaderir.Expr{
|
|
||||||
// gl_FragColor
|
|
||||||
{
|
|
||||||
Type: shaderir.LocalVariable,
|
|
||||||
Index: 1 + len(newP.Varyings),
|
|
||||||
},
|
|
||||||
// l0
|
|
||||||
{
|
|
||||||
Type: shaderir.LocalVariable,
|
|
||||||
Index: 1 + len(newP.Varyings) + 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
newP.FragmentFunc = shaderir.FragmentFunc{
|
newP.FragmentFunc = shaderir.FragmentFunc{
|
||||||
Block: &shaderir.Block{
|
Block: &shaderir.Block{
|
||||||
LocalVars: []shaderir.Type{
|
LocalVars: nil,
|
||||||
{
|
|
||||||
Main: shaderir.Vec4,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
LocalVarIndexOffset: 1 + len(newP.Varyings) + 1,
|
LocalVarIndexOffset: 1 + len(newP.Varyings) + 1,
|
||||||
Stmts: stmts,
|
Stmts: stmts,
|
||||||
},
|
},
|
||||||
|
@ -26,7 +26,6 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
vsOut = "varyings"
|
vsOut = "varyings"
|
||||||
psOut = "psOut"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type compileContext struct {
|
type compileContext struct {
|
||||||
@ -147,11 +146,7 @@ func Compile(p *shaderir.Program) (string, []int) {
|
|||||||
if p.FragmentFunc.Block != nil && len(p.FragmentFunc.Block.Stmts) > 0 {
|
if p.FragmentFunc.Block != nil && len(p.FragmentFunc.Block.Stmts) > 0 {
|
||||||
lines = append(lines, "")
|
lines = append(lines, "")
|
||||||
lines = append(lines, fmt.Sprintf("float4 PSMain(Varyings %s) : SV_TARGET {", vsOut))
|
lines = append(lines, fmt.Sprintf("float4 PSMain(Varyings %s) : SV_TARGET {", vsOut))
|
||||||
lines = append(lines, fmt.Sprintf("\tfloat4 %s = 0.0;", psOut))
|
|
||||||
lines = append(lines, c.block(p, p.FragmentFunc.Block, p.FragmentFunc.Block, 0)...)
|
lines = append(lines, c.block(p, p.FragmentFunc.Block, p.FragmentFunc.Block, 0)...)
|
||||||
if last := fmt.Sprintf("\treturn %s;", psOut); lines[len(lines)-1] != last {
|
|
||||||
lines = append(lines, last)
|
|
||||||
}
|
|
||||||
lines = append(lines, "}")
|
lines = append(lines, "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,10 +306,8 @@ func (c *compileContext) localVariableName(p *shaderir.Program, topBlock *shader
|
|||||||
return fmt.Sprintf("%s.Position", vsOut)
|
return fmt.Sprintf("%s.Position", vsOut)
|
||||||
case idx < nv+1:
|
case idx < nv+1:
|
||||||
return fmt.Sprintf("%s.M%d", vsOut, idx-1)
|
return fmt.Sprintf("%s.M%d", vsOut, idx-1)
|
||||||
case idx == nv+1:
|
|
||||||
return psOut
|
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx-(nv+2))
|
return fmt.Sprintf("l%d", idx-(nv+1))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx)
|
return fmt.Sprintf("l%d", idx)
|
||||||
@ -525,15 +518,14 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
|
|||||||
switch {
|
switch {
|
||||||
case topBlock == p.VertexFunc.Block:
|
case topBlock == p.VertexFunc.Block:
|
||||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, vsOut))
|
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, vsOut))
|
||||||
case topBlock == p.FragmentFunc.Block:
|
|
||||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, psOut))
|
|
||||||
case len(s.Exprs) == 0:
|
case len(s.Exprs) == 0:
|
||||||
lines = append(lines, idt+"return;")
|
lines = append(lines, idt+"return;")
|
||||||
default:
|
default:
|
||||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
|
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
|
||||||
}
|
}
|
||||||
case shaderir.Discard:
|
case shaderir.Discard:
|
||||||
lines = append(lines, idt+"discard;")
|
// 'discard' is invoked only in the fragment shader entry point.
|
||||||
|
lines = append(lines, idt+"discard;", idt+"return float4(0.0, 0.0, 0.0, 0.0);")
|
||||||
default:
|
default:
|
||||||
lines = append(lines, fmt.Sprintf("%s?(unexpected stmt: %d)", idt, s.Type))
|
lines = append(lines, fmt.Sprintf("%s?(unexpected stmt: %d)", idt, s.Type))
|
||||||
}
|
}
|
||||||
|
@ -985,7 +985,7 @@ varying vec2 V1;`,
|
|||||||
{Main: shaderir.Float},
|
{Main: shaderir.Float},
|
||||||
{Main: shaderir.Vec2},
|
{Main: shaderir.Vec2},
|
||||||
},
|
},
|
||||||
3+1,
|
3,
|
||||||
assignStmt(
|
assignStmt(
|
||||||
localVariableExpr(3),
|
localVariableExpr(3),
|
||||||
localVariableExpr(0),
|
localVariableExpr(0),
|
||||||
@ -994,8 +994,7 @@ varying vec2 V1;`,
|
|||||||
localVariableExpr(4),
|
localVariableExpr(4),
|
||||||
localVariableExpr(1),
|
localVariableExpr(1),
|
||||||
),
|
),
|
||||||
assignStmt(
|
returnStmt(
|
||||||
localVariableExpr(5),
|
|
||||||
localVariableExpr(2),
|
localVariableExpr(2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -1019,20 +1018,18 @@ uniform float U0;
|
|||||||
varying float V0;
|
varying float V0;
|
||||||
varying vec2 V1;
|
varying vec2 V1;
|
||||||
|
|
||||||
void F0(in vec4 l0, in float l1, in vec2 l2, out vec4 l3);
|
vec4 F0(in vec4 l0, in float l1, in vec2 l2);
|
||||||
|
|
||||||
void F0(in vec4 l0, in float l1, in vec2 l2, out vec4 l3) {
|
vec4 F0(in vec4 l0, in float l1, in vec2 l2) {
|
||||||
float l4 = float(0);
|
float l3 = float(0);
|
||||||
vec2 l5 = vec2(0);
|
vec2 l4 = vec2(0);
|
||||||
l3 = l0;
|
l3 = l0;
|
||||||
l4 = l1;
|
l4 = l1;
|
||||||
l5 = l2;
|
return l2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 l0 = vec4(0);
|
gl_FragColor = F0(gl_FragCoord, V0, V1);
|
||||||
F0(gl_FragCoord, V0, V1, l0);
|
|
||||||
gl_FragColor = l0;
|
|
||||||
}`,
|
}`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
vertexOut = "varyings"
|
vertexOut = "varyings"
|
||||||
fragmentOut = "out"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type compileContext struct {
|
type compileContext struct {
|
||||||
@ -137,11 +136,7 @@ func Compile(p *shaderir.Program, vertex, fragment string) (shader string) {
|
|||||||
lines = append(lines, fmt.Sprintf("\ttexture2d<float> T%[1]d [[texture(%[1]d)]]", i))
|
lines = append(lines, fmt.Sprintf("\ttexture2d<float> T%[1]d [[texture(%[1]d)]]", i))
|
||||||
}
|
}
|
||||||
lines[len(lines)-1] += ") {"
|
lines[len(lines)-1] += ") {"
|
||||||
lines = append(lines, fmt.Sprintf("\tfloat4 %s = float4(0);", fragmentOut))
|
|
||||||
lines = append(lines, c.block(p, p.FragmentFunc.Block, p.FragmentFunc.Block, 0)...)
|
lines = append(lines, c.block(p, p.FragmentFunc.Block, p.FragmentFunc.Block, 0)...)
|
||||||
if last := fmt.Sprintf("\treturn %s;", fragmentOut); lines[len(lines)-1] != last {
|
|
||||||
lines = append(lines, last)
|
|
||||||
}
|
|
||||||
lines = append(lines, "}")
|
lines = append(lines, "}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,10 +301,8 @@ func localVariableName(p *shaderir.Program, topBlock *shaderir.Block, idx int) s
|
|||||||
return fmt.Sprintf("%s.Position", vertexOut)
|
return fmt.Sprintf("%s.Position", vertexOut)
|
||||||
case idx < nv+1:
|
case idx < nv+1:
|
||||||
return fmt.Sprintf("%s.M%d", vertexOut, idx-1)
|
return fmt.Sprintf("%s.M%d", vertexOut, idx-1)
|
||||||
case idx == nv+1:
|
|
||||||
return fragmentOut
|
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx-(nv+2))
|
return fmt.Sprintf("l%d", idx-(nv+1))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("l%d", idx)
|
return fmt.Sprintf("l%d", idx)
|
||||||
@ -495,15 +488,14 @@ func (c *compileContext) block(p *shaderir.Program, topBlock, block *shaderir.Bl
|
|||||||
switch {
|
switch {
|
||||||
case topBlock == p.VertexFunc.Block:
|
case topBlock == p.VertexFunc.Block:
|
||||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, vertexOut))
|
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, vertexOut))
|
||||||
case topBlock == p.FragmentFunc.Block:
|
|
||||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, fragmentOut))
|
|
||||||
case len(s.Exprs) == 0:
|
case len(s.Exprs) == 0:
|
||||||
lines = append(lines, idt+"return;")
|
lines = append(lines, idt+"return;")
|
||||||
default:
|
default:
|
||||||
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
|
lines = append(lines, fmt.Sprintf("%sreturn %s;", idt, expr(&s.Exprs[0])))
|
||||||
}
|
}
|
||||||
case shaderir.Discard:
|
case shaderir.Discard:
|
||||||
lines = append(lines, idt+"discard_fragment();")
|
// 'discard' is invoked only in the fragment shader entry point.
|
||||||
|
lines = append(lines, idt+"discard_fragment();", idt+"return float4(0.0);")
|
||||||
default:
|
default:
|
||||||
lines = append(lines, fmt.Sprintf("%s?(unexpected stmt: %d)", idt, s.Type))
|
lines = append(lines, fmt.Sprintf("%s?(unexpected stmt: %d)", idt, s.Type))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,6 @@ type VertexFunc struct {
|
|||||||
// FragmentFunc takes pseudo params, and the number is len(varyings) + 2.
|
// FragmentFunc takes pseudo params, and the number is len(varyings) + 2.
|
||||||
// If index == 0, the param represents the coordinate of the fragment (gl_FragCoord in GLSL).
|
// If index == 0, the param represents the coordinate of the fragment (gl_FragCoord in GLSL).
|
||||||
// If 0 < index <= len(varyings), the param represents (index-1)th verying variable.
|
// If 0 < 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 {
|
type FragmentFunc struct {
|
||||||
Block *Block
|
Block *Block
|
||||||
}
|
}
|
||||||
|
@ -193,10 +193,8 @@ func (p *Program) LocalVariableType(topBlock, block *Block, idx int) Type {
|
|||||||
return Type{Main: Vec4}
|
return Type{Main: Vec4}
|
||||||
case idx < nv+1:
|
case idx < nv+1:
|
||||||
return p.Varyings[idx-1]
|
return p.Varyings[idx-1]
|
||||||
case idx == nv+1:
|
|
||||||
return Type{Main: Vec4}
|
|
||||||
default:
|
default:
|
||||||
return localVariableType(p, topBlock, block, idx-(nv+2))
|
return localVariableType(p, topBlock, block, idx-(nv+1))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return localVariableType(p, topBlock, block, idx)
|
return localVariableType(p, topBlock, block, idx)
|
||||||
|
Loading…
Reference in New Issue
Block a user