diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2019-01-04 15:19:50 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2019-01-04 16:56:12 +0300 |
commit | acae607703ce8a3a417cbe0417041de5b891f300 (patch) | |
tree | 213e3222757ab0006513bdc38645f93dd516cd0b /shaders-hlsl | |
parent | 2154d7f06471f2178224d5da3190b1eb2190e008 (diff) |
Register implied expression reads in OpLoad/OpAccessChain.
This is required to avoid relying on complex sub-expression elimination
in compilers, and generates cleaner code.
The problem case is if a complex expression is used in an access chain,
like:
Composite comp = buffer[texture(...)];
vec4 a = comp.a + comp.b + comp.c;
Before, we did not have common subexpression tracking for
OpLoad/OpAccessChain, so we easily ended up with code like:
vec4 a = buffer[texture(...)].a + buffer[texture(...)].b + buffer[texture(...)].c;
A good compiler will optimize this, but we should not rely on it, and
forcing texture(...) to a temporary also looks better.
The solution is to add a vector "implied_expression_reads", which works
similarly to expression_dependencies. We also need an extra mechanism in
to_expression which lets us skip expression read checking and do it
later. E.g. for expr -> access chain -> load, we should only trigger
a read of expr when using the loaded expression.
Diffstat (limited to 'shaders-hlsl')
-rw-r--r-- | shaders-hlsl/frag/complex-expression-in-access-chain.frag | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/shaders-hlsl/frag/complex-expression-in-access-chain.frag b/shaders-hlsl/frag/complex-expression-in-access-chain.frag new file mode 100644 index 00000000..47f93931 --- /dev/null +++ b/shaders-hlsl/frag/complex-expression-in-access-chain.frag @@ -0,0 +1,29 @@ +#version 310 es +precision mediump float; + +struct Foo +{ + vec4 a; + vec4 b; +}; + +layout(binding = 0) buffer UBO +{ + vec4 results[1024]; +}; + +layout(binding = 1) uniform highp isampler2D Buf; +layout(location = 0) flat in int vIn; +layout(location = 1) flat in int vIn2; + +layout(location = 0) out vec4 FragColor; + +void main() +{ + ivec4 coords = texelFetch(Buf, ivec2(gl_FragCoord.xy), 0); + vec4 foo = results[coords.x % 16]; + + int c = vIn * vIn; + int d = vIn2 * vIn2; + FragColor = foo + foo + results[c + d]; +} |