From c3bc3ada4df72ddb490b079535472d4cbca64796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D1=80=D0=B0=D0=BD=D0=B8=D0=BC=D0=B8=D1=80=20=D0=9A?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D1=9F=D0=B8=D1=9B?= Date: Sat, 8 Feb 2025 17:24:43 -0800 Subject: [PATCH] Updated spirv-cross. --- 3rdparty/spirv-cross/main.cpp | 10 +++++++++- 3rdparty/spirv-cross/spirv_cross_c.cpp | 4 ++++ 3rdparty/spirv-cross/spirv_cross_c.h | 4 +++- 3rdparty/spirv-cross/spirv_glsl.cpp | 18 ++++++++++++++++++ 3rdparty/spirv-cross/spirv_msl.cpp | 16 +++++++++++++--- 3rdparty/spirv-cross/spirv_msl.hpp | 4 ++++ 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/3rdparty/spirv-cross/main.cpp b/3rdparty/spirv-cross/main.cpp index 6361fc8ab2..a842ca99e0 100644 --- a/3rdparty/spirv-cross/main.cpp +++ b/3rdparty/spirv-cross/main.cpp @@ -682,6 +682,8 @@ struct CLIArguments bool msl_readwrite_texture_fences = true; bool msl_agx_manual_cube_grad_fixup = false; bool msl_input_attachment_is_ds_attachment = false; + bool msl_disable_rasterization = false; + bool msl_auto_disable_rasterization = false; const char *msl_combined_sampler_suffix = nullptr; bool glsl_emit_push_constant_as_ubo = false; bool glsl_emit_ubo_as_plain_uniforms = false; @@ -983,7 +985,9 @@ static void print_help_msl() "\t\tAll released Apple Silicon GPUs to date ignore one of the three partial derivatives\n" "\t\tbased on the selected major axis, and expect the remaining derivatives to be\n" "\t\tpartially transformed. This fixup gives correct results on Apple Silicon.\n" - "\t[--msl-combined-sampler-suffix ]:\n\t\tUses a custom suffix for combined samplers.\n"); + "\t[--msl-combined-sampler-suffix ]:\n\t\tUses a custom suffix for combined samplers.\n" + "\t[--msl-disable-rasterization]:\n\t\tDisables rasterization and returns void from vertex-like entry points.\n" + "\t[--msl-auto-disable-rasterization]:\n\t\tDisables rasterization if BuiltInPosition is not written.\n"); // clang-format on } @@ -1265,6 +1269,8 @@ static string compile_iteration(const CLIArguments &args, std::vector msl_opts.input_attachment_is_ds_attachment = args.msl_input_attachment_is_ds_attachment; msl_opts.readwrite_texture_fences = args.msl_readwrite_texture_fences; msl_opts.agx_manual_cube_grad_fixup = args.msl_agx_manual_cube_grad_fixup; + msl_opts.disable_rasterization = args.msl_disable_rasterization; + msl_opts.auto_disable_rasterization = args.msl_auto_disable_rasterization; msl_comp->set_msl_options(msl_opts); for (auto &v : args.msl_discrete_descriptor_sets) msl_comp->add_discrete_descriptor_set(v); @@ -1830,6 +1836,8 @@ static int main_inner(int argc, char *argv[]) cbs.add("--msl-replace-recursive-inputs", [&args](CLIParser &) { args.msl_replace_recursive_inputs = true; }); cbs.add("--msl-input-attachment-is-ds-attachment", [&args](CLIParser &) { args.msl_input_attachment_is_ds_attachment = true; }); + cbs.add("--msl-disable-rasterization", [&args](CLIParser &) { args.msl_disable_rasterization = true; }); + cbs.add("--msl-auto-disable-rasterization", [&args](CLIParser &) { args.msl_auto_disable_rasterization = true; }); cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); }); cbs.add("--rename-entry-point", [&args](CLIParser &parser) { auto old_name = parser.next_string(); diff --git a/3rdparty/spirv-cross/spirv_cross_c.cpp b/3rdparty/spirv-cross/spirv_cross_c.cpp index 71bc7b573c..0c31d770fe 100644 --- a/3rdparty/spirv-cross/spirv_cross_c.cpp +++ b/3rdparty/spirv-cross/spirv_cross_c.cpp @@ -569,6 +569,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c options->msl.disable_rasterization = value != 0; break; + case SPVC_COMPILER_OPTION_MSL_AUTO_DISABLE_RASTERIZATION: + options->msl.auto_disable_rasterization = value != 0; + break; + case SPVC_COMPILER_OPTION_MSL_CAPTURE_OUTPUT_TO_BUFFER: options->msl.capture_output_to_buffer = value != 0; break; diff --git a/3rdparty/spirv-cross/spirv_cross_c.h b/3rdparty/spirv-cross/spirv_cross_c.h index a414c46bda..961f1fe8ec 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 64 +#define SPVC_C_API_VERSION_MINOR 65 /* Bumped if internal implementation details change. */ #define SPVC_C_API_VERSION_PATCH 0 @@ -748,6 +748,8 @@ typedef enum spvc_compiler_option 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_MSL_AUTO_DISABLE_RASTERIZATION = 92 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff } spvc_compiler_option; diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index 6c1d5208b9..5f087a847c 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -9824,7 +9824,17 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) case BuiltInInvocationId: return "gl_InvocationID"; case BuiltInLayer: + { + auto model = get_execution_model(); + if (model == ExecutionModelVertex || model == ExecutionModelTessellationEvaluation) + { + if (options.es) + require_extension_internal("GL_NV_viewport_array2"); + else + require_extension_internal("GL_ARB_shader_viewport_layer_array"); + } return "gl_Layer"; + } case BuiltInViewportIndex: return "gl_ViewportIndex"; case BuiltInTessLevelOuter: @@ -17869,6 +17879,14 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) case SPIRBlock::Unreachable: { + // If the entry point ends with unreachable and has a return value, insert a return + // statement to avoid potential compiler errors from non-void functions without a return value. + if (block.return_value) + { + statement("return ", to_unpacked_expression(block.return_value), ";"); + break; + } + // Avoid emitting false fallthrough, which can happen for // if (cond) break; else discard; inside a case label. // Discard is not always implementable as a terminator. diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index 50b215e267..f10566b314 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -1003,6 +1003,7 @@ void CompilerMSL::build_implicit_builtins() // If we're returning a struct from a vertex-like entry point, we must return a position attribute. bool need_position = (get_execution_model() == ExecutionModelVertex || is_tese_shader()) && !capture_output_to_buffer && !get_is_rasterization_disabled() && + !msl_options.auto_disable_rasterization && !active_output_builtins.get(BuiltInPosition); if (need_position) @@ -1039,6 +1040,10 @@ void CompilerMSL::build_implicit_builtins() }); need_position = has_output && !active_output_builtins.get(BuiltInPosition); } + else if (!active_output_builtins.get(BuiltInPosition) && msl_options.auto_disable_rasterization) + { + is_rasterization_disabled = true; + } if (need_position) { @@ -4219,8 +4224,9 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) // If the entry point should return the output struct, set the entry function // to return the output interface struct, otherwise to return nothing. // Watch out for the rare case where the terminator of the last entry point block is a - // Kill, instead of a Return. Based on SPIR-V's block-domination rules, we assume that - // any block that has a Kill will also have a terminating Return, except the last block. + // Kill or Unreachable, instead of a Return. Based on SPIR-V's block-domination rules, + // we assume that any block that has a Kill will also have a terminating Return, except + // the last block. // Indicate the output var requires early initialization. bool ep_should_return_output = !get_is_rasterization_disabled(); uint32_t rtn_id = ep_should_return_output ? ib_var_id : 0; @@ -4230,7 +4236,8 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) for (auto &blk_id : entry_func.blocks) { auto &blk = get(blk_id); - if (blk.terminator == SPIRBlock::Return || (blk.terminator == SPIRBlock::Kill && blk_id == entry_func.blocks.back())) + auto last_blk_return = blk.terminator == SPIRBlock::Kill || blk.terminator == SPIRBlock::Unreachable; + if (blk.terminator == SPIRBlock::Return || (last_blk_return && blk_id == entry_func.blocks.back())) blk.return_value = rtn_id; } vars_needing_early_declaration.push_back(ib_var_id); @@ -15584,6 +15591,9 @@ const std::unordered_set &CompilerMSL::get_illegal_func_names() { static const unordered_set illegal_func_names = { "main", + "fragment", + "vertex", + "kernel", "saturate", "assert", "fmin3", diff --git a/3rdparty/spirv-cross/spirv_msl.hpp b/3rdparty/spirv-cross/spirv_msl.hpp index 4aaad01a89..bbbf9fafe4 100644 --- a/3rdparty/spirv-cross/spirv_msl.hpp +++ b/3rdparty/spirv-cross/spirv_msl.hpp @@ -536,6 +536,10 @@ class CompilerMSL : public CompilerGLSL // if the fragment does not modify the depth value. bool input_attachment_is_ds_attachment = false; + // If BuiltInPosition is not written, automatically disable rasterization. + // The result can be queried with get_is_rasterization_disabled. + bool auto_disable_rasterization = false; + bool is_ios() const { return platform == iOS;