diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-08-23 14:23:40 +0300 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2021-08-23 14:26:45 +0300 |
commit | 2eea6a579bb183a7a28a3d3d9aefc49d5c0820bc (patch) | |
tree | bf37cb40b3ba17e940d69c150c64fe7fd893f2f2 /spirv_msl.cpp | |
parent | 840d4483bcb2048c3c91fd418ae8f23a9b41f4e3 (diff) |
MSL: Consider that function/private variables can be block-like.
Handles a special case with array copies.
The implementation of this fix is not perfect, but should be good
enough for time being.
Diffstat (limited to 'spirv_msl.cpp')
-rw-r--r-- | spirv_msl.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 1e4aa4bd..56794c32 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -8511,13 +8511,27 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t r // Special considerations for stage IO variables. // If the variable is actually backed by non-user visible device storage, we use array templates for those. + // + // Another special consideration is given to thread local variables which happen to have Offset decorations + // applied to them. Block-like types do not use array templates, so we need to force POD path if we detect + // these scenarios. This check isn't perfect since it would be technically possible to mix and match these things, + // and for a fully correct solution we might have to track array template state through access chains as well, + // but for all reasonable use cases, this should suffice. + // This special case should also only apply to Function/Private storage classes. + // We should not check backing variable for temporaries. auto *lhs_var = maybe_get_backing_variable(lhs_id); if (lhs_var && lhs_storage == StorageClassStorageBuffer && storage_class_array_is_thread(lhs_var->storage)) lhs_is_array_template = true; + else if (lhs_var && (lhs_storage == StorageClassFunction || lhs_storage == StorageClassPrivate) && + type_is_block_like(get<SPIRType>(lhs_var->basetype))) + lhs_is_array_template = false; auto *rhs_var = maybe_get_backing_variable(rhs_id); if (rhs_var && rhs_storage == StorageClassStorageBuffer && storage_class_array_is_thread(rhs_var->storage)) rhs_is_array_template = true; + else if (rhs_var && (rhs_storage == StorageClassFunction || rhs_storage == StorageClassPrivate) && + type_is_block_like(get<SPIRType>(rhs_var->basetype))) + rhs_is_array_template = false; // If threadgroup storage qualifiers are *not* used: // Avoid spvCopy* wrapper functions; Otherwise, spvUnsafeArray<> template cannot be used with that storage qualifier. |