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:
parent
72377366d3
commit
de7e5ccd8b
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
150
spirv_cross.cpp
150
spirv_cross.cpp
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.");
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user