diff --git a/3rdparty/spirv-cross/spirv.h b/3rdparty/spirv-cross/spirv.h index 2d6e215de9..398e6c550f 100644 --- a/3rdparty/spirv-cross/spirv.h +++ b/3rdparty/spirv-cross/spirv.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 2014-2020 The Khronos Group Inc. +** Copyright (c) 2014-2024 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a copy ** of this software and/or associated documentation files (the "Materials"), @@ -511,6 +511,7 @@ typedef enum SpvDecoration_ { SpvDecorationNoUnsignedWrap = 4470, SpvDecorationWeightTextureQCOM = 4487, SpvDecorationBlockMatchTextureQCOM = 4488, + SpvDecorationBlockMatchSamplerQCOM = 4499, SpvDecorationExplicitInterpAMD = 4999, SpvDecorationOverrideCoverageNV = 5248, SpvDecorationPassthroughNV = 5250, @@ -996,6 +997,7 @@ typedef enum SpvCapability_ { SpvCapabilityTextureSampleWeightedQCOM = 4484, SpvCapabilityTextureBoxFilterQCOM = 4485, SpvCapabilityTextureBlockMatchQCOM = 4486, + SpvCapabilityTextureBlockMatch2QCOM = 4498, SpvCapabilityFloat16ImageAMD = 5008, SpvCapabilityImageGatherBiasLodAMD = 5009, SpvCapabilityFragmentMaskAMD = 5010, @@ -1605,6 +1607,10 @@ typedef enum SpvOp_ { SpvOpImageBoxFilterQCOM = 4481, SpvOpImageBlockMatchSSDQCOM = 4482, SpvOpImageBlockMatchSADQCOM = 4483, + SpvOpImageBlockMatchWindowSSDQCOM = 4500, + SpvOpImageBlockMatchWindowSADQCOM = 4501, + SpvOpImageBlockMatchGatherSSDQCOM = 4502, + SpvOpImageBlockMatchGatherSADQCOM = 4503, SpvOpGroupIAddNonUniformAMD = 5000, SpvOpGroupFAddNonUniformAMD = 5001, SpvOpGroupFMinNonUniformAMD = 5002, @@ -2284,6 +2290,10 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; case SpvOpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; case SpvOpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case SpvOpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; diff --git a/3rdparty/spirv-cross/spirv.hpp b/3rdparty/spirv-cross/spirv.hpp index f2ee9096bd..5047b9b302 100644 --- a/3rdparty/spirv-cross/spirv.hpp +++ b/3rdparty/spirv-cross/spirv.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2020 The Khronos Group Inc. +// Copyright (c) 2014-2024 The Khronos Group Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and/or associated documentation files (the "Materials"), @@ -507,6 +507,7 @@ enum Decoration { DecorationNoUnsignedWrap = 4470, DecorationWeightTextureQCOM = 4487, DecorationBlockMatchTextureQCOM = 4488, + DecorationBlockMatchSamplerQCOM = 4499, DecorationExplicitInterpAMD = 4999, DecorationOverrideCoverageNV = 5248, DecorationPassthroughNV = 5250, @@ -992,6 +993,7 @@ enum Capability { CapabilityTextureSampleWeightedQCOM = 4484, CapabilityTextureBoxFilterQCOM = 4485, CapabilityTextureBlockMatchQCOM = 4486, + CapabilityTextureBlockMatch2QCOM = 4498, CapabilityFloat16ImageAMD = 5008, CapabilityImageGatherBiasLodAMD = 5009, CapabilityFragmentMaskAMD = 5010, @@ -1601,6 +1603,10 @@ enum Op { OpImageBoxFilterQCOM = 4481, OpImageBlockMatchSSDQCOM = 4482, OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, OpGroupIAddNonUniformAMD = 5000, OpGroupFAddNonUniformAMD = 5001, OpGroupFMinNonUniformAMD = 5002, @@ -2280,6 +2286,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; diff --git a/3rdparty/spirv-cross/spirv_cross_c.cpp b/3rdparty/spirv-cross/spirv_cross_c.cpp index b506ceeeb5..71bc7b573c 100644 --- a/3rdparty/spirv-cross/spirv_cross_c.cpp +++ b/3rdparty/spirv-cross/spirv_cross_c.cpp @@ -198,6 +198,8 @@ struct spvc_resources_s : ScratchMemoryAllocation SmallVector separate_images; SmallVector separate_samplers; SmallVector acceleration_structures; + SmallVector gl_plain_uniforms; + SmallVector builtin_inputs; SmallVector builtin_outputs; @@ -520,6 +522,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c case SPVC_COMPILER_OPTION_HLSL_USE_ENTRY_POINT_NAME: options->hlsl.use_entry_point_name = value != 0; break; + + case SPVC_COMPILER_OPTION_HLSL_PRESERVE_STRUCTURED_BUFFERS: + options->hlsl.preserve_structured_buffers = value != 0; + break; #endif #if SPIRV_CROSS_C_API_MSL @@ -1855,6 +1861,8 @@ bool spvc_resources_s::copy_resources(const ShaderResources &resources) return false; if (!copy_resources(acceleration_structures, resources.acceleration_structures)) return false; + if (!copy_resources(gl_plain_uniforms, resources.gl_plain_uniforms)) + return false; if (!copy_resources(builtin_inputs, resources.builtin_inputs)) return false; if (!copy_resources(builtin_outputs, resources.builtin_outputs)) @@ -2006,6 +2014,9 @@ spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources, list = &resources->shader_record_buffers; break; + case SPVC_RESOURCE_TYPE_GL_PLAIN_UNIFORM: + list = &resources->gl_plain_uniforms; + default: break; } @@ -2177,7 +2188,11 @@ spvc_result spvc_compiler_get_entry_points(spvc_compiler compiler, const spvc_en spvc_result spvc_compiler_set_entry_point(spvc_compiler compiler, const char *name, SpvExecutionModel model) { - compiler->compiler->set_entry_point(name, static_cast(model)); + SPVC_BEGIN_SAFE_SCOPE + { + compiler->compiler->set_entry_point(name, static_cast(model)); + } + SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) return SPVC_SUCCESS; } diff --git a/3rdparty/spirv-cross/spirv_cross_c.h b/3rdparty/spirv-cross/spirv_cross_c.h index a25b0b5b9e..a414c46bda 100644 --- a/3rdparty/spirv-cross/spirv_cross_c.h +++ b/3rdparty/spirv-cross/spirv_cross_c.h @@ -40,7 +40,7 @@ extern "C" { /* Bumped if ABI or API breaks backwards compatibility. */ #define SPVC_C_API_VERSION_MAJOR 0 /* Bumped if APIs or enumerations are added in a backwards compatible way. */ -#define SPVC_C_API_VERSION_MINOR 62 +#define SPVC_C_API_VERSION_MINOR 64 /* Bumped if internal implementation details change. */ #define SPVC_C_API_VERSION_PATCH 0 @@ -226,6 +226,7 @@ typedef enum spvc_resource_type SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE = 12, SPVC_RESOURCE_TYPE_RAY_QUERY = 13, SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER = 14, + SPVC_RESOURCE_TYPE_GL_PLAIN_UNIFORM = 15, SPVC_RESOURCE_TYPE_INT_MAX = 0x7fffffff } spvc_resource_type; @@ -745,6 +746,7 @@ typedef enum spvc_compiler_option SPVC_COMPILER_OPTION_MSL_FORCE_FRAGMENT_WITH_SIDE_EFFECTS_EXECUTION = 89 | SPVC_COMPILER_OPTION_MSL_BIT, SPVC_COMPILER_OPTION_HLSL_USE_ENTRY_POINT_NAME = 90 | SPVC_COMPILER_OPTION_HLSL_BIT, + SPVC_COMPILER_OPTION_HLSL_PRESERVE_STRUCTURED_BUFFERS = 91 | SPVC_COMPILER_OPTION_HLSL_BIT, SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff } spvc_compiler_option; diff --git a/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp b/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp index 3072cd8abb..188c0ae65d 100644 --- a/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp +++ b/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp @@ -564,7 +564,8 @@ Bitset ParsedIR::get_buffer_block_type_flags(const SPIRType &type) const Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const { auto &type = get(var.basetype); - assert(type.basetype == SPIRType::Struct); + if (type.basetype != SPIRType::Struct) + SPIRV_CROSS_THROW("Cannot get buffer block flags for non-buffer variable."); // Some flags like non-writable, non-readable are actually found // as member decorations. If all members have a decoration set, propagate diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index fad1132e82..d8d509f47c 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -2764,6 +2764,8 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var) block_qualifier = "patch "; else if (has_decoration(var.self, DecorationPerPrimitiveEXT)) block_qualifier = "perprimitiveEXT "; + else if (has_decoration(var.self, DecorationPerVertexKHR)) + block_qualifier = "pervertexEXT "; else block_qualifier = ""; @@ -3691,11 +3693,11 @@ void CompilerGLSL::emit_resources() auto &type = this->get(undef.basetype); // OpUndef can be void for some reason ... if (type.basetype == SPIRType::Void) - return; + continue; // This will break. It is bogus and should not be legal. if (type_is_top_level_block(type)) - return; + continue; string initializer; if (options.force_zero_initialized_variables && type_can_zero_initialize(type)) @@ -14481,6 +14483,50 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) break; } + case OpImageBlockMatchWindowSSDQCOM: + case OpImageBlockMatchWindowSADQCOM: + case OpImageBlockMatchGatherSSDQCOM: + case OpImageBlockMatchGatherSADQCOM: + { + require_extension_internal("GL_QCOM_image_processing2"); + uint32_t result_type_id = ops[0]; + uint32_t id = ops[1]; + string expr; + switch (opcode) + { + case OpImageBlockMatchWindowSSDQCOM: + expr = "textureBlockMatchWindowSSDQCOM"; + break; + case OpImageBlockMatchWindowSADQCOM: + expr = "textureBlockMatchWindowSADQCOM"; + break; + case OpImageBlockMatchGatherSSDQCOM: + expr = "textureBlockMatchGatherSSDQCOM"; + break; + case OpImageBlockMatchGatherSADQCOM: + expr = "textureBlockMatchGatherSADQCOM"; + break; + default: + SPIRV_CROSS_THROW("Invalid opcode for QCOM_image_processing2."); + } + expr += "("; + + bool forward = false; + expr += to_expression(ops[2]); + expr += ", " + to_expression(ops[3]); + + expr += ", " + to_non_uniform_aware_expression(ops[4]); + expr += ", " + to_expression(ops[5]); + expr += ", " + to_expression(ops[6]); + + expr += ")"; + emit_op(result_type_id, id, expr, forward); + + inherit_expression_dependencies(id, ops[3]); + inherit_expression_dependencies(id, ops[5]); + break; + } + // Compute case OpControlBarrier: case OpMemoryBarrier: @@ -17608,7 +17654,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) if (!collapsed_switch) { - if (block_like_switch || is_legacy_es()) + if (block_like_switch || is_legacy()) { // ESSL 1.0 is not guaranteed to support do/while. if (is_legacy_es()) @@ -17638,7 +17684,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) // Default case. if (!block_like_switch) { - if (is_legacy_es()) + if (is_legacy()) statement("else"); else statement("default:"); @@ -17646,7 +17692,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) } else { - if (is_legacy_es()) + if (is_legacy()) { statement((i ? "else " : ""), "if (", to_legacy_case_label(block.condition, literals, label_suffix), ")"); @@ -17698,7 +17744,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) if (block.default_block == block.next_block) { - if (is_legacy_es()) + if (is_legacy()) statement("else"); else statement("default:"); @@ -17712,7 +17758,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) if (!collapsed_switch) { - if (block_like_switch && !is_legacy_es()) + if ((block_like_switch || is_legacy()) && !is_legacy_es()) end_scope_decl("while(false)"); else end_scope(); diff --git a/3rdparty/spirv-cross/spirv_hlsl.cpp b/3rdparty/spirv-cross/spirv_hlsl.cpp index 46fc176886..560f177b07 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -919,6 +919,17 @@ void CompilerHLSL::emit_builtin_inputs_in_struct() semantic = "SV_RenderTargetArrayIndex"; break; + case BuiltInBaryCoordKHR: + case BuiltInBaryCoordNoPerspKHR: + if (hlsl_options.shader_model < 61) + SPIRV_CROSS_THROW("SM 6.1 is required for barycentrics."); + type = builtin == BuiltInBaryCoordNoPerspKHR ? "noperspective float3" : "float3"; + if (active_input_builtins.get(BuiltInBaryCoordKHR) && active_input_builtins.get(BuiltInBaryCoordNoPerspKHR)) + semantic = builtin == BuiltInBaryCoordKHR ? "SV_Barycentrics0" : "SV_Barycentrics1"; + else + semantic = "SV_Barycentrics"; + break; + default: SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); } @@ -958,7 +969,7 @@ string CompilerHLSL::to_interpolation_qualifiers(const Bitset &flags) string res; //if (flags & (1ull << DecorationSmooth)) // res += "linear "; - if (flags.get(DecorationFlat)) + if (flags.get(DecorationFlat) || flags.get(DecorationPerVertexKHR)) res += "nointerpolation "; if (flags.get(DecorationNoPerspective)) res += "noperspective "; @@ -1014,7 +1025,11 @@ void CompilerHLSL::emit_interface_block_member_in_struct(const SPIRVariable &var auto mbr_name = join(to_name(type.self), "_", to_member_name(type, member_index)); auto &mbr_type = get(type.member_types[member_index]); - statement(to_interpolation_qualifiers(get_member_decoration_bitset(type.self, member_index)), + Bitset member_decorations = get_member_decoration_bitset(type.self, member_index); + if (has_decoration(var.self, DecorationPerVertexKHR)) + member_decorations.set(DecorationPerVertexKHR); + + statement(to_interpolation_qualifiers(member_decorations), type_to_glsl(mbr_type), " ", mbr_name, type_to_array_glsl(mbr_type, var.self), " : ", semantic, ";"); @@ -1102,7 +1117,7 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord else { auto decl_type = type; - if (execution.model == ExecutionModelMeshEXT) + if (execution.model == ExecutionModelMeshEXT || has_decoration(var.self, DecorationPerVertexKHR)) { decl_type.array.erase(decl_type.array.begin()); decl_type.array_size_literal.erase(decl_type.array_size_literal.begin()); @@ -1341,6 +1356,13 @@ void CompilerHLSL::emit_builtin_variables() type = "uint"; break; + case BuiltInBaryCoordKHR: + case BuiltInBaryCoordNoPerspKHR: + if (hlsl_options.shader_model < 61) + SPIRV_CROSS_THROW("Need SM 6.1 for barycentrics."); + type = "float3"; + break; + default: SPIRV_CROSS_THROW(join("Unsupported builtin in HLSL: ", unsigned(builtin))); } @@ -3298,11 +3320,23 @@ void CompilerHLSL::emit_hlsl_entry_point() { auto type_name = to_name(type.self); auto var_name = to_name(var.self); + bool is_per_vertex = has_decoration(var.self, DecorationPerVertexKHR); + uint32_t array_size = is_per_vertex ? to_array_size_literal(type) : 0; + for (uint32_t mbr_idx = 0; mbr_idx < uint32_t(type.member_types.size()); mbr_idx++) { auto mbr_name = to_member_name(type, mbr_idx); auto flat_name = join(type_name, "_", mbr_name); - statement(var_name, ".", mbr_name, " = stage_input.", flat_name, ";"); + + if (is_per_vertex) + { + for (uint32_t i = 0; i < array_size; i++) + statement(var_name, "[", i, "].", mbr_name, " = GetAttributeAtVertex(stage_input.", flat_name, ", ", i, ");"); + } + else + { + statement(var_name, ".", mbr_name, " = stage_input.", flat_name, ";"); + } } } else @@ -3315,6 +3349,12 @@ void CompilerHLSL::emit_hlsl_entry_point() for (uint32_t col = 0; col < mtype.columns; col++) statement(name, "[", col, "] = stage_input.", name, "_", col, ";"); } + else if (has_decoration(var.self, DecorationPerVertexKHR)) + { + uint32_t array_size = to_array_size_literal(type); + for (uint32_t i = 0; i < array_size; i++) + statement(name, "[", i, "]", " = GetAttributeAtVertex(stage_input.", name, ", ", i, ");"); + } else { statement(name, " = stage_input.", name, ";"); @@ -6725,6 +6765,7 @@ string CompilerHLSL::compile() backend.support_case_fallthrough = false; backend.force_merged_mesh_block = get_execution_model() == ExecutionModelMeshEXT; backend.force_gl_in_out_block = backend.force_merged_mesh_block; + backend.supports_empty_struct = hlsl_options.shader_model <= 30; // SM 4.1 does not support precise for some reason. backend.support_precise_qualifier = hlsl_options.shader_model >= 50 || hlsl_options.shader_model == 40; diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index acc66eef9a..aba26be8f3 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -7599,6 +7599,16 @@ void CompilerMSL::emit_custom_functions() statement(""); break; + case SPVFuncImplMulExtended: + // Compiler may hit an internal error with mulhi, but doesn't when encapsulated for some reason. + statement("template"); + statement("[[clang::optnone]] T spvMulExtended(V l, V r)"); + begin_scope(); + statement("return T{U(l * r), U(mulhi(l, r))};"); + end_scope(); + statement(""); + break; + default: break; } @@ -9550,13 +9560,13 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) uint32_t op0 = ops[2]; uint32_t op1 = ops[3]; auto &type = get(result_type); + auto &op_type = get(type.member_types[0]); auto input_type = opcode == OpSMulExtended ? int_type : uint_type; string cast_op0, cast_op1; binary_op_bitcast_helper(cast_op0, cast_op1, input_type, op0, op1, false); - emit_uninitialized_temporary_expression(result_type, result_id); - statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", cast_op0, " * ", cast_op1, ";"); - statement(to_expression(result_id), ".", to_member_name(type, 1), " = mulhi(", cast_op0, ", ", cast_op1, ");"); + auto expr = join("spvMulExtended<", type_to_glsl(type), ", ", type_to_glsl(op_type), ">(", cast_op0, ", ", cast_op1, ")"); + emit_op(result_type, result_id, expr, true); break; } @@ -10303,6 +10313,13 @@ void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, { auto obj_expression = to_expression(obj); auto split_index = obj_expression.find_first_of('@'); + bool needs_reinterpret = opcode == OpAtomicUMax || opcode == OpAtomicUMin || opcode == OpAtomicSMax || opcode == OpAtomicSMin; + needs_reinterpret &= type.basetype != expected_type; + SPIRVariable *backing_var = nullptr; + + // Try to avoid waiting until not force recompile later mode to enable force recompile later + if (needs_reinterpret && (backing_var = maybe_get_backing_variable(obj))) + add_spv_func_and_recompile(SPVFuncImplTextureCast); // Will only be false if we're in "force recompile later" mode. if (split_index != string::npos) @@ -10313,27 +10330,21 @@ void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, // Handle problem cases with sign where we need signed min/max on a uint image for example. // It seems to work to cast the texture type itself, even if it is probably wildly outside of spec, // but SPIR-V requires this to work. - if ((opcode == OpAtomicUMax || opcode == OpAtomicUMin || - opcode == OpAtomicSMax || opcode == OpAtomicSMin) && - type.basetype != expected_type) + if (needs_reinterpret && backing_var) { - auto *backing_var = maybe_get_backing_variable(obj); - if (backing_var) - { - add_spv_func_and_recompile(SPVFuncImplTextureCast); + assert(spv_function_implementations.count(SPVFuncImplTextureCast) && "Should have been added above"); - const auto *backing_type = &get(backing_var->basetype); - while (backing_type->op != OpTypeImage) - backing_type = &get(backing_type->parent_type); + const auto *backing_type = &get(backing_var->basetype); + while (backing_type->op != OpTypeImage) + backing_type = &get(backing_type->parent_type); - auto img_type = *backing_type; - auto tmp_type = type; - tmp_type.basetype = expected_type; - img_type.image.type = ir.increase_bound_by(1); - set(img_type.image.type, tmp_type); + auto img_type = *backing_type; + auto tmp_type = type; + tmp_type.basetype = expected_type; + img_type.image.type = ir.increase_bound_by(1); + set(img_type.image.type, tmp_type); - image_expr = join("spvTextureCast<", type_to_glsl(img_type, obj), ">(", image_expr, ")"); - } + image_expr = join("spvTextureCast<", type_to_glsl(img_type, obj), ">(", image_expr, ")"); } exp += join(image_expr, ".", op, "("); @@ -12758,17 +12769,10 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in else quals = member_location_attribute_qualifier(type, index); - if (builtin == BuiltInBaryCoordKHR || builtin == BuiltInBaryCoordNoPerspKHR) + if (builtin == BuiltInBaryCoordKHR && has_member_decoration(type.self, index, DecorationNoPerspective)) { - if (has_member_decoration(type.self, index, DecorationFlat) || - has_member_decoration(type.self, index, DecorationCentroid) || - has_member_decoration(type.self, index, DecorationSample) || - has_member_decoration(type.self, index, DecorationNoPerspective)) - { - // NoPerspective is baked into the builtin type. - SPIRV_CROSS_THROW( - "Flat, Centroid, Sample, NoPerspective decorations are not supported for BaryCoord inputs."); - } + // NoPerspective is baked into the builtin type. + SPIRV_CROSS_THROW("NoPerspective decorations are not supported for BaryCoord inputs."); } // Don't bother decorating integers with the 'flat' attribute; it's @@ -12786,7 +12790,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in { if (!quals.empty()) quals += ", "; - if (has_member_decoration(type.self, index, DecorationNoPerspective)) + if (has_member_decoration(type.self, index, DecorationNoPerspective) || builtin == BuiltInBaryCoordNoPerspKHR) quals += "centroid_no_perspective"; else quals += "centroid_perspective"; @@ -12795,17 +12799,23 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in { if (!quals.empty()) quals += ", "; - if (has_member_decoration(type.self, index, DecorationNoPerspective)) + if (has_member_decoration(type.self, index, DecorationNoPerspective) || builtin == BuiltInBaryCoordNoPerspKHR) quals += "sample_no_perspective"; else quals += "sample_perspective"; } - else if (has_member_decoration(type.self, index, DecorationNoPerspective)) + else if (has_member_decoration(type.self, index, DecorationNoPerspective) || builtin == BuiltInBaryCoordNoPerspKHR) { if (!quals.empty()) quals += ", "; quals += "center_no_perspective"; } + else if (builtin == BuiltInBaryCoordKHR) + { + if (!quals.empty()) + quals += ", "; + quals += "center_perspective"; + } } if (!quals.empty()) @@ -13873,6 +13883,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) } else { + add_spv_func_and_recompile(SPVFuncImplVariableDescriptor); ep_args += "const device spvDescriptor<" + get_argument_address_space(var) + " " + type_to_glsl(type) + "*>* "; } @@ -15253,6 +15264,7 @@ const std::unordered_set &CompilerMSL::get_illegal_func_names() "fmin3", "fmax3", "divide", + "fmod", "median3", "VARIABLE_TRACEPOINT", "STATIC_DATA_TRACEPOINT", @@ -16806,18 +16818,12 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) SPIRV_CROSS_THROW("Subgroup ballot masks are handled specially in MSL."); case BuiltInBaryCoordKHR: - if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) - SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS."); - else if (!msl_options.supports_msl_version(2, 2)) - SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.2 and above on macOS."); - return "barycentric_coord, center_perspective"; - case BuiltInBaryCoordNoPerspKHR: if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS."); else if (!msl_options.supports_msl_version(2, 2)) SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.2 and above on macOS."); - return "barycentric_coord, center_no_perspective"; + return "barycentric_coord"; default: return "unsupported-built-in"; @@ -17705,6 +17711,10 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o case OpSUDotAccSat: return SPVFuncImplReduceAdd; + case OpSMulExtended: + case OpUMulExtended: + return SPVFuncImplMulExtended; + default: break; } diff --git a/3rdparty/spirv-cross/spirv_msl.hpp b/3rdparty/spirv-cross/spirv_msl.hpp index 2d970c0da5..14cd84b0f7 100644 --- a/3rdparty/spirv-cross/spirv_msl.hpp +++ b/3rdparty/spirv-cross/spirv_msl.hpp @@ -838,7 +838,8 @@ class CompilerMSL : public CompilerGLSL SPVFuncImplPaddedStd140, SPVFuncImplReduceAdd, SPVFuncImplImageFence, - SPVFuncImplTextureCast + SPVFuncImplTextureCast, + SPVFuncImplMulExtended, }; // If the underlying resource has been used for comparison then duplicate loads of that resource must be too diff --git a/3rdparty/spirv-cross/spirv_reflect.cpp b/3rdparty/spirv-cross/spirv_reflect.cpp index 633983bd30..552d671a64 100644 --- a/3rdparty/spirv-cross/spirv_reflect.cpp +++ b/3rdparty/spirv-cross/spirv_reflect.cpp @@ -637,6 +637,8 @@ void CompilerReflection::emit_resources(const char *tag, const SmallVectoremit_json_key_value("WeightTextureQCOM", get_decoration(res.id, DecorationWeightTextureQCOM)); if (mask.get(DecorationBlockMatchTextureQCOM)) json_stream->emit_json_key_value("BlockMatchTextureQCOM", get_decoration(res.id, DecorationBlockMatchTextureQCOM)); + if (mask.get(DecorationBlockMatchSamplerQCOM)) + json_stream->emit_json_key_value("BlockMatchSamplerQCOM", get_decoration(res.id, DecorationBlockMatchSamplerQCOM)); // For images, the type itself adds a layout qualifer. // Only emit the format for storage images.