Emit storage qualifier in the correct place.

Need to emit qualifiers in a specific order for legacy GLSL.

<interpolation> <storage> <precision> <type>.
This commit is contained in:
Hans-Kristian Arntzen 2017-02-24 09:56:17 +01:00
parent e941b92b11
commit 036b9b73f5
10 changed files with 58 additions and 33 deletions

View File

@ -9,10 +9,10 @@ in VertexData
layout(location = 3) float i;
} vin;
layout(location = 4) in flat float f;
layout(location = 5) in centroid vec4 g;
layout(location = 6) in flat int h;
layout(location = 7) in sample float i;
layout(location = 4) flat in float f;
layout(location = 5) centroid in vec4 g;
layout(location = 6) flat in int h;
layout(location = 7) sample in float i;
void main()
{

View File

@ -8,9 +8,9 @@ out VertexData
layout(location = 3) float i;
} vout;
layout(location = 4) out flat float f;
layout(location = 5) out centroid vec4 g;
layout(location = 6) out flat int h;
layout(location = 4) flat out float f;
layout(location = 5) centroid out vec4 g;
layout(location = 6) flat out int h;
layout(location = 7) out float i;
void main()

View File

@ -9,7 +9,7 @@ struct Foobar
};
layout(location = 0) out vec4 FragColor;
layout(location = 0) in mediump flat int index;
layout(location = 0) flat in mediump int index;
vec4 resolve(Foobar f)
{

View File

@ -4,19 +4,19 @@ precision highp int;
struct Inputs
{
vec4 a;
vec2 b;
highp vec4 a;
highp vec2 b;
};
varying vec4 Inputs_a;
varying vec2 Inputs_b;
varying highp vec4 Inputs_a;
varying highp vec2 Inputs_b;
void main()
{
Inputs v0 = Inputs(Inputs_a, Inputs_b);
Inputs v1 = Inputs(Inputs_a, Inputs_b);
vec4 a = Inputs_a;
vec4 b = Inputs_b.xxyy;
highp vec4 a = Inputs_a;
highp vec4 b = Inputs_b.xxyy;
gl_FragData[0] = ((((v0.a + v0.b.xxyy) + v1.a) + v1.b.yyxx) + a) + b;
}

View File

@ -2,7 +2,7 @@
#extension GL_EXT_tessellation_shader : require
layout(vertices = 1) out;
out patch vec3 vFoo;
patch out vec3 vFoo;
void main()
{

View File

@ -12,8 +12,8 @@ layout(std140) uniform UBO
vec4 uFrustum[6];
} _41;
out patch vec2 vOutPatchPosBase;
out patch vec4 vPatchLods;
patch out vec2 vOutPatchPosBase;
patch out vec4 vPatchLods;
in vec2 vPatchPosBase[32];
bool frustum_cull(vec2 p0)

View File

@ -14,8 +14,8 @@ layout(binding = 1, std140) uniform UBO
layout(binding = 0) uniform mediump sampler2D uHeightmapDisplacement;
in patch vec2 vOutPatchPosBase;
in patch vec4 vPatchLods;
patch in vec2 vOutPatchPosBase;
patch in vec4 vPatchLods;
out vec4 vGradNormalTex;
out vec3 vWorld;

View File

@ -1,5 +1,5 @@
#version 310 es
precision mediump float;
precision highp float;
struct Inputs
{

View File

@ -1138,21 +1138,36 @@ void CompilerGLSL::emit_buffer_block_flattened(const SPIRVariable &var)
SPIRV_CROSS_THROW("All basic types in a flattened block must be the same.");
}
void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
const char *CompilerGLSL::to_storage_qualifiers_glsl(const SPIRVariable &var)
{
auto &execution = get_entry_point();
if (var.storage == StorageClassInput || var.storage == StorageClassOutput)
{
if (is_legacy() && execution.model == ExecutionModelVertex)
return var.storage == StorageClassInput ? "attribute " : "varying ";
else if (is_legacy() && execution.model == ExecutionModelFragment)
return "varying "; // Fragment outputs are renamed so they never hit this case.
else
return var.storage == StorageClassInput ? "in " : "out ";
}
else if (var.storage == StorageClassUniformConstant || var.storage == StorageClassUniform ||
var.storage == StorageClassPushConstant)
{
return "uniform ";
}
return "";
}
void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
{
auto &type = get<SPIRType>(var.basetype);
// Either make it plain in/out or in/out blocks depending on what shader is doing ...
bool block = (meta[type.self].decoration.decoration_flags & (1ull << DecorationBlock)) != 0;
const char *qual = nullptr;
if (is_legacy() && execution.model == ExecutionModelVertex)
qual = var.storage == StorageClassInput ? "attribute " : "varying ";
else if (is_legacy() && execution.model == ExecutionModelFragment)
qual = "varying "; // Fragment outputs are renamed so they never hit this case.
else
qual = var.storage == StorageClassInput ? "in " : "out ";
const char *qual = to_storage_qualifiers_glsl(var);
if (block)
{
@ -1242,7 +1257,7 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
else
{
add_resource_name(var.self);
statement(layout_for_variable(var), qual, variable_decl(var), ";");
statement(layout_for_variable(var), variable_decl(var), ";");
}
}
}
@ -1259,7 +1274,7 @@ void CompilerGLSL::emit_uniform(const SPIRVariable &var)
}
add_resource_name(var.self);
statement(layout_for_variable(var), "uniform ", variable_decl(var), ";");
statement(layout_for_variable(var), variable_decl(var), ";");
}
void CompilerGLSL::emit_specialization_constant(const SPIRConstant &constant)
@ -3451,7 +3466,12 @@ void CompilerGLSL::store_flattened_struct(SPIRVariable &var, uint32_t value)
// Since we're declaring a variable potentially multiple times here,
// store the variable in an isolated scope.
begin_scope();
// Emit variable without storage qualifiers because it's a local variable here.
auto old_storage = var.storage;
var.storage = StorageClassFunction;
statement(variable_decl(var), " = ", rhs, ";");
var.storage = old_storage;
auto &type = get<SPIRType>(var.basetype);
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
@ -5480,8 +5500,9 @@ string CompilerGLSL::member_decl(const SPIRType &type, const SPIRType &membertyp
if (is_block)
qualifiers = to_interpolation_qualifiers(memberflags);
return join(layout_for_member(type, index), flags_to_precision_qualifiers_glsl(membertype, memberflags), qualifiers,
qualifier, variable_decl(membertype, to_member_name(type, index)));
return join(layout_for_member(type, index), qualifiers, qualifier,
flags_to_precision_qualifiers_glsl(membertype, memberflags),
variable_decl(membertype, to_member_name(type, index)));
}
const char *CompilerGLSL::flags_to_precision_qualifiers_glsl(const SPIRType &type, uint64_t flags)
@ -5542,9 +5563,12 @@ string CompilerGLSL::to_qualifiers_glsl(uint32_t id)
if (var && var->storage == StorageClassWorkgroup && !backend.shared_is_implied)
res += "shared ";
res += to_precision_qualifiers_glsl(id);
res += to_interpolation_qualifiers(flags);
if (var)
res += to_storage_qualifiers_glsl(*var);
res += to_precision_qualifiers_glsl(id);
auto &type = expression_type(id);
if (type.image.dim != DimSubpassData && type.image.sampled == 2)
{
if (flags & (1ull << DecorationNonWritable))

View File

@ -349,6 +349,7 @@ protected:
std::string argument_decl(const SPIRFunction::Parameter &arg);
std::string to_qualifiers_glsl(uint32_t id);
const char *to_precision_qualifiers_glsl(uint32_t id);
const char *to_storage_qualifiers_glsl(const SPIRVariable &var);
const char *flags_to_precision_qualifiers_glsl(const SPIRType &type, uint64_t flags);
const char *format_to_glsl(spv::ImageFormat format);
std::string layout_for_member(const SPIRType &type, uint32_t index);