MSL: Start considering float[] and float2[] in std140 layout.
This commit is contained in:
parent
9e3a41ad00
commit
64ca1ec677
@ -515,7 +515,7 @@ bool Compiler::is_member_builtin(const SPIRType &type, uint32_t index, BuiltIn *
|
|||||||
|
|
||||||
bool Compiler::is_scalar(const SPIRType &type) const
|
bool Compiler::is_scalar(const SPIRType &type) const
|
||||||
{
|
{
|
||||||
return type.vecsize == 1 && type.columns == 1;
|
return type.basetype != SPIRType::Struct && type.vecsize == 1 && type.columns == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compiler::is_vector(const SPIRType &type) const
|
bool Compiler::is_vector(const SPIRType &type) const
|
||||||
|
@ -1585,6 +1585,27 @@ bool CompilerMSL::is_member_packable(SPIRType &ib_type, uint32_t index)
|
|||||||
|
|
||||||
auto &mbr_type = get<SPIRType>(ib_type.member_types[index]);
|
auto &mbr_type = get<SPIRType>(ib_type.member_types[index]);
|
||||||
|
|
||||||
|
uint32_t component_size = mbr_type.width / 8;
|
||||||
|
uint32_t unpacked_mbr_size;
|
||||||
|
if (mbr_type.vecsize == 3)
|
||||||
|
unpacked_mbr_size = component_size * (mbr_type.vecsize + 1) * mbr_type.columns;
|
||||||
|
else
|
||||||
|
unpacked_mbr_size = component_size * mbr_type.vecsize * mbr_type.columns;
|
||||||
|
|
||||||
|
// Special case for packing. Check for float[] or vec2[] in std140 layout. Here we actually need to pad out instead,
|
||||||
|
// but we will use the same mechanism as before.
|
||||||
|
if (is_array(mbr_type) &&
|
||||||
|
(is_scalar(mbr_type) || is_vector(mbr_type)) &&
|
||||||
|
mbr_type.vecsize <= 2 &&
|
||||||
|
type_struct_member_array_stride(ib_type, index) == 4 * component_size)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Another sanity check for matrices. We currently do not support std140 matrices which need to be padded out per column.
|
||||||
|
//if (is_matrix(mbr_type) && mbr_type.vecsize <= 2 && type_struct_member_matrix_stride(ib_type, index) == 16)
|
||||||
|
// SPIRV_CROSS_THROW("Currently cannot support matrices with small vector size in std140 layout.");
|
||||||
|
|
||||||
// Only vectors or 3-row matrices need to be packed.
|
// Only vectors or 3-row matrices need to be packed.
|
||||||
if (mbr_type.vecsize == 1 || (is_matrix(mbr_type) && mbr_type.vecsize != 3))
|
if (mbr_type.vecsize == 1 || (is_matrix(mbr_type) && mbr_type.vecsize != 3))
|
||||||
return false;
|
return false;
|
||||||
@ -1593,12 +1614,6 @@ bool CompilerMSL::is_member_packable(SPIRType &ib_type, uint32_t index)
|
|||||||
if (is_matrix(mbr_type) && !has_member_decoration(ib_type.self, index, DecorationRowMajor))
|
if (is_matrix(mbr_type) && !has_member_decoration(ib_type.self, index, DecorationRowMajor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32_t component_size = mbr_type.width / 8;
|
|
||||||
uint32_t unpacked_mbr_size;
|
|
||||||
if (mbr_type.vecsize == 3)
|
|
||||||
unpacked_mbr_size = component_size * (mbr_type.vecsize + 1) * mbr_type.columns;
|
|
||||||
else
|
|
||||||
unpacked_mbr_size = component_size * mbr_type.vecsize * mbr_type.columns;
|
|
||||||
if (is_array(mbr_type))
|
if (is_array(mbr_type))
|
||||||
{
|
{
|
||||||
// If member is an array, and the array stride is larger than the type needs, don't pack it.
|
// If member is an array, and the array stride is larger than the type needs, don't pack it.
|
||||||
@ -1644,7 +1659,13 @@ MSLStructMemberKey CompilerMSL::get_struct_member_key(uint32_t type_id, uint32_t
|
|||||||
// by wrapping the expression in a constructor of the appropriate type.
|
// by wrapping the expression in a constructor of the appropriate type.
|
||||||
string CompilerMSL::unpack_expression_type(string expr_str, const SPIRType &type)
|
string CompilerMSL::unpack_expression_type(string expr_str, const SPIRType &type)
|
||||||
{
|
{
|
||||||
return join(type_to_glsl(type), "(", expr_str, ")");
|
// float[] and float2[] cases are really just padding, so directly swizzle from the backing float4 instead.
|
||||||
|
if (is_scalar(type))
|
||||||
|
return enclose_expression(expr_str) + ".x";
|
||||||
|
else if (is_vector(type) && type.vecsize == 2)
|
||||||
|
return enclose_expression(expr_str) + ".xy";
|
||||||
|
else
|
||||||
|
return join(type_to_glsl(type), "(", expr_str, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emits the file header info
|
// Emits the file header info
|
||||||
@ -3964,13 +3985,16 @@ void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_
|
|||||||
|
|
||||||
// If this member is packed, mark it as so.
|
// If this member is packed, mark it as so.
|
||||||
string pack_pfx = "";
|
string pack_pfx = "";
|
||||||
|
|
||||||
|
const SPIRType *effective_membertype = &membertype;
|
||||||
|
SPIRType override_type;
|
||||||
|
|
||||||
if (member_is_packed_type(type, index))
|
if (member_is_packed_type(type, index))
|
||||||
{
|
{
|
||||||
pack_pfx = "packed_";
|
|
||||||
|
|
||||||
// If we're packing a matrix, output an appropriate typedef
|
// If we're packing a matrix, output an appropriate typedef
|
||||||
if (membertype.vecsize > 1 && membertype.columns > 1)
|
if (membertype.vecsize > 1 && membertype.columns > 1)
|
||||||
{
|
{
|
||||||
|
pack_pfx = "packed_";
|
||||||
string base_type = membertype.width == 16 ? "half" : "float";
|
string base_type = membertype.width == 16 ? "half" : "float";
|
||||||
string td_line = "typedef ";
|
string td_line = "typedef ";
|
||||||
td_line += base_type + to_string(membertype.vecsize) + "x" + to_string(membertype.columns);
|
td_line += base_type + to_string(membertype.vecsize) + "x" + to_string(membertype.columns);
|
||||||
@ -3979,10 +4003,19 @@ void CompilerMSL::emit_struct_member(const SPIRType &type, uint32_t member_type_
|
|||||||
td_line += ";";
|
td_line += ";";
|
||||||
add_typedef_line(td_line);
|
add_typedef_line(td_line);
|
||||||
}
|
}
|
||||||
|
else if (membertype.vecsize <= 2 && membertype.basetype != SPIRType::Struct)
|
||||||
|
{
|
||||||
|
// A "packed" float array, but we pad here instead to 4-vector.
|
||||||
|
override_type = membertype;
|
||||||
|
override_type.vecsize = 4;
|
||||||
|
effective_membertype = &override_type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pack_pfx = "packed_";
|
||||||
}
|
}
|
||||||
|
|
||||||
statement(pack_pfx, type_to_glsl(membertype), " ", qualifier, to_member_name(type, index),
|
statement(pack_pfx, type_to_glsl(*effective_membertype), " ", qualifier, to_member_name(type, index),
|
||||||
member_attribute_qualifier(type, index), type_to_array_glsl(membertype), ";");
|
member_attribute_qualifier(type, index), type_to_array_glsl(*effective_membertype), ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a MSL qualifier for the specified function attribute member
|
// Return a MSL qualifier for the specified function attribute member
|
||||||
|
Loading…
Reference in New Issue
Block a user