MSL: Re-roll array expressions in initializers.
We cannot rely on copy path when using an array as part of a struct initializer, so reroll such expressions to an initializer list again.
This commit is contained in:
parent
53ab2144b9
commit
f6f849397e
@ -73,17 +73,11 @@ kernel void main0(device BUF& o [[buffer(0)]])
|
|||||||
o.a = int(c[1][1][1]);
|
o.a = int(c[1][1][1]);
|
||||||
float _43[2] = { o.b, o.c };
|
float _43[2] = { o.b, o.c };
|
||||||
float _48[2] = { o.b, o.b };
|
float _48[2] = { o.b, o.b };
|
||||||
float _49[2][2];
|
float _49[2][2] = { { _43[0], _43[1] }, { _48[0], _48[1] } };
|
||||||
spvArrayCopyFromStack1(_49[0], _43);
|
|
||||||
spvArrayCopyFromStack1(_49[1], _48);
|
|
||||||
float _54[2] = { o.c, o.c };
|
float _54[2] = { o.c, o.c };
|
||||||
float _59[2] = { o.c, o.b };
|
float _59[2] = { o.c, o.b };
|
||||||
float _60[2][2];
|
float _60[2][2] = { { _54[0], _54[1] }, { _59[0], _59[1] } };
|
||||||
spvArrayCopyFromStack1(_60[0], _54);
|
float _61[2][2][2] = { { { _49[0][0], _49[0][1] }, { _49[1][0], _49[1][1] } }, { { _60[0][0], _60[0][1] }, { _60[1][0], _60[1][1] } } };
|
||||||
spvArrayCopyFromStack1(_60[1], _59);
|
|
||||||
float _61[2][2][2];
|
|
||||||
spvArrayCopyFromStack2(_61[0], _49);
|
|
||||||
spvArrayCopyFromStack2(_61[1], _60);
|
|
||||||
float d[2][2][2];
|
float d[2][2][2];
|
||||||
spvArrayCopyFromStack3(d, _61);
|
spvArrayCopyFromStack3(d, _61);
|
||||||
float e[2][2][2];
|
float e[2][2][2];
|
||||||
|
@ -2886,6 +2886,49 @@ string CompilerGLSL::to_extract_component_expression(uint32_t id, uint32_t index
|
|||||||
return join(expr, ".", index_to_swizzle(index));
|
return join(expr, ".", index_to_swizzle(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string CompilerGLSL::to_rerolled_array_expression(const string &base_expr, const SPIRType &type)
|
||||||
|
{
|
||||||
|
uint32_t size = to_array_size_literal(type);
|
||||||
|
auto &parent = get<SPIRType>(type.parent_type);
|
||||||
|
string expr = "{ ";
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
auto subexpr = join(base_expr, "[", convert_to_string(i), "]");
|
||||||
|
if (parent.array.empty())
|
||||||
|
expr += subexpr;
|
||||||
|
else
|
||||||
|
expr += to_rerolled_array_expression(subexpr, parent);
|
||||||
|
|
||||||
|
if (i + 1 < size)
|
||||||
|
expr += ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
expr += " }";
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
string CompilerGLSL::to_composite_constructor_expression(uint32_t id)
|
||||||
|
{
|
||||||
|
auto &type = expression_type(id);
|
||||||
|
if (!backend.array_is_value_type && !type.array.empty())
|
||||||
|
{
|
||||||
|
// For this case, we need to "re-roll" an array initializer from a temporary.
|
||||||
|
// We cannot simply pass the array directly, since it decays to a pointer and it cannot
|
||||||
|
// participate in a struct initializer. E.g.
|
||||||
|
// float arr[2] = { 1.0, 2.0 };
|
||||||
|
// Foo foo = { arr }; must be transformed to
|
||||||
|
// Foo foo = { { arr[0], arr[1] } };
|
||||||
|
// The array sizes cannot be deduced from specialization constants since we cannot use any loops.
|
||||||
|
|
||||||
|
// We're only triggering one read of the array expression, but this is fine since arrays have to be declared
|
||||||
|
// as temporaries anyways.
|
||||||
|
return to_rerolled_array_expression(to_enclosed_expression(id), type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return to_expression(id);
|
||||||
|
}
|
||||||
|
|
||||||
string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read)
|
string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read)
|
||||||
{
|
{
|
||||||
auto itr = invalid_expressions.find(id);
|
auto itr = invalid_expressions.find(id);
|
||||||
@ -7302,7 +7345,7 @@ string CompilerGLSL::build_composite_combiner(uint32_t return_type, const uint32
|
|||||||
|
|
||||||
if (i)
|
if (i)
|
||||||
op += ", ";
|
op += ", ";
|
||||||
subop = to_expression(elems[i]);
|
subop = to_composite_constructor_expression(elems[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
base = e ? e->base_expression : 0;
|
base = e ? e->base_expression : 0;
|
||||||
@ -7858,15 +7901,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
|
|||||||
forward = false;
|
forward = false;
|
||||||
|
|
||||||
string constructor_op;
|
string constructor_op;
|
||||||
if (!backend.array_is_value_type && out_type.array.size() > 1)
|
if (backend.use_initializer_list && composite)
|
||||||
{
|
|
||||||
// We cannot construct array of arrays because we cannot treat the inputs
|
|
||||||
// as value types. Need to declare the array-of-arrays, and copy in elements one by one.
|
|
||||||
emit_uninitialized_temporary_expression(result_type, id);
|
|
||||||
for (uint32_t i = 0; i < length; i++)
|
|
||||||
emit_array_copy(join(to_expression(id), "[", i, "]"), elems[i]);
|
|
||||||
}
|
|
||||||
else if (backend.use_initializer_list && composite)
|
|
||||||
{
|
{
|
||||||
// Only use this path if we are building composites.
|
// Only use this path if we are building composites.
|
||||||
// This path cannot be used for arithmetic.
|
// This path cannot be used for arithmetic.
|
||||||
|
@ -502,6 +502,8 @@ protected:
|
|||||||
SPIRExpression &emit_uninitialized_temporary_expression(uint32_t type, uint32_t id);
|
SPIRExpression &emit_uninitialized_temporary_expression(uint32_t type, uint32_t id);
|
||||||
void append_global_func_args(const SPIRFunction &func, uint32_t index, SmallVector<std::string> &arglist);
|
void append_global_func_args(const SPIRFunction &func, uint32_t index, SmallVector<std::string> &arglist);
|
||||||
std::string to_expression(uint32_t id, bool register_expression_read = true);
|
std::string to_expression(uint32_t id, bool register_expression_read = true);
|
||||||
|
std::string to_composite_constructor_expression(uint32_t id);
|
||||||
|
std::string to_rerolled_array_expression(const std::string &expr, const SPIRType &type);
|
||||||
std::string to_enclosed_expression(uint32_t id, bool register_expression_read = true);
|
std::string to_enclosed_expression(uint32_t id, bool register_expression_read = true);
|
||||||
std::string to_unpacked_expression(uint32_t id, bool register_expression_read = true);
|
std::string to_unpacked_expression(uint32_t id, bool register_expression_read = true);
|
||||||
std::string to_enclosed_unpacked_expression(uint32_t id, bool register_expression_read = true);
|
std::string to_enclosed_unpacked_expression(uint32_t id, bool register_expression_read = true);
|
||||||
|
@ -8691,14 +8691,6 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o
|
|||||||
return SPVFuncImplTextureSwizzle;
|
return SPVFuncImplTextureSwizzle;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpCompositeConstruct:
|
|
||||||
{
|
|
||||||
auto &type = compiler.get<SPIRType>(args[0]);
|
|
||||||
if (type.array.size() > 1) // We need to use copies to build the composite.
|
|
||||||
return static_cast<SPVFuncImpl>(SPVFuncImplArrayCopyMultidimBase + type.array.size() - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case OpExtInst:
|
case OpExtInst:
|
||||||
{
|
{
|
||||||
uint32_t extension_set = args[2];
|
uint32_t extension_set = args[2];
|
||||||
|
Loading…
Reference in New Issue
Block a user