diff --git a/reference/shaders/frag/composite-extract-forced-temporary.frag b/reference/shaders/frag/composite-extract-forced-temporary.frag new file mode 100644 index 00000000..78b28a99 --- /dev/null +++ b/reference/shaders/frag/composite-extract-forced-temporary.frag @@ -0,0 +1,15 @@ +#version 310 es +precision mediump float; +precision highp int; + +layout(binding = 0) uniform mediump sampler2D Texture; + +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; + +void main() +{ + float f = texture(Texture, vTexCoord).x; + FragColor = vec4((f * f)); +} + diff --git a/reference/shaders/frag/sampler-ms.frag b/reference/shaders/frag/sampler-ms.frag new file mode 100644 index 00000000..45fea2d6 --- /dev/null +++ b/reference/shaders/frag/sampler-ms.frag @@ -0,0 +1,14 @@ +#version 310 es +precision mediump float; +precision highp int; + +layout(binding = 0) uniform mediump sampler2DMS uSampler; + +layout(location = 0) out vec4 FragColor; + +void main() +{ + ivec2 coord = ivec2(gl_FragCoord.xy); + FragColor = (((texelFetch(uSampler, coord, 0) + texelFetch(uSampler, coord, 1)) + texelFetch(uSampler, coord, 2)) + texelFetch(uSampler, coord, 3)); +} + diff --git a/reference/shaders/geom/single-invocation.geom b/reference/shaders/geom/single-invocation.geom new file mode 100644 index 00000000..592f7996 --- /dev/null +++ b/reference/shaders/geom/single-invocation.geom @@ -0,0 +1,26 @@ +#version 310 es +#extension GL_EXT_geometry_shader : require +layout(triangles) in; +layout(max_vertices = 3, triangle_strip) out; + +out vec3 vNormal; +in VertexData +{ + vec3 normal; +} vin[3]; + + +void main() +{ + gl_Position = gl_in[0].gl_Position; + vNormal = vin[0].normal; + EmitVertex(); + gl_Position = gl_in[1].gl_Position; + vNormal = vin[1].normal; + EmitVertex(); + gl_Position = gl_in[2].gl_Position; + vNormal = vin[2].normal; + EmitVertex(); + EndPrimitive(); +} + diff --git a/shaders/frag/composite-extract-forced-temporary.frag b/shaders/frag/composite-extract-forced-temporary.frag new file mode 100644 index 00000000..35fdbe86 --- /dev/null +++ b/shaders/frag/composite-extract-forced-temporary.frag @@ -0,0 +1,11 @@ +#version 310 es +precision mediump float; +layout(binding = 0) uniform sampler2D Texture; +layout(location = 0) out vec4 FragColor; +layout(location = 0) in vec2 vTexCoord; + +void main() +{ + float f = texture(Texture, vTexCoord).x; + FragColor = vec4(f * f); +} diff --git a/shaders/frag/sampler-ms.frag b/shaders/frag/sampler-ms.frag new file mode 100644 index 00000000..f10785d6 --- /dev/null +++ b/shaders/frag/sampler-ms.frag @@ -0,0 +1,16 @@ +#version 310 es +precision mediump float; +precision highp int; + +layout(binding = 0) uniform sampler2DMS uSampler; +layout(location = 0) out vec4 FragColor; + +void main() +{ + ivec2 coord = ivec2(gl_FragCoord.xy); + FragColor = + texelFetch(uSampler, coord, 0) + + texelFetch(uSampler, coord, 1) + + texelFetch(uSampler, coord, 2) + + texelFetch(uSampler, coord, 3); +} diff --git a/shaders/geom/single-invocation.geom b/shaders/geom/single-invocation.geom new file mode 100644 index 00000000..92f60011 --- /dev/null +++ b/shaders/geom/single-invocation.geom @@ -0,0 +1,28 @@ +#version 310 es +#extension GL_EXT_geometry_shader : require + +layout(triangles) in; +layout(triangle_strip, max_vertices = 3) out; + +in VertexData { + vec3 normal; +} vin[]; + +out vec3 vNormal; + +void main() +{ + gl_Position = gl_in[0].gl_Position; + vNormal = vin[0].normal; + EmitVertex(); + + gl_Position = gl_in[1].gl_Position; + vNormal = vin[1].normal; + EmitVertex(); + + gl_Position = gl_in[2].gl_Position; + vNormal = vin[2].normal; + EmitVertex(); + + EndPrimitive(); +} diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 9df30ed9..bf33a25e 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -229,8 +229,13 @@ void CompilerGLSL::emit_header() if (!options.es && options.version < 320) statement("#extension GL_ARB_geometry_shader4 : require"); outputs.push_back(join("max_vertices = ", execution.output_vertices)); - if (execution.flags & (1ull << ExecutionModeInvocations)) + if ((execution.flags & (1ull << ExecutionModeInvocations)) && execution.invocations != 1) + { + // Instanced GS is part of 400 core or this extension. + if (!options.es && options.version < 400) + statement("#extension GL_ARB_gpu_shader5 : require"); inputs.push_back(join("invocations = ", execution.invocations)); + } if (execution.flags & (1ull << ExecutionModeInputPoints)) inputs.push_back("points"); if (execution.flags & (1ull << ExecutionModeInputLines)) @@ -1838,6 +1843,12 @@ void CompilerGLSL::emit_texture_op(const Instruction &i) expr += to_expression(comp); } + if (sample) + { + expr += ", "; + expr += to_expression(sample); + } + expr += ")"; emit_op(result_type, id, expr, forward, false); @@ -2805,8 +2816,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto &type = get(result_type); + // We can only split the expression here if our expression is forwarded as a temporary. + bool allow_base_expression = forced_temporaries.find(id) == end(forced_temporaries); + // Only apply this optimization if result is scalar. - if (should_forward(ops[2]) && type.vecsize == 1 && type.columns == 1 && length == 1) + if (allow_base_expression && should_forward(ops[2]) && type.vecsize == 1 && type.columns == 1 && length == 1) { // We want to split the access chain from the base. // This is so we can later combine different CompositeExtract results