When compiling from HLSL which pads and aligns float[]/float2[] within structures to float4[] we need to unpack the original type in Metal from the float4.

This commit is contained in:
Mark Satterthwaite 2019-08-14 10:57:23 -04:00 committed by Lukas Hermanns
parent 40a4456a54
commit 9ce3158193
3 changed files with 33 additions and 2 deletions

View File

@ -528,7 +528,9 @@ protected:
std::string to_unpacked_expression(uint32_t id, bool register_expression_read = true);
std::string to_unpacked_row_major_matrix_expression(uint32_t id);
std::string to_enclosed_unpacked_expression(uint32_t id, bool register_expression_read = true);
std::string to_dereferenced_expression(uint32_t id, bool register_expression_read = true);
/* UE Change Begin: Metal expands float[]/float2[] members inside structs to float4[] so we must unpack */
virtual std::string to_dereferenced_expression(uint32_t id, bool register_expression_read = true);
/* UE Change End: Metal expands float[]/float2[] members inside structs to float4[] so we must unpack */
std::string to_pointer_expression(uint32_t id, bool register_expression_read = true);
std::string to_enclosed_pointer_expression(uint32_t id, bool register_expression_read = true);
std::string to_extract_component_expression(uint32_t id, uint32_t index);

View File

@ -3120,6 +3120,32 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp
}
}
/* UE Change Begin: Metal expands float[]/float2[] members inside structs to float4[] so we must unpack */
string CompilerMSL::to_dereferenced_expression(uint32_t id, bool register_expression_read)
{
auto &type = expression_type(id);
if (!type.pointer || !should_dereference(id))
{
uint32_t packed_type_id = get_extended_decoration(id, SPIRVCrossDecorationPhysicalTypePacked);
const SPIRType *packed_type = nullptr;
if (packed_type_id)
packed_type = &get<SPIRType>(packed_type_id);
if (packed_type && is_array(*packed_type) && is_scalar(*packed_type))
return to_unpacked_expression(id, register_expression_read);
}
return CompilerGLSL::to_dereferenced_expression(id, register_expression_read);
}
static bool expression_ends_with(string const& expr_str, std::string const& ending)
{
if (expr_str.length() >= ending.length())
return (0 == expr_str.compare(expr_str.length() - ending.length(), ending.length(), ending));
else
return false;
}
// Converts the format of the current expression from packed to unpacked,
// by wrapping the expression in a constructor of the appropriate type.
// Also, handle special physical ID remapping scenarios, similar to emit_store_statement().
@ -3141,7 +3167,7 @@ string CompilerMSL::unpack_expression_type(string expr_str, const SPIRType &type
};
// std140 array cases for vectors.
if (physical_type && is_vector(*physical_type) && is_array(*physical_type) && physical_type->vecsize > type.vecsize)
if (physical_type && is_vector(*physical_type) && is_array(*physical_type) && physical_type->vecsize > type.vecsize && !expression_ends_with(expr_str, swizzle_lut[type.vecsize - 1]))
{
assert(type.vecsize >= 1 && type.vecsize <= 3);
return enclose_expression(expr_str) + swizzle_lut[type.vecsize - 1];

View File

@ -580,6 +580,9 @@ protected:
uint32_t grad_y, uint32_t lod, uint32_t coffset, uint32_t offset, uint32_t bias,
uint32_t comp, uint32_t sample, uint32_t minlod, bool *p_forward) override;
std::string to_initializer_expression(const SPIRVariable &var) override;
/* UE Change Begin: Metal expands float[]/float2[] members inside structs to float4[] so we must unpack */
virtual std::string to_dereferenced_expression(uint32_t id, bool register_expression_read = true) override;
/* UE Change End: Metal expands float[]/float2[] members inside structs to float4[] so we must unpack */
std::string unpack_expression_type(std::string expr_str, const SPIRType &type, uint32_t physical_type_id,
bool is_packed, bool row_major) override;