Add support for SampleId/SampleMask/SamplePosition builtins.

This commit is contained in:
Hans-Kristian Arntzen 2017-07-24 10:07:02 +02:00
parent d89d0e01fc
commit c8d60914c4
10 changed files with 88 additions and 35 deletions

View File

@ -0,0 +1,13 @@
#version 310 es
#extension GL_OES_sample_variables : require
precision mediump float;
precision highp int;
layout(location = 0) out vec2 FragColor;
void main()
{
FragColor = (gl_SamplePosition + vec2(float(gl_SampleMaskIn[0]))) + vec2(float(gl_SampleID));
gl_SampleMask[0] = 1;
}

View File

@ -1,14 +1,12 @@
#version 310 es
precision mediump float;
precision highp int;
#version 450
layout(binding = 0) uniform mediump sampler2DMS uSubpass0;
layout(binding = 1) uniform mediump sampler2DMS uSubpass1;
layout(binding = 0) uniform sampler2DMS uSubpass0;
layout(binding = 1) uniform sampler2DMS uSubpass1;
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = texelFetch(uSubpass0, ivec2(gl_FragCoord.xy), 1) + texelFetch(uSubpass1, ivec2(gl_FragCoord.xy), 2);
FragColor = (texelFetch(uSubpass0, ivec2(gl_FragCoord.xy), 1) + texelFetch(uSubpass1, ivec2(gl_FragCoord.xy), 2)) + texelFetch(uSubpass0, ivec2(gl_FragCoord.xy), gl_SampleID);
}

View File

@ -1,14 +1,12 @@
#version 310 es
precision mediump float;
precision highp int;
#version 450
layout(input_attachment_index = 0, set = 0, binding = 0) uniform mediump subpassInputMS uSubpass0;
layout(input_attachment_index = 1, set = 0, binding = 1) uniform mediump subpassInputMS uSubpass1;
layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInputMS uSubpass0;
layout(input_attachment_index = 1, set = 0, binding = 1) uniform subpassInputMS uSubpass1;
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = subpassLoad(uSubpass0, 1) + subpassLoad(uSubpass1, 2);
FragColor = (subpassLoad(uSubpass0, 1) + subpassLoad(uSubpass1, 2)) + subpassLoad(uSubpass0, gl_SampleID);
}

View File

@ -0,0 +1,11 @@
#version 310 es
#extension GL_OES_sample_variables : require
precision mediump float;
layout(location = 0) out vec2 FragColor;
void main()
{
FragColor = gl_SamplePosition + vec2(gl_SampleMaskIn[0]) + float(gl_SampleID);
gl_SampleMask[0] = 1;
}

View File

@ -1,11 +1,10 @@
#version 310 es
precision mediump float;
#version 450
layout(input_attachment_index = 0, set = 0, binding = 0) uniform mediump subpassInputMS uSubpass0;
layout(input_attachment_index = 1, set = 0, binding = 1) uniform mediump subpassInputMS uSubpass1;
layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInputMS uSubpass0;
layout(input_attachment_index = 1, set = 0, binding = 1) uniform subpassInputMS uSubpass1;
layout(location = 0) out vec4 FragColor;
void main()
{
FragColor = subpassLoad(uSubpass0, 1) + subpassLoad(uSubpass1, 2);
FragColor = subpassLoad(uSubpass0, 1) + subpassLoad(uSubpass1, 2) + subpassLoad(uSubpass0, gl_SampleID);
}

View File

@ -1917,7 +1917,7 @@ string CompilerGLSL::to_expression(uint32_t id)
{
auto &dec = meta[var.self].decoration;
if (dec.builtin)
return builtin_to_glsl(dec.builtin_type);
return builtin_to_glsl(dec.builtin_type, var.storage);
else
return to_name(id);
}
@ -3448,7 +3448,7 @@ string CompilerGLSL::bitcast_glsl(const SPIRType &result_type, uint32_t argument
return join(op, "(", to_expression(argument), ")");
}
string CompilerGLSL::builtin_to_glsl(BuiltIn builtin)
string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
{
switch (builtin)
{
@ -3512,6 +3512,32 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin)
return "gl_GlobalInvocationID";
case BuiltInLocalInvocationIndex:
return "gl_LocalInvocationIndex";
case BuiltInSampleId:
if (options.es && options.version < 320)
require_extension("GL_OES_sample_variables");
if (!options.es && options.version < 400)
SPIRV_CROSS_THROW("gl_SampleID not supported before GLSL 400.");
return "gl_SampleID";
case BuiltInSampleMask:
if (options.es && options.version < 320)
require_extension("GL_OES_sample_variables");
if (!options.es && options.version < 400)
SPIRV_CROSS_THROW("gl_SampleMask/gl_SampleMaskIn not supported before GLSL 400.");
if (storage == StorageClassInput)
return "gl_SampleMaskIn";
else
return "gl_SampleMask";
case BuiltInSamplePosition:
if (options.es && options.version < 320)
require_extension("GL_OES_sample_variables");
if (!options.es && options.version < 400)
SPIRV_CROSS_THROW("gl_SamplePosition not supported before GLSL 400.");
return "gl_SamplePosition";
default:
return join("gl_BuiltIn_", convert_to_string(builtin));
}
@ -3629,10 +3655,10 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
if (access_chain_is_arrayed)
{
expr += ".";
expr += builtin_to_glsl(builtin);
expr += builtin_to_glsl(builtin, type->storage);
}
else
expr = builtin_to_glsl(builtin);
expr = builtin_to_glsl(builtin, type->storage);
}
else
{

View File

@ -172,7 +172,7 @@ protected:
virtual void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id);
virtual void emit_texture_op(const Instruction &i);
virtual std::string type_to_glsl(const SPIRType &type, uint32_t id = 0);
virtual std::string builtin_to_glsl(spv::BuiltIn builtin);
virtual std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage);
virtual void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index,
const std::string &qualifier = "");
virtual std::string image_type_glsl(const SPIRType &type, uint32_t id = 0);

View File

@ -326,7 +326,7 @@ void CompilerHLSL::emit_builtin_outputs_in_struct()
}
if (type && semantic)
statement(type, " ", builtin_to_glsl(builtin), " : ", semantic, ";");
statement(type, " ", builtin_to_glsl(builtin, StorageClassOutput), " : ", semantic, ";");
}
}
@ -375,7 +375,7 @@ void CompilerHLSL::emit_builtin_inputs_in_struct()
}
if (type && semantic)
statement(type, " ", builtin_to_glsl(builtin), " : ", semantic, ";");
statement(type, " ", builtin_to_glsl(builtin, StorageClassInput), " : ", semantic, ";");
}
}
@ -574,8 +574,12 @@ void CompilerHLSL::emit_builtin_variables()
break;
}
StorageClass storage = (active_input_builtins & (1ull << i)) != 0 ? StorageClassInput : StorageClassOutput;
// FIXME: SampleMask can be both in and out with sample builtin,
// need to distinguish that when we add support for that.
if (type)
statement("static ", type, " ", builtin_to_glsl(builtin), ";");
statement("static ", type, " ", builtin_to_glsl(builtin, storage), ";");
}
}
@ -1066,7 +1070,7 @@ void CompilerHLSL::emit_hlsl_entry_point()
if (!(active_input_builtins & (1ull << i)))
continue;
auto builtin = builtin_to_glsl(static_cast<BuiltIn>(i));
auto builtin = builtin_to_glsl(static_cast<BuiltIn>(i), StorageClassInput);
switch (static_cast<BuiltIn>(i))
{
case BuiltInFragCoord:
@ -1173,7 +1177,7 @@ void CompilerHLSL::emit_hlsl_entry_point()
if (i == BuiltInPointSize)
continue;
auto builtin = builtin_to_glsl(static_cast<BuiltIn>(i));
auto builtin = builtin_to_glsl(static_cast<BuiltIn>(i), StorageClassOutput);
statement("stage_output.", builtin, " = ", builtin, ";");
}

View File

@ -591,7 +591,8 @@ string CompilerMSL::add_input_buffer_block_member(uint32_t mbr_type_id, string m
set_member_decoration(ib_type_id, ib_mbr_idx, DecorationLocation, k_unknown_location);
// Update the original variable reference to include the structure and index reference
string idx_var_name = builtin_to_glsl(p_va->per_instance ? BuiltInInstanceIndex : BuiltInVertexIndex);
string idx_var_name =
builtin_to_glsl(p_va->per_instance ? BuiltInInstanceIndex : BuiltInVertexIndex, StorageClassInput);
return get_name(ib_var_id) + "[" + idx_var_name + "]." + mbr_name;
}
@ -2385,7 +2386,7 @@ string CompilerMSL::to_qualified_member_name(const SPIRType &type, uint32_t inde
// Don't qualify Builtin names because they are unique and are treated as such when building expressions
BuiltIn builtin;
if (is_member_builtin(type, index, &builtin))
return builtin_to_glsl(builtin);
return builtin_to_glsl(builtin, type.storage);
// Strip any underscore prefix from member name
string mbr_name = to_member_name(type, index);
@ -2592,7 +2593,7 @@ string CompilerMSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &in
// Returns an MSL string identifying the name of a SPIR-V builtin.
// Output builtins are qualified with the name of the stage out structure.
string CompilerMSL::builtin_to_glsl(BuiltIn builtin)
string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage)
{
switch (builtin)
{
@ -2613,12 +2614,12 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin)
case BuiltInClipDistance:
case BuiltInLayer:
if (current_function && (current_function->self == entry_point))
return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin);
return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage);
else
return CompilerGLSL::builtin_to_glsl(builtin);
return CompilerGLSL::builtin_to_glsl(builtin, storage);
default:
return CompilerGLSL::builtin_to_glsl(builtin);
return CompilerGLSL::builtin_to_glsl(builtin, storage);
}
}
@ -2744,7 +2745,10 @@ string CompilerMSL::built_in_func_arg(BuiltIn builtin, bool prefix_comma)
if (prefix_comma)
bi_arg += ", ";
bi_arg += builtin_type_decl(builtin);
bi_arg += " " + builtin_to_glsl(builtin);
assert(builtin == BuiltInVertexIndex || builtin == BuiltInInstanceIndex);
bi_arg += " " + builtin_to_glsl(builtin, StorageClassInput);
bi_arg += " [[" + builtin_qualifier(builtin) + "]]";
return bi_arg;
}

View File

@ -151,7 +151,7 @@ protected:
const std::string &qualifier = "") override;
std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
std::string image_type_glsl(const SPIRType &type, uint32_t id = 0) override;
std::string builtin_to_glsl(spv::BuiltIn builtin) override;
std::string builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) override;
std::string constant_expression(const SPIRConstant &c) override;
size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const override;
std::string to_func_call_arg(uint32_t id) override;