Add support for loading flattened structs.
This commit is contained in:
parent
97350d32fd
commit
fc80cd8cbf
22
reference/shaders/legacy/fragment/struct-varying.legacy.frag
Normal file
22
reference/shaders/legacy/fragment/struct-varying.legacy.frag
Normal file
@ -0,0 +1,22 @@
|
||||
#version 100
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
struct Inputs
|
||||
{
|
||||
vec4 a;
|
||||
vec2 b;
|
||||
};
|
||||
|
||||
varying vec4 Inputs_a;
|
||||
varying 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;
|
||||
gl_FragData[0] = ((((v0.a + v0.b.xxyy) + v1.a) + v1.b.yyxx) + a) + b;
|
||||
}
|
||||
|
@ -22,7 +22,11 @@ void main()
|
||||
Output_a = vout.a;
|
||||
Output_b = vout.b;
|
||||
}
|
||||
Output_a = s.a;
|
||||
Output_b = s.b;
|
||||
Output tmp = Output(Output_a, Output_b);
|
||||
Output_a = tmp.a;
|
||||
Output_b = tmp.b;
|
||||
Output_a.x = 1.0;
|
||||
Output_b.y = 1.0;
|
||||
float c = Output_a.x;
|
||||
}
|
||||
|
25
shaders/legacy/fragment/struct-varying.legacy.frag
Normal file
25
shaders/legacy/fragment/struct-varying.legacy.frag
Normal file
@ -0,0 +1,25 @@
|
||||
#version 310 es
|
||||
precision mediump float;
|
||||
|
||||
struct Inputs
|
||||
{
|
||||
vec4 a;
|
||||
vec2 b;
|
||||
};
|
||||
|
||||
layout(location = 0) in Inputs vin;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Read struct once.
|
||||
Inputs v0 = vin;
|
||||
// Read struct again.
|
||||
Inputs v1 = vin;
|
||||
|
||||
// Read members individually.
|
||||
vec4 a = vin.a;
|
||||
vec4 b = vin.b.xxyy;
|
||||
|
||||
FragColor = v0.a + v0.b.xxyy + v1.a + v1.b.yyxx + a + b;
|
||||
}
|
@ -17,7 +17,17 @@ void main()
|
||||
// Write whole struct again, checks for scoping.
|
||||
vout = s;
|
||||
|
||||
// Read it back.
|
||||
Output tmp = vout;
|
||||
|
||||
// Write elements individually.
|
||||
vout.a = s.a;
|
||||
vout.b = s.b;
|
||||
vout.a = tmp.a;
|
||||
vout.b = tmp.b;
|
||||
|
||||
// Write individual elements.
|
||||
vout.a.x = 1.0;
|
||||
vout.b.y = 1.0;
|
||||
|
||||
// Read individual elements.
|
||||
float c = vout.a.x;
|
||||
}
|
@ -1760,6 +1760,10 @@ string CompilerGLSL::to_expression(uint32_t id)
|
||||
var.deferred_declaration = false;
|
||||
return variable_decl(var);
|
||||
}
|
||||
else if (flattened_structs.count(id))
|
||||
{
|
||||
return load_flattened_struct(var);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto &dec = meta[var.self].decoration;
|
||||
@ -3386,6 +3390,11 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
|
||||
return expr;
|
||||
}
|
||||
|
||||
string CompilerGLSL::to_flattened_struct_member(const SPIRType &type, uint32_t index)
|
||||
{
|
||||
return sanitize_underscores(join(to_name(type.self), "_", to_member_name(type, index)));
|
||||
}
|
||||
|
||||
string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type,
|
||||
bool *out_need_transpose)
|
||||
{
|
||||
@ -3404,6 +3413,8 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
|
||||
{
|
||||
auto chain = access_chain_internal(base, indices, count, false, true).substr(1);
|
||||
auto &type = get<SPIRType>(get<SPIRVariable>(base).basetype);
|
||||
if (out_need_transpose)
|
||||
*out_need_transpose = false;
|
||||
return sanitize_underscores(join(to_name(type.self), "_", chain));
|
||||
}
|
||||
else
|
||||
@ -3412,6 +3423,25 @@ string CompilerGLSL::access_chain(uint32_t base, const uint32_t *indices, uint32
|
||||
}
|
||||
}
|
||||
|
||||
string CompilerGLSL::load_flattened_struct(SPIRVariable &var)
|
||||
{
|
||||
auto expr = type_to_glsl_constructor(get<SPIRType>(var.basetype));
|
||||
expr += '(';
|
||||
|
||||
auto &type = get<SPIRType>(var.basetype);
|
||||
for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++)
|
||||
{
|
||||
if (i)
|
||||
expr += ", ";
|
||||
|
||||
// Flatten the varyings.
|
||||
// Apply name transformation for flattened I/O blocks.
|
||||
expr += to_flattened_struct_member(type, i);
|
||||
}
|
||||
expr += ')';
|
||||
return expr;
|
||||
}
|
||||
|
||||
void CompilerGLSL::store_flattened_struct(SPIRVariable &var, uint32_t value)
|
||||
{
|
||||
// We're trying to store a structure which has been flattened.
|
||||
@ -3431,7 +3461,7 @@ void CompilerGLSL::store_flattened_struct(SPIRVariable &var, uint32_t value)
|
||||
// Apply name transformation for flattened I/O blocks.
|
||||
|
||||
auto lhs = sanitize_underscores(join(to_name(type.self), "_", to_member_name(type, i)));
|
||||
rhs = access_chain_internal(var.self, &i, 1, true);
|
||||
rhs = join(to_name(var.self), ".", to_member_name(type, i));
|
||||
statement(lhs, " = ", rhs, ";");
|
||||
}
|
||||
end_scope();
|
||||
|
@ -387,6 +387,8 @@ protected:
|
||||
std::unordered_set<uint32_t> flattened_buffer_blocks;
|
||||
std::unordered_set<uint32_t> flattened_structs;
|
||||
|
||||
std::string load_flattened_struct(SPIRVariable &var);
|
||||
std::string to_flattened_struct_member(const SPIRType &type, uint32_t index);
|
||||
void store_flattened_struct(SPIRVariable &var, uint32_t value);
|
||||
|
||||
// Usage tracking. If a temporary is used more than once, use the temporary instead to
|
||||
|
Loading…
Reference in New Issue
Block a user