MSL: Enable proper value types for return and value-passing of arrays.
Now that we have spvUnsafeArray<T> there is no need to deal with these special purpose cases.
This commit is contained in:
parent
4ac12594c9
commit
a82ecbeba9
@ -58,7 +58,7 @@ struct main0_in
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float4 consume_constant_arrays2(thread const spvUnsafeArray<float4, 4> (&positions), thread const spvUnsafeArray<float4, 4> (&positions2), thread int& Index1, thread int& Index2)
|
||||
float4 consume_constant_arrays2(spvUnsafeArray<float4, 4> positions, spvUnsafeArray<float4, 4> positions2, thread int& Index1, thread int& Index2)
|
||||
{
|
||||
spvUnsafeArray<float4, 4> indexable;
|
||||
indexable = positions;
|
||||
@ -68,7 +68,7 @@ float4 consume_constant_arrays2(thread const spvUnsafeArray<float4, 4> (&positio
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
float4 consume_constant_arrays(thread const spvUnsafeArray<float4, 4> (&positions), thread const spvUnsafeArray<float4, 4> (&positions2), thread int& Index1, thread int& Index2)
|
||||
float4 consume_constant_arrays(spvUnsafeArray<float4, 4> positions, spvUnsafeArray<float4, 4> positions2, thread int& Index1, thread int& Index2)
|
||||
{
|
||||
return consume_constant_arrays2(positions, positions2, Index1, Index2);
|
||||
}
|
||||
|
@ -58,28 +58,24 @@ struct main0_in
|
||||
};
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void test(thread spvUnsafeArray<float4, 2> (&SPIRV_Cross_return_value))
|
||||
spvUnsafeArray<float4, 2> test()
|
||||
{
|
||||
SPIRV_Cross_return_value = _20;
|
||||
return _20;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline))
|
||||
void test2(thread spvUnsafeArray<float4, 2> (&SPIRV_Cross_return_value), thread float4& vInput0, thread float4& vInput1)
|
||||
spvUnsafeArray<float4, 2> test2(thread float4& vInput0, thread float4& vInput1)
|
||||
{
|
||||
spvUnsafeArray<float4, 2> foobar;
|
||||
foobar[0] = vInput0;
|
||||
foobar[1] = vInput1;
|
||||
SPIRV_Cross_return_value = foobar;
|
||||
return foobar;
|
||||
}
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]])
|
||||
{
|
||||
main0_out out = {};
|
||||
spvUnsafeArray<float4, 2> _42;
|
||||
test(_42);
|
||||
spvUnsafeArray<float4, 2> _44;
|
||||
test2(_44, in.vInput0, in.vInput1);
|
||||
out.gl_Position = _42[0] + _44[1];
|
||||
out.gl_Position = test()[0] + test2(in.vInput0, in.vInput1)[1];
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -982,7 +982,7 @@ string CompilerMSL::compile()
|
||||
backend.native_row_major_matrix = false;
|
||||
backend.unsized_array_supported = false;
|
||||
backend.can_declare_arrays_inline = false;
|
||||
backend.can_return_array = false;
|
||||
backend.can_return_array = true; // <-- Allow Metal to use the array<T> template
|
||||
backend.allow_truncated_access_chain = true;
|
||||
backend.array_is_value_type = true; // <-- Allow Metal to use the array<T> template to make arrays a value type
|
||||
backend.comparison_image_samples_scalar = true;
|
||||
@ -6765,31 +6765,11 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &)
|
||||
|
||||
auto &type = get<SPIRType>(func.return_type);
|
||||
|
||||
if (type.array.empty())
|
||||
{
|
||||
decl += func_type_decl(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We cannot return arrays in MSL, so "return" through an out variable.
|
||||
decl += "void";
|
||||
}
|
||||
|
||||
decl += func_type_decl(type);
|
||||
decl += " ";
|
||||
decl += to_name(func.self);
|
||||
decl += "(";
|
||||
|
||||
if (!type.array.empty())
|
||||
{
|
||||
// Fake arrays returns by writing to an out array instead.
|
||||
decl += "thread ";
|
||||
decl += type_to_glsl(type);
|
||||
decl += " (&SPIRV_Cross_return_value)";
|
||||
decl += type_to_array_glsl(type);
|
||||
if (!func.arguments.empty())
|
||||
decl += ", ";
|
||||
}
|
||||
|
||||
if (processing_entry_point)
|
||||
{
|
||||
if (msl_options.argument_buffers)
|
||||
@ -9586,34 +9566,10 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg)
|
||||
(storage == StorageClassFunction || storage == StorageClassGeneric))
|
||||
{
|
||||
// If the argument is a pure value and not an opaque type, we will pass by value.
|
||||
if (is_array(type))
|
||||
{
|
||||
// We are receiving an array by value. This is problematic.
|
||||
// We cannot be sure of the target address space since we are supposed to receive a copy,
|
||||
// but this is not possible with MSL without some extra work.
|
||||
// We will have to assume we're getting a reference in thread address space.
|
||||
// If we happen to get a reference in constant address space, the caller must emit a copy and pass that.
|
||||
// Thread const therefore becomes the only logical choice, since we cannot "create" a constant array from
|
||||
// non-constant arrays, but we can create thread const from constant.
|
||||
decl = string("thread const ") + decl;
|
||||
decl += " (&";
|
||||
const char *restrict_kw = to_restrict(name_id);
|
||||
if (*restrict_kw)
|
||||
{
|
||||
decl += " ";
|
||||
decl += restrict_kw;
|
||||
}
|
||||
decl += to_expression(name_id);
|
||||
decl += ")";
|
||||
decl += type_to_array_glsl(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!address_space.empty())
|
||||
decl = join(address_space, " ", decl);
|
||||
decl += " ";
|
||||
decl += to_expression(name_id);
|
||||
}
|
||||
if (!address_space.empty())
|
||||
decl = join(address_space, " ", decl);
|
||||
decl += " ";
|
||||
decl += to_expression(name_id);
|
||||
}
|
||||
else if (is_array(type) && !type_is_image)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user