diff --git a/reference/opt/shaders-msl/frag/constant-array.frag b/reference/opt/shaders-msl/frag/constant-array.frag index 0efa3b3f..9cdd5227 100644 --- a/reference/opt/shaders-msl/frag/constant-array.frag +++ b/reference/opt/shaders-msl/frag/constant-array.frag @@ -28,8 +28,15 @@ struct main0_out }; // Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopy(thread T (&dst)[N], U (&src)[N]) +template +void spvArrayCopy(thread T (&dst)[N], thread const T (&src)[N]) +{ + for (uint i = 0; i < N; dst[i] = src[i], i++); +} + +// An overload for constant arrays. +template +void spvArrayCopyConstant(thread T (&dst)[N], constant T (&src)[N]) { for (uint i = 0; i < N; dst[i] = src[i], i++); } diff --git a/reference/opt/shaders-msl/frag/constant-composites.frag b/reference/opt/shaders-msl/frag/constant-composites.frag index 317495d1..d216da6d 100644 --- a/reference/opt/shaders-msl/frag/constant-composites.frag +++ b/reference/opt/shaders-msl/frag/constant-composites.frag @@ -25,8 +25,15 @@ struct main0_out }; // Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopy(thread T (&dst)[N], U (&src)[N]) +template +void spvArrayCopy(thread T (&dst)[N], thread const T (&src)[N]) +{ + for (uint i = 0; i < N; dst[i] = src[i], i++); +} + +// An overload for constant arrays. +template +void spvArrayCopyConstant(thread T (&dst)[N], constant T (&src)[N]) { for (uint i = 0; i < N; dst[i] = src[i], i++); } diff --git a/reference/shaders-msl/asm/frag/op-constant-null.asm.frag b/reference/shaders-msl/asm/frag/op-constant-null.asm.frag index fe8745a9..1d9d11c9 100644 --- a/reference/shaders-msl/asm/frag/op-constant-null.asm.frag +++ b/reference/shaders-msl/asm/frag/op-constant-null.asm.frag @@ -19,8 +19,15 @@ struct main0_out }; // Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopy(thread T (&dst)[N], U (&src)[N]) +template +void spvArrayCopy(thread T (&dst)[N], thread const T (&src)[N]) +{ + for (uint i = 0; i < N; dst[i] = src[i], i++); +} + +// An overload for constant arrays. +template +void spvArrayCopyConstant(thread T (&dst)[N], constant T (&src)[N]) { for (uint i = 0; i < N; dst[i] = src[i], i++); } diff --git a/reference/shaders-msl/frag/constant-array.frag b/reference/shaders-msl/frag/constant-array.frag index 7c0e29e0..773d5940 100644 --- a/reference/shaders-msl/frag/constant-array.frag +++ b/reference/shaders-msl/frag/constant-array.frag @@ -28,8 +28,15 @@ struct main0_out }; // Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopy(thread T (&dst)[N], U (&src)[N]) +template +void spvArrayCopy(thread T (&dst)[N], thread const T (&src)[N]) +{ + for (uint i = 0; i < N; dst[i] = src[i], i++); +} + +// An overload for constant arrays. +template +void spvArrayCopyConstant(thread T (&dst)[N], constant T (&src)[N]) { for (uint i = 0; i < N; dst[i] = src[i], i++); } diff --git a/reference/shaders-msl/frag/constant-composites.frag b/reference/shaders-msl/frag/constant-composites.frag index 317495d1..d216da6d 100644 --- a/reference/shaders-msl/frag/constant-composites.frag +++ b/reference/shaders-msl/frag/constant-composites.frag @@ -25,8 +25,15 @@ struct main0_out }; // Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopy(thread T (&dst)[N], U (&src)[N]) +template +void spvArrayCopy(thread T (&dst)[N], thread const T (&src)[N]) +{ + for (uint i = 0; i < N; dst[i] = src[i], i++); +} + +// An overload for constant arrays. +template +void spvArrayCopyConstant(thread T (&dst)[N], constant T (&src)[N]) { for (uint i = 0; i < N; dst[i] = src[i], i++); } diff --git a/reference/shaders-msl/vert/return-array.vert b/reference/shaders-msl/vert/return-array.vert index 4c52acd1..c3857b90 100644 --- a/reference/shaders-msl/vert/return-array.vert +++ b/reference/shaders-msl/vert/return-array.vert @@ -19,15 +19,22 @@ struct main0_out }; // Implementation of an array copy function to cover GLSL's ability to copy an array via assignment. -template -void spvArrayCopy(thread T (&dst)[N], U (&src)[N]) +template +void spvArrayCopy(thread T (&dst)[N], thread const T (&src)[N]) +{ + for (uint i = 0; i < N; dst[i] = src[i], i++); +} + +// An overload for constant arrays. +template +void spvArrayCopyConstant(thread T (&dst)[N], constant T (&src)[N]) { for (uint i = 0; i < N; dst[i] = src[i], i++); } void test(thread float4 (&SPIRV_Cross_return_value)[2]) { - spvArrayCopy(SPIRV_Cross_return_value, _20); + spvArrayCopyConstant(SPIRV_Cross_return_value, _20); } void test2(thread float4 (&SPIRV_Cross_return_value)[2], thread float4& vInput0, thread float4& vInput1) diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 1bd2f307..71a32b5e 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -915,8 +915,16 @@ void CompilerMSL::emit_custom_functions() case SPVFuncImplArrayCopy: statement("// Implementation of an array copy function to cover GLSL's ability to copy an array via " "assignment."); - statement("template"); - statement("void spvArrayCopy(thread T (&dst)[N], U (&src)[N])"); + statement("template"); + statement("void spvArrayCopy(thread T (&dst)[N], thread const T (&src)[N])"); + begin_scope(); + statement("for (uint i = 0; i < N; dst[i] = src[i], i++);"); + end_scope(); + statement(""); + + statement("// An overload for constant arrays."); + statement("template"); + statement("void spvArrayCopyConstant(thread T (&dst)[N], constant T (&src)[N])"); begin_scope(); statement("for (uint i = 0; i < N; dst[i] = src[i], i++);"); end_scope(); @@ -1777,7 +1785,10 @@ bool CompilerMSL::maybe_emit_input_struct_assignment(uint32_t id_lhs, uint32_t i void CompilerMSL::emit_array_copy(const string &lhs, uint32_t rhs_id) { // Assignment from an array initializer is fine. - statement("spvArrayCopy(", lhs, ", ", to_expression(rhs_id), ");"); + if (ids[rhs_id].get_type() == TypeConstant) + statement("spvArrayCopyConstant(", lhs, ", ", to_expression(rhs_id), ");"); + else + statement("spvArrayCopy(", lhs, ", ", to_expression(rhs_id), ");"); } // Since MSL does not allow arrays to be copied via simple variable assignment,