diff --git a/3rdparty/spirv-cross/main.cpp b/3rdparty/spirv-cross/main.cpp index 776fcd326..1f21c4c08 100644 --- a/3rdparty/spirv-cross/main.cpp +++ b/3rdparty/spirv-cross/main.cpp @@ -860,7 +860,7 @@ static void print_help_msl() "\t[--msl-domain-lower-left]:\n\t\tUse a lower-left tessellation domain.\n" "\t[--msl-argument-buffers]:\n\t\tEmit Metal argument buffers instead of discrete resource bindings.\n" "\t\tRequires MSL 2.0 to be enabled.\n" - "\t[--msl-argument-buffers-tier]:\n\t\tWhen using Metal argument buffers, indicate the Metal argument buffer tier level supported by the Metal platform.\n" + "\t[--msl-argument-buffer-tier]:\n\t\tWhen using Metal argument buffers, indicate the Metal argument buffer tier level supported by the Metal platform.\n" "\t\tUses same values as Metal MTLArgumentBuffersTier enumeration (0 = Tier1, 1 = Tier2).\n" "\t\tSetting this value also enables msl-argument-buffers.\n" "\t[--msl-texture-buffer-native]:\n\t\tEnable native support for texel buffers. Otherwise, it is emulated as a normal texture.\n" diff --git a/3rdparty/spirv-cross/spirv_cross_c.cpp b/3rdparty/spirv-cross/spirv_cross_c.cpp index c8ebbe4ca..f76c14c0d 100644 --- a/3rdparty/spirv-cross/spirv_cross_c.cpp +++ b/3rdparty/spirv-cross/spirv_cross_c.cpp @@ -2535,6 +2535,51 @@ spvc_type_id spvc_constant_get_type(spvc_constant constant) return constant->constant_type; } +void spvc_constant_set_scalar_fp16(spvc_constant constant, unsigned column, unsigned row, unsigned short value) +{ + constant->m.c[column].r[row].u32 = value; +} + +void spvc_constant_set_scalar_fp32(spvc_constant constant, unsigned column, unsigned row, float value) +{ + constant->m.c[column].r[row].f32 = value; +} + +void spvc_constant_set_scalar_fp64(spvc_constant constant, unsigned column, unsigned row, double value) +{ + constant->m.c[column].r[row].f64 = value; +} + +void spvc_constant_set_scalar_u32(spvc_constant constant, unsigned column, unsigned row, unsigned value) +{ + constant->m.c[column].r[row].u32 = value; +} + +void spvc_constant_set_scalar_i32(spvc_constant constant, unsigned column, unsigned row, int value) +{ + constant->m.c[column].r[row].i32 = value; +} + +void spvc_constant_set_scalar_u16(spvc_constant constant, unsigned column, unsigned row, unsigned short value) +{ + constant->m.c[column].r[row].u32 = uint32_t(value); +} + +void spvc_constant_set_scalar_i16(spvc_constant constant, unsigned column, unsigned row, signed short value) +{ + constant->m.c[column].r[row].u32 = uint32_t(value); +} + +void spvc_constant_set_scalar_u8(spvc_constant constant, unsigned column, unsigned row, unsigned char value) +{ + constant->m.c[column].r[row].u32 = uint32_t(value); +} + +void spvc_constant_set_scalar_i8(spvc_constant constant, unsigned column, unsigned row, signed char value) +{ + constant->m.c[column].r[row].u32 = uint32_t(value); +} + spvc_bool spvc_compiler_get_binary_offset_for_decoration(spvc_compiler compiler, spvc_variable_id id, SpvDecoration decoration, unsigned *word_offset) diff --git a/3rdparty/spirv-cross/spirv_cross_c.h b/3rdparty/spirv-cross/spirv_cross_c.h index e39ff2c4e..7f8c6fad2 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 55 +#define SPVC_C_API_VERSION_MINOR 56 /* Bumped if internal implementation details change. */ #define SPVC_C_API_VERSION_PATCH 0 @@ -1049,6 +1049,19 @@ SPVC_PUBLIC_API int spvc_constant_get_scalar_i8(spvc_constant constant, unsigned SPVC_PUBLIC_API void spvc_constant_get_subconstants(spvc_constant constant, const spvc_constant_id **constituents, size_t *count); SPVC_PUBLIC_API spvc_type_id spvc_constant_get_type(spvc_constant constant); +/* + * C implementation of the C++ api. + */ +SPVC_PUBLIC_API void spvc_constant_set_scalar_fp16(spvc_constant constant, unsigned column, unsigned row, unsigned short value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_fp32(spvc_constant constant, unsigned column, unsigned row, float value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_fp64(spvc_constant constant, unsigned column, unsigned row, double value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_u32(spvc_constant constant, unsigned column, unsigned row, unsigned value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_i32(spvc_constant constant, unsigned column, unsigned row, int value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_u16(spvc_constant constant, unsigned column, unsigned row, unsigned short value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_i16(spvc_constant constant, unsigned column, unsigned row, signed short value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_u8(spvc_constant constant, unsigned column, unsigned row, unsigned char value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_i8(spvc_constant constant, unsigned column, unsigned row, signed char value); + /* * Misc reflection * Maps to C++ API. diff --git a/3rdparty/spirv-cross/spirv_cross_containers.hpp b/3rdparty/spirv-cross/spirv_cross_containers.hpp index 50513f49e..e79b32093 100644 --- a/3rdparty/spirv-cross/spirv_cross_containers.hpp +++ b/3rdparty/spirv-cross/spirv_cross_containers.hpp @@ -26,6 +26,7 @@ #include "spirv_cross_error_handling.hpp" #include +#include #include #include #include diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index 48ed5efec..2ccc1a472 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -4688,7 +4688,7 @@ void CompilerGLSL::strip_enclosed_expression(string &expr) expr.erase(begin(expr)); } -string CompilerGLSL::enclose_expression(const string &expr) +bool CompilerGLSL::needs_enclose_expression(const std::string &expr) { bool need_parens = false; @@ -4722,10 +4722,15 @@ string CompilerGLSL::enclose_expression(const string &expr) assert(paren_count == 0); } + return need_parens; +} + +string CompilerGLSL::enclose_expression(const string &expr) +{ // If this expression contains any spaces which are not enclosed by parentheses, // we need to enclose it so we can treat the whole string as an expression. // This happens when two expressions have been part of a binary op earlier. - if (need_parens) + if (needs_enclose_expression(expr)) return join('(', expr, ')'); else return expr; @@ -6280,6 +6285,14 @@ void CompilerGLSL::emit_unary_op_cast(uint32_t result_type, uint32_t result_id, inherit_expression_dependencies(result_id, op0); } +void CompilerGLSL::emit_mesh_tasks(SPIRBlock &block) +{ + statement("EmitMeshTasksEXT(", + to_unpacked_expression(block.mesh.groups[0]), ", ", + to_unpacked_expression(block.mesh.groups[1]), ", ", + to_unpacked_expression(block.mesh.groups[2]), ");"); +} + void CompilerGLSL::emit_binary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op) { // Various FP arithmetic opcodes such as add, sub, mul will hit this. @@ -10889,6 +10902,12 @@ bool CompilerGLSL::optimize_read_modify_write(const SPIRType &type, const string char bop = rhs[op]; auto expr = rhs.substr(lhs.size() + 3); + + // Avoids false positives where we get a = a * b + c. + // Normally, these expressions are always enclosed, but unexpected code paths may end up hitting this. + if (needs_enclose_expression(expr)) + return false; + // Try to find increments and decrements. Makes it look neater as += 1, -= 1 is fairly rare to see in real code. // Find some common patterns which are equivalent. if ((bop == '+' || bop == '-') && (expr == "1" || expr == "uint(1)" || expr == "1u" || expr == "int(1u)")) @@ -16873,10 +16892,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) break; case SPIRBlock::EmitMeshTasks: - statement("EmitMeshTasksEXT(", - to_unpacked_expression(block.mesh.groups[0]), ", ", - to_unpacked_expression(block.mesh.groups[1]), ", ", - to_unpacked_expression(block.mesh.groups[2]), ");"); + emit_mesh_tasks(block); break; default: diff --git a/3rdparty/spirv-cross/spirv_glsl.hpp b/3rdparty/spirv-cross/spirv_glsl.hpp index d48ca8fd0..0b40ed801 100644 --- a/3rdparty/spirv-cross/spirv_glsl.hpp +++ b/3rdparty/spirv-cross/spirv_glsl.hpp @@ -708,6 +708,7 @@ protected: void emit_unary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op); void emit_unary_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op); + virtual void emit_mesh_tasks(SPIRBlock &block); bool expression_is_forwarded(uint32_t id) const; bool expression_suppresses_usage_tracking(uint32_t id) const; bool expression_read_implies_multiple_reads(uint32_t id) const; @@ -768,6 +769,7 @@ protected: std::string to_extract_component_expression(uint32_t id, uint32_t index); std::string to_extract_constant_composite_expression(uint32_t result_type, const SPIRConstant &c, const uint32_t *chain, uint32_t length); + static bool needs_enclose_expression(const std::string &expr); std::string enclose_expression(const std::string &expr); std::string dereference_expression(const SPIRType &expression_type, const std::string &expr); std::string address_of_expression(const std::string &expr); diff --git a/3rdparty/spirv-cross/spirv_hlsl.cpp b/3rdparty/spirv-cross/spirv_hlsl.cpp index 23ad2bf1d..5763b5ffa 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -1808,8 +1808,10 @@ void CompilerHLSL::emit_resources() if (is_hidden_variable(var, true)) continue; - if (var.storage != StorageClassOutput && - var.storage != StorageClassTaskPayloadWorkgroupEXT) + if (var.storage == StorageClassTaskPayloadWorkgroupEXT && is_mesh_shader) + continue; + + if (var.storage != StorageClassOutput) { if (!variable_is_lut(var)) { @@ -1819,6 +1821,7 @@ void CompilerHLSL::emit_resources() switch (var.storage) { case StorageClassWorkgroup: + case StorageClassTaskPayloadWorkgroupEXT: storage = "groupshared"; break; @@ -2573,6 +2576,19 @@ void CompilerHLSL::emit_rayquery_function(const char *commited, const char *cand emit_op(ops[0], ops[1], join(to_expression(ops[2]), is_commited ? commited : candidate), false); } +void CompilerHLSL::emit_mesh_tasks(SPIRBlock &block) +{ + if (block.mesh.payload != 0) + { + statement("DispatchMesh(", to_unpacked_expression(block.mesh.groups[0]), ", ", to_unpacked_expression(block.mesh.groups[1]), ", ", + to_unpacked_expression(block.mesh.groups[2]), ", ", to_unpacked_expression(block.mesh.payload), ");"); + } + else + { + SPIRV_CROSS_THROW("Amplification shader in HLSL must have payload"); + } +} + void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) { auto &type = get(var.basetype); @@ -2818,6 +2834,8 @@ string CompilerHLSL::get_inner_entry_point_name() const return "comp_main"; else if (execution.model == ExecutionModelMeshEXT) return "mesh_main"; + else if (execution.model == ExecutionModelTaskEXT) + return "task_main"; else SPIRV_CROSS_THROW("Unsupported execution model."); } @@ -2931,8 +2949,8 @@ void CompilerHLSL::emit_hlsl_entry_point() switch (execution.model) { + case ExecutionModelTaskEXT: case ExecutionModelMeshEXT: - case ExecutionModelMeshNV: case ExecutionModelGLCompute: { if (execution.model == ExecutionModelMeshEXT) @@ -3205,7 +3223,8 @@ void CompilerHLSL::emit_hlsl_entry_point() if (execution.model == ExecutionModelVertex || execution.model == ExecutionModelFragment || execution.model == ExecutionModelGLCompute || - execution.model == ExecutionModelMeshEXT) + execution.model == ExecutionModelMeshEXT || + execution.model == ExecutionModelTaskEXT) { // For mesh shaders, we receive special arguments that we must pass down as function arguments. // HLSL does not support proper reference types for passing these IO blocks, @@ -6243,7 +6262,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) case OpRayQueryGenerateIntersectionKHR: { flush_variable_declaration(ops[0]); - statement(to_expression(ops[0]), ".CommitProceduralPrimitiveHit(", ops[1], ");"); + statement(to_expression(ops[0]), ".CommitProceduralPrimitiveHit(", to_expression(ops[1]), ");"); break; } case OpRayQueryConfirmIntersectionKHR: @@ -6355,7 +6374,6 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) statement("SetMeshOutputCounts(", to_unpacked_expression(ops[0]), ", ", to_unpacked_expression(ops[1]), ");"); break; } - default: CompilerGLSL::emit_instruction(instruction); break; diff --git a/3rdparty/spirv-cross/spirv_hlsl.hpp b/3rdparty/spirv-cross/spirv_hlsl.hpp index 2e16ebd30..51af5bf07 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.hpp +++ b/3rdparty/spirv-cross/spirv_hlsl.hpp @@ -280,6 +280,7 @@ private: void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier, uint32_t base_offset = 0) override; void emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops); + void emit_mesh_tasks(SPIRBlock &block) override; const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override; void replace_illegal_names() override; diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index 8f71c1699..5ff98b7be 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -17280,41 +17280,44 @@ void CompilerMSL::analyze_argument_buffers() // member_index and next_arg_buff_index are incremented when padding members are added. if (msl_options.pad_argument_buffer_resources) { - while (resource.index > next_arg_buff_index) + if (!resource.descriptor_alias) { - auto &rez_bind = get_argument_buffer_resource(desc_set, next_arg_buff_index); - switch (rez_bind.basetype) + while (resource.index > next_arg_buff_index) { - case SPIRType::Void: - case SPIRType::Boolean: - case SPIRType::SByte: - case SPIRType::UByte: - case SPIRType::Short: - case SPIRType::UShort: - case SPIRType::Int: - case SPIRType::UInt: - case SPIRType::Int64: - case SPIRType::UInt64: - case SPIRType::AtomicCounter: - case SPIRType::Half: - case SPIRType::Float: - case SPIRType::Double: - add_argument_buffer_padding_buffer_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::Image: - add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::Sampler: - add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::SampledImage: - if (next_arg_buff_index == rez_bind.msl_sampler) - add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - else + auto &rez_bind = get_argument_buffer_resource(desc_set, next_arg_buff_index); + switch (rez_bind.basetype) + { + case SPIRType::Void: + case SPIRType::Boolean: + case SPIRType::SByte: + case SPIRType::UByte: + case SPIRType::Short: + case SPIRType::UShort: + case SPIRType::Int: + case SPIRType::UInt: + case SPIRType::Int64: + case SPIRType::UInt64: + case SPIRType::AtomicCounter: + case SPIRType::Half: + case SPIRType::Float: + case SPIRType::Double: + add_argument_buffer_padding_buffer_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + case SPIRType::Image: add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - default: - break; + break; + case SPIRType::Sampler: + add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + case SPIRType::SampledImage: + if (next_arg_buff_index == rez_bind.msl_sampler) + add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + else + add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + default: + break; + } } } @@ -17595,7 +17598,7 @@ string CompilerMSL::additional_fixed_sample_mask_str() const #pragma warning(push) #pragma warning(disable : 4996) #endif -#if _WIN32 +#if defined(_WIN32) sprintf(print_buffer, "0x%x", msl_options.additional_fixed_sample_mask); #else snprintf(print_buffer, sizeof(print_buffer), "0x%x", msl_options.additional_fixed_sample_mask);