Refactor out packed expressions to extended decorations.

Can't safely just cast to the original enum without lots of hacks.
This commit is contained in:
Hans-Kristian Arntzen 2019-01-17 11:22:24 +01:00
parent 72377366d3
commit de7e5ccd8b
8 changed files with 231 additions and 55 deletions

View File

@ -17,6 +17,6 @@ kernel void main0(device foo& _8 [[buffer(0)]], uint3 gl_LocalInvocationID [[thr
_8.bar = gl_LocalInvocationID.x;
_8.baz = float3(gl_GlobalInvocationID);
_8.blah = uchar4(uint4(uint4(uchar4(_8.blah)).xyz + gl_WorkGroupID, 0u));
_8.wibble.xy = half2(float2(_8.wibble.xy) * float2(gl_NumWorkGroups.xy));
_8.wibble = half2(float2(_8.wibble.xy) * float2(gl_NumWorkGroups.xy));
}

View File

@ -17,6 +17,6 @@ kernel void main0(device foo& _8 [[buffer(0)]], uint3 gl_LocalInvocationID [[thr
_8.bar = gl_LocalInvocationID.x;
_8.baz = float3(gl_GlobalInvocationID);
_8.blah = uchar4(uint4(uint4(uchar4(_8.blah)).xyz + gl_WorkGroupID, 0u));
_8.wibble.xy = half2(float2(_8.wibble.xy) * float2(gl_NumWorkGroups.xy));
_8.wibble = half2(float2(_8.wibble.xy) * float2(gl_NumWorkGroups.xy));
}

View File

@ -1339,9 +1339,9 @@ T &variant_set(Variant &var, P &&... args)
struct AccessChainMeta
{
uint32_t storage_packed_type = 0;
bool need_transpose = false;
bool storage_is_packed = false;
bool storage_is_packed_on_store = false;
bool storage_is_invariant = false;
};
@ -1366,6 +1366,12 @@ struct Meta
uint32_t index = 0;
spv::FPRoundingMode fp_rounding_mode = spv::FPRoundingModeMax;
bool builtin = false;
struct
{
uint32_t packed_type = 0;
bool packed = false;
} extended;
};
Decoration decoration;

View File

@ -169,7 +169,7 @@ string Compiler::to_name(uint32_t id, bool allow_alias) const
{
// If the alias master has been specially packed, we will have emitted a clean variant as well,
// so skip the name aliasing here.
if (!has_decoration(type.type_alias, SPIRV_CROSS_DECORATION_PACKED))
if (!has_extended_decoration(type.type_alias, SPIRVCrossDecorationPacked))
return to_name(type.type_alias);
}
}
@ -868,7 +868,7 @@ void Compiler::fixup_type_alias()
for (auto alias_itr = begin(type_ids); alias_itr != end(type_ids); ++alias_itr)
{
auto &type = get<SPIRType>(*alias_itr);
if (type.type_alias != 0 && !has_decoration(type.type_alias, SPIRV_CROSS_DECORATION_PACKED))
if (type.type_alias != 0 && !has_extended_decoration(type.type_alias, SPIRVCrossDecorationPacked))
{
// We will skip declaring this type, so make sure the type_alias type comes before.
auto master_itr = find(begin(type_ids), end(type_ids), type.type_alias);
@ -1165,6 +1165,152 @@ void Compiler::set_decoration(uint32_t id, Decoration decoration, uint32_t argum
ir.set_decoration(id, decoration, argument);
}
void Compiler::set_extended_decoration(uint32_t id, ExtendedDecorations decoration, uint32_t value)
{
auto &dec = ir.meta[id].decoration;
switch (decoration)
{
case SPIRVCrossDecorationPacked:
dec.extended.packed = true;
break;
case SPIRVCrossDecorationPackedType:
dec.extended.packed_type = value;
break;
}
}
void Compiler::set_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration, uint32_t value)
{
ir.meta[type].members.resize(max(ir.meta[type].members.size(), size_t(index) + 1));
auto &dec = ir.meta[type].members[index];
switch (decoration)
{
case SPIRVCrossDecorationPacked:
dec.extended.packed = true;
break;
case SPIRVCrossDecorationPackedType:
dec.extended.packed_type = value;
break;
}
}
uint32_t Compiler::get_extended_decoration(uint32_t id, ExtendedDecorations decoration) const
{
auto *m = ir.find_meta(id);
if (!m)
return 0;
auto &dec = m->decoration;
switch (decoration)
{
case SPIRVCrossDecorationPacked:
return uint32_t(dec.extended.packed);
case SPIRVCrossDecorationPackedType:
return dec.extended.packed_type;
}
return 0;
}
uint32_t Compiler::get_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration) const
{
auto *m = ir.find_meta(type);
if (!m)
return 0;
if (index >= m->members.size())
return 0;
auto &dec = m->members[index];
switch (decoration)
{
case SPIRVCrossDecorationPacked:
return uint32_t(dec.extended.packed);
case SPIRVCrossDecorationPackedType:
return dec.extended.packed_type;
}
return 0;
}
bool Compiler::has_extended_decoration(uint32_t id, ExtendedDecorations decoration) const
{
auto *m = ir.find_meta(id);
if (!m)
return false;
auto &dec = m->decoration;
switch (decoration)
{
case SPIRVCrossDecorationPacked:
return dec.extended.packed;
case SPIRVCrossDecorationPackedType:
return dec.extended.packed_type != 0;
}
return false;
}
bool Compiler::has_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration) const
{
auto *m = ir.find_meta(type);
if (!m)
return false;
if (index >= m->members.size())
return false;
auto &dec = m->members[index];
switch (decoration)
{
case SPIRVCrossDecorationPacked:
return dec.extended.packed;
case SPIRVCrossDecorationPackedType:
return dec.extended.packed_type != 0;
}
return false;
}
void Compiler::unset_extended_decoration(uint32_t id, ExtendedDecorations decoration)
{
auto &dec = ir.meta[id].decoration;
switch (decoration)
{
case SPIRVCrossDecorationPacked:
dec.extended.packed = false;
break;
case SPIRVCrossDecorationPackedType:
dec.extended.packed_type = 0;
break;
}
}
void Compiler::unset_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration)
{
ir.meta[type].members.resize(max(ir.meta[type].members.size(), size_t(index) + 1));
auto &dec = ir.meta[type].members[index];
switch (decoration)
{
case SPIRVCrossDecorationPacked:
dec.extended.packed = false;
break;
case SPIRVCrossDecorationPackedType:
dec.extended.packed_type = 0;
break;
}
}
StorageClass Compiler::get_storage_class(uint32_t id) const
{
return get<SPIRVariable>(id).storage;

View File

@ -108,22 +108,18 @@ enum BufferPackingStandard
BufferPackingHLSLCbufferPackOffset
};
// Decoration used internally to track various meta-data.
enum CustomDecorations
{
SPIRVCrossPackedExpression = 10000000,
SPIRVCrossUnpackExpressionOnStore = 10000001,
};
#define SPIRV_CROSS_DECORATION_PACKED static_cast<spv::Decoration>(SPIRVCrossPackedExpression)
#define SPIRV_CROSS_UNPACK_EXPRESSION_ON_STORE static_cast<spv::Decoration>(SPIRVCrossUnpackExpressionOnStore)
struct EntryPoint
{
std::string name;
spv::ExecutionModel execution_model;
};
enum ExtendedDecorations
{
SPIRVCrossDecorationPacked,
SPIRVCrossDecorationPackedType
};
class Compiler
{
public:
@ -956,6 +952,16 @@ protected:
bool image_is_comparison(const SPIRType &type, uint32_t id) const;
void set_extended_decoration(uint32_t id, ExtendedDecorations decoration, uint32_t value = 0);
uint32_t get_extended_decoration(uint32_t id, ExtendedDecorations decoration) const;
bool has_extended_decoration(uint32_t id, ExtendedDecorations decoration) const;
void unset_extended_decoration(uint32_t id, ExtendedDecorations decoration);
void set_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration, uint32_t value = 0);
uint32_t get_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration) const;
bool has_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration) const;
void unset_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration);
private:
// Used only to implement the old deprecated get_entry_point() interface.
const SPIREntryPoint &get_first_entry_point(const std::string &name) const;

View File

@ -696,7 +696,7 @@ void CompilerGLSL::emit_struct(SPIRType &type)
// Type-punning with these types is legal, which complicates things
// when we are storing struct and array types in an SSBO for example.
// If the type master is packed however, we can no longer assume that the struct declaration will be redundant.
if (type.type_alias != 0 && !has_decoration(type.type_alias, SPIRV_CROSS_DECORATION_PACKED))
if (type.type_alias != 0 && !has_extended_decoration(type.type_alias, SPIRVCrossDecorationPacked))
return;
add_resource_name(type.self);
@ -810,9 +810,9 @@ string CompilerGLSL::layout_for_member(const SPIRType &type, uint32_t index)
SPIRV_CROSS_THROW("Component decoration is not supported in ES targets.");
}
// SPIRV_CROSS_DECORATION_PACKED is set by layout_for_variable earlier to mark that we need to emit offset qualifiers.
// SPIRVCrossDecorationPacked is set by layout_for_variable earlier to mark that we need to emit offset qualifiers.
// This is only done selectively in GLSL as needed.
if (has_decoration(type.self, SPIRV_CROSS_DECORATION_PACKED) && dec.decoration_flags.get(DecorationOffset))
if (has_extended_decoration(type.self, SPIRVCrossDecorationPacked) && dec.decoration_flags.get(DecorationOffset))
attr.push_back(join("offset = ", dec.offset));
if (attr.empty())
@ -1370,7 +1370,7 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
// layout_for_variable() will be called before the actual buffer emit.
// The alternative is a full pass before codegen where we deduce this decoration,
// but then we are just doing the exact same work twice, and more complexity.
set_decoration(type.self, SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
}
else
{
@ -1398,7 +1398,7 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
if (!options.es && !options.vulkan_semantics && options.version < 440)
require_extension_internal("GL_ARB_enhanced_layouts");
set_decoration(type.self, SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
}
else if (buffer_is_packing_standard(type, BufferPackingStd430EnhancedLayout))
{
@ -1409,7 +1409,7 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
if (!options.es && !options.vulkan_semantics && options.version < 440)
require_extension_internal("GL_ARB_enhanced_layouts");
set_decoration(type.self, SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
}
else
{
@ -2491,7 +2491,7 @@ string CompilerGLSL::to_unpacked_expression(uint32_t id, bool register_expressio
// If we need to transpose, it will also take care of unpacking rules.
auto *e = maybe_get<SPIRExpression>(id);
bool need_transpose = e && e->need_transpose;
if (!need_transpose && has_decoration(id, SPIRV_CROSS_DECORATION_PACKED))
if (!need_transpose && has_extended_decoration(id, SPIRVCrossDecorationPacked))
return unpack_expression_type(to_expression(id, register_expression_read), expression_type(id));
else
return to_expression(id, register_expression_read);
@ -2502,7 +2502,7 @@ string CompilerGLSL::to_enclosed_unpacked_expression(uint32_t id, bool register_
// If we need to transpose, it will also take care of unpacking rules.
auto *e = maybe_get<SPIRExpression>(id);
bool need_transpose = e && e->need_transpose;
if (!need_transpose && has_decoration(id, SPIRV_CROSS_DECORATION_PACKED))
if (!need_transpose && has_extended_decoration(id, SPIRVCrossDecorationPacked))
return unpack_expression_type(to_expression(id, register_expression_read), expression_type(id));
else
return to_enclosed_expression(id, register_expression_read);
@ -2538,7 +2538,7 @@ string CompilerGLSL::to_enclosed_pointer_expression(uint32_t id, bool register_e
string CompilerGLSL::to_extract_component_expression(uint32_t id, uint32_t index)
{
auto expr = to_enclosed_expression(id);
if (has_decoration(id, SPIRV_CROSS_DECORATION_PACKED))
if (has_extended_decoration(id, SPIRVCrossDecorationPacked))
return join(expr, "[", index, "]");
else
return join(expr, ".", index_to_swizzle(index));
@ -2581,7 +2581,7 @@ string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read)
return to_enclosed_expression(e.base_expression) + e.expression;
else if (e.need_transpose)
{
bool is_packed = has_decoration(id, SPIRV_CROSS_DECORATION_PACKED);
bool is_packed = has_extended_decoration(id, SPIRVCrossDecorationPacked);
return convert_row_major_matrix(e.expression, get<SPIRType>(e.expression_type), is_packed);
}
else
@ -5502,7 +5502,8 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
bool access_chain_is_arrayed = expr.find_first_of('[') != string::npos;
bool row_major_matrix_needs_conversion = is_non_native_row_major_matrix(base);
bool is_packed = has_decoration(base, SPIRV_CROSS_DECORATION_PACKED);
bool is_packed = has_extended_decoration(base, SPIRVCrossDecorationPacked);
uint32_t packed_type = get_extended_decoration(base, SPIRVCrossDecorationPackedType);
bool is_invariant = has_decoration(base, DecorationInvariant);
bool pending_array_enclose = false;
bool dimension_flatten = false;
@ -5678,6 +5679,11 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
is_invariant = true;
is_packed = member_is_packed_type(*type, index);
if (is_packed)
packed_type = get_extended_member_decoration(type->self, index, SPIRVCrossDecorationPackedType);
else
packed_type = 0;
row_major_matrix_needs_conversion = member_is_non_native_row_major_matrix(*type, index);
type = &get<SPIRType>(type->member_types[index]);
}
@ -5689,6 +5695,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
expr = convert_row_major_matrix(expr, *type, is_packed);
row_major_matrix_needs_conversion = false;
is_packed = false;
packed_type = 0;
}
expr += "[";
@ -5728,6 +5735,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
}
is_packed = false;
packed_type = 0;
type_id = type->parent_type;
type = &get<SPIRType>(type_id);
}
@ -5747,6 +5755,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice
meta->need_transpose = row_major_matrix_needs_conversion;
meta->storage_is_packed = is_packed;
meta->storage_is_invariant = is_invariant;
meta->storage_packed_type = packed_type;
}
return expr;
@ -6711,8 +6720,12 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
register_read(id, ptr, forward);
// Pass through whether the result is of a packed type.
if (has_decoration(ptr, SPIRV_CROSS_DECORATION_PACKED))
set_decoration(id, SPIRV_CROSS_DECORATION_PACKED);
if (has_extended_decoration(ptr, SPIRVCrossDecorationPacked))
{
set_extended_decoration(id, SPIRVCrossDecorationPacked);
set_extended_decoration(id, SPIRVCrossDecorationPackedType,
get_extended_decoration(ptr, SPIRVCrossDecorationPackedType));
}
inherit_expression_dependencies(id, ptr);
if (forward)
@ -6743,14 +6756,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
// Mark the result as being packed. Some platforms handled packed vectors differently than non-packed.
if (meta.storage_is_packed)
set_decoration(ops[1], SPIRV_CROSS_DECORATION_PACKED);
else
unset_decoration(ops[1], SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(ops[1], SPIRVCrossDecorationPacked);
if (meta.storage_packed_type != 0)
set_extended_decoration(ops[1], SPIRVCrossDecorationPackedType, meta.storage_packed_type);
if (meta.storage_is_invariant)
set_decoration(ops[1], DecorationInvariant);
else
unset_decoration(ops[1], DecorationInvariant);
for (uint32_t i = 2; i < length; i++)
{
@ -7061,7 +7071,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
allow_base_expression = false;
// Packed expressions cannot be split up.
if (has_decoration(ops[2], SPIRV_CROSS_DECORATION_PACKED))
if (has_extended_decoration(ops[2], SPIRVCrossDecorationPacked))
allow_base_expression = false;
AccessChainMeta meta;
@ -7100,7 +7110,9 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
// instead of loading everything through an access chain.
e->need_transpose = meta.need_transpose;
if (meta.storage_is_packed)
set_decoration(id, SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(id, SPIRVCrossDecorationPacked);
if (meta.storage_packed_type != 0)
set_extended_decoration(id, SPIRVCrossDecorationPackedType, meta.storage_packed_type);
if (meta.storage_is_invariant)
set_decoration(id, DecorationInvariant);
@ -7188,7 +7200,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
shuffle = true;
// Cannot use swizzles with packed expressions, force shuffle path.
if (!shuffle && has_decoration(vec0, SPIRV_CROSS_DECORATION_PACKED))
if (!shuffle && has_extended_decoration(vec0, SPIRVCrossDecorationPacked))
shuffle = true;
string expr;
@ -8817,7 +8829,7 @@ bool CompilerGLSL::member_is_non_native_row_major_matrix(const SPIRType &type, u
// GLSL does not define packed data types, but certain subclasses do.
bool CompilerGLSL::member_is_packed_type(const SPIRType &type, uint32_t index) const
{
return has_member_decoration(type.self, index, SPIRV_CROSS_DECORATION_PACKED);
return has_extended_member_decoration(type.self, index, SPIRVCrossDecorationPacked);
}
// Wraps the expression string in a function call that converts the

View File

@ -1835,7 +1835,7 @@ void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type
string packing_offset;
bool is_push_constant = type.storage == StorageClassPushConstant;
if ((has_decoration(type.self, SPIRV_CROSS_DECORATION_PACKED) || is_push_constant) &&
if ((has_extended_decoration(type.self, SPIRVCrossDecorationPacked) || is_push_constant) &&
has_member_decoration(type.self, index, DecorationOffset))
{
uint32_t offset = memb[index].offset - base_offset;
@ -1870,7 +1870,7 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var)
if (type.array.empty())
{
if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset))
set_decoration(type.self, SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
else
SPIRV_CROSS_THROW("cbuffer cannot be expressed with either HLSL packing layout or packoffset.");
@ -1952,7 +1952,7 @@ void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var)
auto &type = get<SPIRType>(var.basetype);
if (buffer_is_packing_standard(type, BufferPackingHLSLCbufferPackOffset, layout.start, layout.end))
set_decoration(type.self, SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
else
SPIRV_CROSS_THROW(
"root constant cbuffer cannot be expressed with either HLSL packing layout or packoffset.");

View File

@ -757,7 +757,7 @@ void CompilerMSL::mark_as_packable(SPIRType &type)
if (type.basetype == SPIRType::Struct)
{
set_decoration(type.self, SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(type.self, SPIRVCrossDecorationPacked);
// Recurse
size_t mbr_cnt = type.member_types.size();
@ -1551,7 +1551,10 @@ void CompilerMSL::align_struct(SPIRType &ib_type)
for (uint32_t mbr_idx = 0; mbr_idx < mbr_cnt; mbr_idx++)
{
if (is_member_packable(ib_type, mbr_idx))
set_member_decoration(ib_type_id, mbr_idx, SPIRV_CROSS_DECORATION_PACKED);
{
set_extended_member_decoration(ib_type_id, mbr_idx, SPIRVCrossDecorationPacked);
set_extended_member_decoration(ib_type_id, mbr_idx, SPIRVCrossDecorationPackedType, ib_type.member_types[mbr_idx]);
}
// Align current offset to the current member's default alignment.
size_t align_mask = get_declared_struct_member_alignment(ib_type, mbr_idx) - 1;
@ -1580,7 +1583,7 @@ void CompilerMSL::align_struct(SPIRType &ib_type)
bool CompilerMSL::is_member_packable(SPIRType &ib_type, uint32_t index)
{
// We've already marked it as packable
if (has_member_decoration(ib_type.self, index, SPIRV_CROSS_DECORATION_PACKED))
if (has_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPacked))
return true;
auto &mbr_type = get<SPIRType>(ib_type.member_types[index]);
@ -1657,21 +1660,24 @@ MSLStructMemberKey CompilerMSL::get_struct_member_key(uint32_t type_id, uint32_t
void CompilerMSL::emit_store(uint32_t lhs_expression, uint32_t rhs_expression)
{
if (!has_decoration(lhs_expression, SPIRV_CROSS_DECORATION_PACKED))
if (!has_extended_decoration(lhs_expression, SPIRVCrossDecorationPacked) ||
get_extended_decoration(lhs_expression, SPIRVCrossDecorationPackedType) == 0)
{
CompilerGLSL::emit_store(lhs_expression, rhs_expression);
}
else
{
// Special handling when storing to a float[] or float2[] in std140 layout.
auto &type = expression_type(lhs_expression);
auto &type = get<SPIRType>(get_extended_decoration(lhs_expression, SPIRVCrossDecorationPackedType));
string lhs = to_dereferenced_expression(lhs_expression);
string rhs = to_pointer_expression(rhs_expression);
// Unpack the expression so we can store to it with a float or float2.
// It's still an l-value, so it's fine. Most other unpacking of expressions turn them into r-values instead.
if (is_scalar(type))
if (is_scalar(type) && is_array(type))
lhs = enclose_expression(lhs) + ".x";
else if (is_vector(type) && type.vecsize == 2)
else if (is_vector(type) && type.vecsize == 2 && is_array(type))
lhs = enclose_expression(lhs) + ".xy";
if (!optimize_read_modify_write(expression_type(rhs_expression), lhs, rhs))
@ -2376,7 +2382,7 @@ void CompilerMSL::emit_specialization_constants_and_structs()
declared_structs.insert(type_id);
if (has_decoration(type_id, SPIRV_CROSS_DECORATION_PACKED))
if (has_extended_decoration(type_id, SPIRVCrossDecorationPacked))
align_struct(type);
// Make sure we declare the underlying struct type, and not the "decorated" type with pointers, etc.
@ -2859,7 +2865,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
uint32_t mtx_id = ops[opcode == OpMatrixTimesVector ? 2 : 3];
auto *e = maybe_get<SPIRExpression>(mtx_id);
auto &t = expression_type(mtx_id);
bool is_packed = has_decoration(mtx_id, SPIRV_CROSS_DECORATION_PACKED);
bool is_packed = has_extended_decoration(mtx_id, SPIRVCrossDecorationPacked);
if (e && e->need_transpose && (t.columns == t.vecsize || is_packed))
{
e->need_transpose = false;
@ -2868,11 +2874,11 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
// are generally transposed, so unpacking using a constructor argument
// will result in an error.
// The simplest solution for now is to just avoid unpacking the matrix in this operation.
unset_decoration(mtx_id, SPIRV_CROSS_DECORATION_PACKED);
unset_extended_decoration(mtx_id, SPIRVCrossDecorationPacked);
emit_binary_op(ops[0], ops[1], ops[3], ops[2], "*");
if (is_packed)
set_decoration(mtx_id, SPIRV_CROSS_DECORATION_PACKED);
set_extended_decoration(mtx_id, SPIRVCrossDecorationPacked);
e->need_transpose = true;
}
else
@ -3905,7 +3911,7 @@ bool CompilerMSL::is_non_native_row_major_matrix(uint32_t id)
// Generate a function that will swap matrix elements from row-major to column-major.
// Packed row-matrix should just use transpose() function.
if (!has_decoration(id, SPIRV_CROSS_DECORATION_PACKED))
if (!has_extended_decoration(id, SPIRVCrossDecorationPacked))
{
const auto type = expression_type(id);
add_convert_row_major_matrix_function(type.columns, type.vecsize);
@ -3927,7 +3933,7 @@ bool CompilerMSL::member_is_non_native_row_major_matrix(const SPIRType &type, ui
// Generate a function that will swap matrix elements from row-major to column-major.
// Packed row-matrix should just use transpose() function.
if (!has_member_decoration(type.self, index, SPIRV_CROSS_DECORATION_PACKED))
if (!has_extended_member_decoration(type.self, index, SPIRVCrossDecorationPacked))
{
const auto mbr_type = get<SPIRType>(type.member_types[index]);
add_convert_row_major_matrix_function(mbr_type.columns, mbr_type.vecsize);
@ -5634,7 +5640,7 @@ size_t CompilerMSL::get_declared_struct_member_size(const SPIRType &struct_type,
uint32_t columns = type.columns;
// An unpacked 3-element vector or matrix column is the same memory size as a 4-element.
if (vecsize == 3 && !has_member_decoration(struct_type.self, index, SPIRV_CROSS_DECORATION_PACKED))
if (vecsize == 3 && !has_extended_member_decoration(struct_type.self, index, SPIRVCrossDecorationPacked))
vecsize = 4;
return component_size * vecsize * columns;