Support mixed constant composites.
This commit is contained in:
parent
5e1d6fb3ce
commit
ceefae5584
@ -712,16 +712,27 @@ struct SPIRConstant : IVariant
|
||||
struct ConstantVector
|
||||
{
|
||||
Constant r[4];
|
||||
uint32_t id[4] = {}; // If != 0, this is a specialization constant, and we should keep track of it as such.
|
||||
uint32_t id[4] = {}; // If != 0, this element is a specialization constant, and we should keep track of it as such.
|
||||
uint32_t vecsize = 1;
|
||||
};
|
||||
|
||||
struct ConstantMatrix
|
||||
{
|
||||
ConstantVector c[4];
|
||||
uint32_t id[4] = {}; // If != 0, this column is a specialization constant, and we should keep track of it as such.
|
||||
uint32_t columns = 1;
|
||||
};
|
||||
|
||||
inline uint32_t specialization_constant_id(uint32_t col, uint32_t row) const
|
||||
{
|
||||
return m.c[col].id[row];
|
||||
}
|
||||
|
||||
inline uint32_t specialization_constant_id(uint32_t col) const
|
||||
{
|
||||
return m.id[col];
|
||||
}
|
||||
|
||||
inline uint32_t scalar(uint32_t col = 0, uint32_t row = 0) const
|
||||
{
|
||||
return m.c[col].r[row].u32;
|
||||
@ -756,10 +767,12 @@ struct SPIRConstant : IVariant
|
||||
{
|
||||
return m.c[0];
|
||||
}
|
||||
|
||||
inline uint32_t vector_size() const
|
||||
{
|
||||
return m.c[0].vecsize;
|
||||
}
|
||||
|
||||
inline uint32_t columns() const
|
||||
{
|
||||
return m.columns;
|
||||
@ -792,9 +805,6 @@ struct SPIRConstant : IVariant
|
||||
m.c[0].r[0].u32 = v0;
|
||||
m.c[0].vecsize = 1;
|
||||
m.columns = 1;
|
||||
|
||||
if (specialized)
|
||||
m.c[0].id[0] = self;
|
||||
}
|
||||
|
||||
// Construct scalar (64-bit).
|
||||
@ -804,31 +814,37 @@ struct SPIRConstant : IVariant
|
||||
m.c[0].r[0].u64 = v0;
|
||||
m.c[0].vecsize = 1;
|
||||
m.columns = 1;
|
||||
|
||||
if (specialized)
|
||||
m.c[0].id[0] = self;
|
||||
}
|
||||
|
||||
// Construct vector.
|
||||
// Construct vectors and matrices.
|
||||
SPIRConstant(uint32_t constant_type_, const SPIRConstant * const *vector_elements, uint32_t num_elements, bool specialized)
|
||||
: constant_type(constant_type_), specialization(specialized)
|
||||
{
|
||||
m.c[0].vecsize = num_elements;
|
||||
m.columns = 1;
|
||||
bool matrix = vector_elements[0]->m.c[0].vecsize > 1;
|
||||
|
||||
for (uint32_t i = 0; i < num_elements; i++)
|
||||
if (matrix)
|
||||
{
|
||||
m.c[0].r[i] = vector_elements[i]->m.c[0].r[0];
|
||||
m.c[0].id[i] = vector_elements[i]->m.c[0].id[0];
|
||||
}
|
||||
}
|
||||
m.columns = num_elements;
|
||||
|
||||
// Construct matrix.
|
||||
SPIRConstant(uint32_t constant_type_, const ConstantVector *vectors, uint32_t num_vectors, bool specialized)
|
||||
: constant_type(constant_type_), specialization(specialized)
|
||||
{
|
||||
m.columns = num_vectors;
|
||||
memcpy(m.c, vectors, num_vectors * sizeof(*vectors));
|
||||
for (uint32_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
m.c[i] = vector_elements[i]->m.c[0];
|
||||
if (vector_elements[i]->specialization)
|
||||
m.id[i] = vector_elements[i]->self;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.c[0].vecsize = num_elements;
|
||||
m.columns = 1;
|
||||
|
||||
for (uint32_t i = 0; i < num_elements; i++)
|
||||
{
|
||||
m.c[0].r[i] = vector_elements[i]->m.c[0].r[0];
|
||||
if (vector_elements[i]->specialization)
|
||||
m.c[0].id[i] = vector_elements[i]->self;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t constant_type;
|
||||
|
@ -1686,34 +1686,18 @@ void Compiler::parse(const Instruction &instruction)
|
||||
if (ctype.basetype == SPIRType::Struct || !ctype.array.empty())
|
||||
{
|
||||
set<SPIRConstant>(id, type, ops + 2, length - 2, op == OpSpecConstantComposite);
|
||||
break;
|
||||
}
|
||||
|
||||
bool matrix = ctype.columns > 1;
|
||||
|
||||
if (matrix)
|
||||
{
|
||||
uint32_t columns = length - 2;
|
||||
if (columns > 4)
|
||||
SPIRV_CROSS_THROW("OpConstantComposite only supports 1, 2, 3 and 4 columns.");
|
||||
|
||||
SPIRConstant::ConstantVector c[4];
|
||||
for (uint32_t i = 0; i < columns; i++)
|
||||
c[i] = get<SPIRConstant>(ops[2 + i]).vector();
|
||||
set<SPIRConstant>(id, type, c, columns, op == OpSpecConstantComposite);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t components = length - 2;
|
||||
if (components > 4)
|
||||
SPIRV_CROSS_THROW("OpConstantComposite only supports 1, 2, 3 and 4 components.");
|
||||
uint32_t elements = length - 2;
|
||||
if (elements > 4)
|
||||
SPIRV_CROSS_THROW("OpConstantComposite only supports 1, 2, 3 and 4 elements.");
|
||||
|
||||
const SPIRConstant *c[4];
|
||||
for (uint32_t i = 0; i < components; i++)
|
||||
for (uint32_t i = 0; i < elements; i++)
|
||||
c[i] = &get<SPIRConstant>(ops[2 + i]);
|
||||
set<SPIRConstant>(id, type, c, components, op == OpSpecConstantComposite);
|
||||
set<SPIRConstant>(id, type, c, elements, op == OpSpecConstantComposite);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
101
spirv_glsl.cpp
101
spirv_glsl.cpp
@ -1342,8 +1342,16 @@ void CompilerGLSL::emit_specialization_constant(const SPIRConstant &constant)
|
||||
auto &type = get<SPIRType>(constant.constant_type);
|
||||
auto name = to_name(constant.self);
|
||||
|
||||
statement("layout(constant_id = ", get_decoration(constant.self, DecorationSpecId), ") const ",
|
||||
variable_decl(type, name), " = ", constant_expression(constant), ";");
|
||||
// Only scalars have constant IDs.
|
||||
if (has_decoration(constant.self, DecorationSpecId))
|
||||
{
|
||||
statement("layout(constant_id = ", get_decoration(constant.self, DecorationSpecId), ") const ",
|
||||
variable_decl(type, name), " = ", constant_expression(constant), ";");
|
||||
}
|
||||
else
|
||||
{
|
||||
statement("const ", variable_decl(type, name), " = ", constant_expression(constant), ";");
|
||||
}
|
||||
}
|
||||
|
||||
void CompilerGLSL::replace_illegal_names()
|
||||
@ -2169,7 +2177,11 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c)
|
||||
string res = type_to_glsl(get<SPIRType>(c.constant_type)) + "(";
|
||||
for (uint32_t col = 0; col < c.columns(); col++)
|
||||
{
|
||||
res += constant_expression_vector(c, col);
|
||||
if (options.vulkan_semantics && c.specialization_constant_id(col) != 0)
|
||||
res += to_name(c.specialization_constant_id(col));
|
||||
else
|
||||
res += constant_expression_vector(c, col);
|
||||
|
||||
if (col + 1 < c.columns())
|
||||
res += ", ";
|
||||
}
|
||||
@ -2188,6 +2200,20 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
res += type_to_glsl(type) + "(";
|
||||
|
||||
bool splat = backend.use_constructor_splatting && c.vector_size() > 1;
|
||||
|
||||
if (splat)
|
||||
{
|
||||
// Cannot use constant splatting if we have specialization constants somewhere in the vector.
|
||||
for (uint32_t i = 0; i < c.vector_size(); i++)
|
||||
{
|
||||
if (options.vulkan_semantics && c.specialization_constant_id(vector, i) != 0)
|
||||
{
|
||||
splat = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (splat)
|
||||
{
|
||||
if (type_to_std430_base_size(type) == 8)
|
||||
@ -2219,7 +2245,11 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < c.vector_size(); i++)
|
||||
{
|
||||
res += convert_to_string(c.scalar_f32(vector, i));
|
||||
if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
res += convert_to_string(c.scalar_f32(vector, i));
|
||||
|
||||
if (backend.float_literal_suffix)
|
||||
res += "f";
|
||||
if (i + 1 < c.vector_size())
|
||||
@ -2239,9 +2269,15 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < c.vector_size(); i++)
|
||||
{
|
||||
res += convert_to_string(c.scalar_f64(vector, i));
|
||||
if (backend.double_literal_suffix)
|
||||
res += "lf";
|
||||
if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
{
|
||||
res += convert_to_string(c.scalar_f64(vector, i));
|
||||
if (backend.double_literal_suffix)
|
||||
res += "lf";
|
||||
}
|
||||
|
||||
if (i + 1 < c.vector_size())
|
||||
res += ", ";
|
||||
}
|
||||
@ -2261,11 +2297,17 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < c.vector_size(); i++)
|
||||
{
|
||||
res += convert_to_string(c.scalar_i64(vector, i));
|
||||
if (backend.long_long_literal_suffix)
|
||||
res += "ll";
|
||||
if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
res += "l";
|
||||
{
|
||||
res += convert_to_string(c.scalar_i64(vector, i));
|
||||
if (backend.long_long_literal_suffix)
|
||||
res += "ll";
|
||||
else
|
||||
res += "l";
|
||||
}
|
||||
|
||||
if (i + 1 < c.vector_size())
|
||||
res += ", ";
|
||||
}
|
||||
@ -2285,11 +2327,17 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < c.vector_size(); i++)
|
||||
{
|
||||
res += convert_to_string(c.scalar_u64(vector, i));
|
||||
if (backend.long_long_literal_suffix)
|
||||
res += "ull";
|
||||
if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
res += "ul";
|
||||
{
|
||||
res += convert_to_string(c.scalar_u64(vector, i));
|
||||
if (backend.long_long_literal_suffix)
|
||||
res += "ull";
|
||||
else
|
||||
res += "ul";
|
||||
}
|
||||
|
||||
if (i + 1 < c.vector_size())
|
||||
res += ", ";
|
||||
}
|
||||
@ -2307,9 +2355,15 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < c.vector_size(); i++)
|
||||
{
|
||||
res += convert_to_string(c.scalar(vector, i));
|
||||
if (backend.uint32_t_literal_suffix)
|
||||
res += "u";
|
||||
if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
{
|
||||
res += convert_to_string(c.scalar(vector, i));
|
||||
if (backend.uint32_t_literal_suffix)
|
||||
res += "u";
|
||||
}
|
||||
|
||||
if (i + 1 < c.vector_size())
|
||||
res += ", ";
|
||||
}
|
||||
@ -2323,7 +2377,10 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < c.vector_size(); i++)
|
||||
{
|
||||
res += convert_to_string(c.scalar_i32(vector, i));
|
||||
if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
res += convert_to_string(c.scalar_i32(vector, i));
|
||||
if (i + 1 < c.vector_size())
|
||||
res += ", ";
|
||||
}
|
||||
@ -2337,7 +2394,11 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
||||
{
|
||||
for (uint32_t i = 0; i < c.vector_size(); i++)
|
||||
{
|
||||
res += c.scalar(vector, i) ? "true" : "false";
|
||||
if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
res += c.scalar(vector, i) ? "true" : "false";
|
||||
|
||||
if (i + 1 < c.vector_size())
|
||||
res += ", ";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user