Skip to content

Commit 4df211a

Browse files
Force inline sampler types after argument inlining (fixes #496) (#498)
1 parent 05d200b commit 4df211a

4 files changed

Lines changed: 39 additions & 0 deletions

File tree

Minifier/builtin.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ let builtinMatrixTypes = set([
2828
yield p+"mat"+c+"x"+r
2929
])
3030

31+
let isSamplerType (name: string) = name.Contains("sampler")
32+
3133
let builtinTypes = set [ "void" ] + builtinScalarTypes + builtinVectorTypes + builtinMatrixTypes;
3234

3335
let implicitConversions = // (from, to)

Minifier/inlining.fs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,12 @@ type ArgumentInlining(options: Options.Options) =
339339
let _, body = options.visitor(applyExpr).mapStmt (BlockLevel.FunctionRoot fct) body
340340
// Handle argument inlining for f. Remove the parameter from the declaration.
341341
let fct = {fct with args = removeInlined f fct.args}
342+
// Sampler types can be declared as globals or as function parameters but not as locals.
343+
// This means we can inline them into the body of the function only if we inline them further.
344+
for inl in argInlinings do
345+
match inl.varDecl.ty.name with
346+
| TypeName ident when Builtin.isSamplerType ident.Name -> inl.varDecl.decl.name.ToBeInlined <- true
347+
| _ -> ()
342348
// Handle argument inlining for f. Insert in front of the body a declaration for each inlined argument.
343349
let decls =
344350
argInlinings

tests/unit/arg-inlining.expected

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#version 300 es
2+
3+
precision highp float;
14
float noinline_canInlineWhenResolvable()
25
{
36
return 11.;
@@ -78,7 +81,19 @@ float f()
7881
s+=s+noinline_cannotInlineWhenArgIsNotInlinable(s);
7982
return s+s+noinline_cannotInlineWhenArgIsNotInlinable(acos(s));
8083
}
84+
out vec4 fragColor;
85+
uniform sampler2D samp;
86+
vec3 dof()
87+
{
88+
float f=10.;
89+
for(;;)
90+
{
91+
vec3 a=texture(samp,vec2(0)).xyz;
92+
return a.zyx+a.xyz*(f*=f);
93+
}
94+
}
8195
void main()
8296
{
8397
f();
98+
fragColor.xyz=dof();
8499
}

tests/unit/arg-inlining.frag

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#version 300 es
2+
precision highp float;
3+
14
// Argument inlining inlines the argument of a function call into the function body.
25

36
float noinline_canInlineWhenResolvable(float a) { return a+10.; }
@@ -46,7 +49,20 @@ float f()
4649
return s;
4750
}
4851

52+
53+
// sampler types are immutable and cannot be locals, they must always be inlined (#496)
54+
out vec4 fragColor;
55+
uniform sampler2D samp;
56+
vec3 dof(sampler2D tex, float f) {
57+
for (;;) {
58+
vec3 a = texture(tex,vec2(0)).rgb;
59+
return a.zyx+a.xyz*(f*=f);
60+
}
61+
}
62+
63+
4964
void main()
5065
{
5166
f();
67+
fragColor.xyz = dof(samp, 10.0);
5268
}

0 commit comments

Comments
 (0)