diff options
author | Hans-Kristian Arntzen <post@arntzen-software.no> | 2023-06-06 13:55:29 +0200 |
---|---|---|
committer | Hans-Kristian Arntzen <post@arntzen-software.no> | 2023-06-06 13:55:29 +0200 |
commit | 01b98264ce49ae8f7a771e02bcce4e6d4040757f (patch) | |
tree | d744375914a8747ae66bc61a89ffbce53cb1bfa9 | |
parent | c4eb2317a438f862e1ede40c3f8238fbfc67e323 (diff) | |
download | SPIRV-Cross-01b98264ce49ae8f7a771e02bcce4e6d4040757f.tar.gz SPIRV-Cross-01b98264ce49ae8f7a771e02bcce4e6d4040757f.tar.bz2 SPIRV-Cross-01b98264ce49ae8f7a771e02bcce4e6d4040757f.zip |
MSL: Handle stores to struct bool[].
-rw-r--r-- | spirv_glsl.cpp | 8 | ||||
-rw-r--r-- | spirv_glsl.hpp | 2 | ||||
-rw-r--r-- | spirv_msl.cpp | 36 | ||||
-rw-r--r-- | spirv_msl.hpp | 2 |
4 files changed, 35 insertions, 13 deletions
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp index 567cf30b..a262a9b1 100644 --- a/spirv_glsl.cpp +++ b/spirv_glsl.cpp @@ -5109,9 +5109,12 @@ string CompilerGLSL::to_rerolled_array_expression(const SPIRType &parent_type, type.basetype == SPIRType::Boolean && backend.boolean_in_struct_remapped_type != SPIRType::Boolean; - SPIRType tmp_type = type; + SPIRType tmp_type; if (remapped_boolean) + { + tmp_type = get<SPIRType>(type.parent_type); tmp_type.basetype = backend.boolean_in_struct_remapped_type; + } uint32_t size = to_array_size_literal(type); auto &parent = get<SPIRType>(type.parent_type); @@ -17374,9 +17377,10 @@ uint32_t CompilerGLSL::mask_relevant_memory_semantics(uint32_t semantics) MemorySemanticsCrossWorkgroupMemoryMask | MemorySemanticsSubgroupMemoryMask); } -void CompilerGLSL::emit_array_copy(const string &lhs, uint32_t, uint32_t rhs_id, StorageClass, StorageClass) +bool CompilerGLSL::emit_array_copy(const string &lhs, uint32_t, uint32_t rhs_id, StorageClass, StorageClass) { statement(lhs, " = ", to_expression(rhs_id), ";"); + return true; } bool CompilerGLSL::unroll_array_to_complex_store(uint32_t target_id, uint32_t source_id) diff --git a/spirv_glsl.hpp b/spirv_glsl.hpp index d093d827..2cd41cb8 100644 --- a/spirv_glsl.hpp +++ b/spirv_glsl.hpp @@ -807,7 +807,7 @@ protected: std::string layout_for_variable(const SPIRVariable &variable); std::string to_combined_image_sampler(VariableID image_id, VariableID samp_id); virtual bool skip_argument(uint32_t id) const; - virtual void emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id, + virtual bool emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id, spv::StorageClass lhs_storage, spv::StorageClass rhs_storage); virtual void emit_block_hints(const SPIRBlock &block); virtual std::string to_initializer_expression(const SPIRVariable &var); diff --git a/spirv_msl.cpp b/spirv_msl.cpp index 35c27508..b7a0dc1b 100644 --- a/spirv_msl.cpp +++ b/spirv_msl.cpp @@ -9470,7 +9470,7 @@ static bool storage_class_array_is_thread(StorageClass storage) } } -void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t rhs_id, +bool CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t rhs_id, StorageClass lhs_storage, StorageClass rhs_storage) { // Allow Metal to use the array<T> template to make arrays a value type. @@ -9509,7 +9509,8 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t r // Avoid spvCopy* wrapper functions; Otherwise, spvUnsafeArray<> template cannot be used with that storage qualifier. if (lhs_is_array_template && rhs_is_array_template && !using_builtin_array()) { - statement(lhs, " = ", to_expression(rhs_id), ";"); + // Fall back to normal copy path. + return false; } else { @@ -9586,6 +9587,8 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t r else statement("spvArrayCopy", tag, type.array.size(), "(", lhs, ", ", to_expression(rhs_id), ");"); } + + return true; } uint32_t CompilerMSL::get_physical_tess_level_array_size(spv::BuiltIn builtin) const @@ -9649,7 +9652,9 @@ bool CompilerMSL::maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs) auto lhs_storage = get_expression_effective_storage_class(id_lhs); auto rhs_storage = get_expression_effective_storage_class(id_rhs); - emit_array_copy(to_expression(id_lhs), id_lhs, id_rhs, lhs_storage, rhs_storage); + if (!emit_array_copy(to_expression(id_lhs), id_lhs, id_rhs, lhs_storage, rhs_storage)) + return false; + register_write(id_lhs); return true; @@ -16911,24 +16916,37 @@ void CompilerMSL::cast_to_variable_store(uint32_t target_id, std::string &expr, auto *target_expr = maybe_get<SPIRExpression>(target_id); auto *var = maybe_get_backing_variable(target_id); const SPIRType *var_type = nullptr, *phys_type = nullptr; + if (uint32_t phys_id = get_extended_decoration(target_id, SPIRVCrossDecorationPhysicalTypeID)) phys_type = &get<SPIRType>(phys_id); else phys_type = &expr_type; + if (var) { target_id = var->self; var_type = &get_variable_data_type(*var); } - // Type fixups for workgroup variables if they are booleans. - if (var && (var->storage == StorageClassWorkgroup || var_type->basetype == SPIRType::Struct) && - expr_type.basetype == SPIRType::Boolean) + bool rewrite_boolean_store = + expr_type.basetype == SPIRType::Boolean && + (var && (var->storage == StorageClassWorkgroup || var_type->basetype == SPIRType::Struct)); + + // Type fixups for workgroup variables or struct members if they are booleans. + if (rewrite_boolean_store) { - auto short_type = expr_type; - short_type.basetype = SPIRType::Short; - expr = join(type_to_glsl(short_type), "(", expr, ")"); + if (type_is_top_level_array(expr_type)) + { + expr = to_rerolled_array_expression(*var_type, expr, expr_type); + } + else + { + auto short_type = expr_type; + short_type.basetype = SPIRType::Short; + expr = join(type_to_glsl(short_type), "(", expr, ")"); + } } + // Type fixups for workgroup variables if they are matrices. // Don't do fixup for packed types; those are handled specially. // FIXME: Maybe use a type like spvStorageMatrix for packed matrices? diff --git a/spirv_msl.hpp b/spirv_msl.hpp index 2bc17b12..420ca930 100644 --- a/spirv_msl.hpp +++ b/spirv_msl.hpp @@ -1032,7 +1032,7 @@ protected: void add_pragma_line(const std::string &line); void add_typedef_line(const std::string &line); void emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uint32_t id_mem_sem); - void emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id, + bool emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id, spv::StorageClass lhs_storage, spv::StorageClass rhs_storage) override; void build_implicit_builtins(); uint32_t build_constant_uint_array_pointer(); |