From 8a0ae08123c9451e0ecc44d1283a650df677d253 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: Mon, 26 Jul 2021 17:38:51 -0700 Subject: [PATCH] Updated spirv-cross. --- 3rdparty/spirv-cross/GLSL.std.450.h | 29 +- .../include/spirv_cross/barrier.hpp | 1 + .../include/spirv_cross/external_interface.h | 1 + .../spirv-cross/include/spirv_cross/image.hpp | 1 + .../spirv_cross/internal_interface.hpp | 1 + .../include/spirv_cross/sampler.hpp | 1 + .../include/spirv_cross/thread_group.hpp | 1 + 3rdparty/spirv-cross/main.cpp | 6 +- 3rdparty/spirv-cross/spirv_cfg.cpp | 2 +- 3rdparty/spirv-cross/spirv_cfg.hpp | 2 +- 3rdparty/spirv-cross/spirv_common.hpp | 7 +- 3rdparty/spirv-cross/spirv_cpp.cpp | 2 +- 3rdparty/spirv-cross/spirv_cpp.hpp | 2 +- 3rdparty/spirv-cross/spirv_cross.cpp | 8 +- 3rdparty/spirv-cross/spirv_cross.hpp | 2 +- 3rdparty/spirv-cross/spirv_cross_c.cpp | 5 +- 3rdparty/spirv-cross/spirv_cross_c.h | 6 +- .../spirv-cross/spirv_cross_containers.hpp | 2 +- .../spirv_cross_error_handling.hpp | 2 +- .../spirv-cross/spirv_cross_parsed_ir.cpp | 2 +- .../spirv-cross/spirv_cross_parsed_ir.hpp | 2 +- 3rdparty/spirv-cross/spirv_cross_util.cpp | 2 +- 3rdparty/spirv-cross/spirv_cross_util.hpp | 2 +- 3rdparty/spirv-cross/spirv_glsl.cpp | 248 +++++++++---- 3rdparty/spirv-cross/spirv_glsl.hpp | 5 +- 3rdparty/spirv-cross/spirv_hlsl.cpp | 351 ++++++++++-------- 3rdparty/spirv-cross/spirv_hlsl.hpp | 10 +- 3rdparty/spirv-cross/spirv_msl.cpp | 77 ++-- 3rdparty/spirv-cross/spirv_msl.hpp | 5 +- 3rdparty/spirv-cross/spirv_parser.cpp | 2 +- 3rdparty/spirv-cross/spirv_parser.hpp | 2 +- 3rdparty/spirv-cross/spirv_reflect.cpp | 2 +- 3rdparty/spirv-cross/spirv_reflect.hpp | 2 +- 33 files changed, 484 insertions(+), 309 deletions(-) diff --git a/3rdparty/spirv-cross/GLSL.std.450.h b/3rdparty/spirv-cross/GLSL.std.450.h index 54cc00e9a..2686fc4ea 100644 --- a/3rdparty/spirv-cross/GLSL.std.450.h +++ b/3rdparty/spirv-cross/GLSL.std.450.h @@ -1,27 +1,10 @@ /* -** Copyright (c) 2014-2016 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"), -** to deal in the Materials without restriction, including without limitation -** the rights to use, copy, modify, merge, publish, distribute, sublicense, -** and/or sell copies of the Materials, and to permit persons to whom the -** Materials are furnished to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in -** all copies or substantial portions of the Materials. -** -** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS -** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS -** IN THE MATERIALS. + * Copyright 2014-2016,2021 The Khronos Group, Inc. + * SPDX-License-Identifier: MIT + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS + * STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND + * HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ */ #ifndef GLSLstd450_H diff --git a/3rdparty/spirv-cross/include/spirv_cross/barrier.hpp b/3rdparty/spirv-cross/include/spirv_cross/barrier.hpp index bfcd22843..4ca7f4d77 100644 --- a/3rdparty/spirv-cross/include/spirv_cross/barrier.hpp +++ b/3rdparty/spirv-cross/include/spirv_cross/barrier.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2017 ARM Limited + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/3rdparty/spirv-cross/include/spirv_cross/external_interface.h b/3rdparty/spirv-cross/include/spirv_cross/external_interface.h index 1d26f1e1e..949654f5b 100644 --- a/3rdparty/spirv-cross/include/spirv_cross/external_interface.h +++ b/3rdparty/spirv-cross/include/spirv_cross/external_interface.h @@ -1,5 +1,6 @@ /* * Copyright 2015-2017 ARM Limited + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/3rdparty/spirv-cross/include/spirv_cross/image.hpp b/3rdparty/spirv-cross/include/spirv_cross/image.hpp index 73de894f8..a41ccdfbb 100644 --- a/3rdparty/spirv-cross/include/spirv_cross/image.hpp +++ b/3rdparty/spirv-cross/include/spirv_cross/image.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2017 ARM Limited + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/3rdparty/spirv-cross/include/spirv_cross/internal_interface.hpp b/3rdparty/spirv-cross/include/spirv_cross/internal_interface.hpp index e56223dfd..3ff7f8e25 100644 --- a/3rdparty/spirv-cross/include/spirv_cross/internal_interface.hpp +++ b/3rdparty/spirv-cross/include/spirv_cross/internal_interface.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2017 ARM Limited + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/3rdparty/spirv-cross/include/spirv_cross/sampler.hpp b/3rdparty/spirv-cross/include/spirv_cross/sampler.hpp index 542e11b44..020848095 100644 --- a/3rdparty/spirv-cross/include/spirv_cross/sampler.hpp +++ b/3rdparty/spirv-cross/include/spirv_cross/sampler.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2017 ARM Limited + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/3rdparty/spirv-cross/include/spirv_cross/thread_group.hpp b/3rdparty/spirv-cross/include/spirv_cross/thread_group.hpp index 377f098b4..b21558156 100644 --- a/3rdparty/spirv-cross/include/spirv_cross/thread_group.hpp +++ b/3rdparty/spirv-cross/include/spirv_cross/thread_group.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2017 ARM Limited + * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/3rdparty/spirv-cross/main.cpp b/3rdparty/spirv-cross/main.cpp index c769848cd..e5b4e3a19 100644 --- a/3rdparty/spirv-cross/main.cpp +++ b/3rdparty/spirv-cross/main.cpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_cpp.hpp" @@ -662,6 +662,7 @@ struct CLIArguments bool glsl_emit_push_constant_as_ubo = false; bool glsl_emit_ubo_as_plain_uniforms = false; bool glsl_force_flattened_io_blocks = false; + uint32_t glsl_ovr_multiview_view_count = 0; SmallVector> glsl_ext_framebuffer_fetch; bool glsl_ext_framebuffer_fetch_noncoherent = false; bool vulkan_glsl_disable_ext_samplerless_texture_functions = false; @@ -779,6 +780,7 @@ static void print_help_glsl() "\t[--remap-variable-type ]:\n\t\tRemaps a variable type based on name.\n" "\t\tPrimary use case is supporting external samplers in ESSL for video rendering on Android where you could remap a texture to a YUV one.\n" "\t[--glsl-force-flattened-io-blocks]:\n\t\tAlways flatten I/O blocks and structs.\n" + "\t[--glsl-ovr-multiview-view-count count]:\n\t\tIn GL_OVR_multiview2, specify layout(num_views).\n" ); // clang-format on } @@ -1280,6 +1282,7 @@ static string compile_iteration(const CLIArguments &args, std::vector opts.emit_push_constant_as_uniform_buffer = args.glsl_emit_push_constant_as_ubo; opts.emit_uniform_buffer_as_plain_uniforms = args.glsl_emit_ubo_as_plain_uniforms; opts.force_flattened_io_blocks = args.glsl_force_flattened_io_blocks; + opts.ovr_multiview_view_count = args.glsl_ovr_multiview_view_count; opts.emit_line_directives = args.emit_line_directives; opts.enable_storage_image_qualifier_deduction = args.enable_storage_image_qualifier_deduction; opts.force_zero_initialized_variables = args.force_zero_initialized_variables; @@ -1471,6 +1474,7 @@ static int main_inner(int argc, char *argv[]) cbs.add("--glsl-emit-push-constant-as-ubo", [&args](CLIParser &) { args.glsl_emit_push_constant_as_ubo = true; }); cbs.add("--glsl-emit-ubo-as-plain-uniforms", [&args](CLIParser &) { args.glsl_emit_ubo_as_plain_uniforms = true; }); cbs.add("--glsl-force-flattened-io-blocks", [&args](CLIParser &) { args.glsl_force_flattened_io_blocks = true; }); + cbs.add("--glsl-ovr-multiview-view-count", [&args](CLIParser &parser) { args.glsl_ovr_multiview_view_count = parser.next_uint(); }); cbs.add("--glsl-remap-ext-framebuffer-fetch", [&args](CLIParser &parser) { uint32_t input_index = parser.next_uint(); uint32_t color_attachment = parser.next_uint(); diff --git a/3rdparty/spirv-cross/spirv_cfg.cpp b/3rdparty/spirv-cross/spirv_cfg.cpp index 0a66d60bd..9081a6646 100644 --- a/3rdparty/spirv-cross/spirv_cfg.cpp +++ b/3rdparty/spirv-cross/spirv_cfg.cpp @@ -1,5 +1,6 @@ /* * Copyright 2016-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_cfg.hpp" diff --git a/3rdparty/spirv-cross/spirv_cfg.hpp b/3rdparty/spirv-cross/spirv_cfg.hpp index 041526d65..90973b567 100644 --- a/3rdparty/spirv-cross/spirv_cfg.hpp +++ b/3rdparty/spirv-cross/spirv_cfg.hpp @@ -1,5 +1,6 @@ /* * Copyright 2016-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_CFG_HPP diff --git a/3rdparty/spirv-cross/spirv_common.hpp b/3rdparty/spirv-cross/spirv_common.hpp index f0024d7ed..4bafbf93d 100644 --- a/3rdparty/spirv-cross/spirv_common.hpp +++ b/3rdparty/spirv-cross/spirv_common.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_COMMON_HPP @@ -417,6 +417,11 @@ struct IVariant virtual ~IVariant() = default; virtual IVariant *clone(ObjectPoolBase *pool) = 0; ID self = 0; + +protected: + IVariant() = default; + IVariant(const IVariant&) = default; + IVariant &operator=(const IVariant&) = default; }; #define SPIRV_CROSS_DECLARE_CLONE(T) \ diff --git a/3rdparty/spirv-cross/spirv_cpp.cpp b/3rdparty/spirv-cross/spirv_cpp.cpp index e95fe00ee..b7946bf33 100644 --- a/3rdparty/spirv-cross/spirv_cpp.cpp +++ b/3rdparty/spirv-cross/spirv_cpp.cpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_cpp.hpp" diff --git a/3rdparty/spirv-cross/spirv_cpp.hpp b/3rdparty/spirv-cross/spirv_cpp.hpp index a3bf0edb3..c76629cdc 100644 --- a/3rdparty/spirv-cross/spirv_cpp.hpp +++ b/3rdparty/spirv-cross/spirv_cpp.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_CPP_HPP diff --git a/3rdparty/spirv-cross/spirv_cross.cpp b/3rdparty/spirv-cross/spirv_cross.cpp index e948820d2..4fcd969a6 100644 --- a/3rdparty/spirv-cross/spirv_cross.cpp +++ b/3rdparty/spirv-cross/spirv_cross.cpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_cross.hpp" @@ -167,6 +167,12 @@ bool Compiler::block_is_pure(const SPIRBlock &block) case OpTraceRayKHR: case OpExecuteCallableNV: case OpExecuteCallableKHR: + case OpRayQueryInitializeKHR: + case OpRayQueryTerminateKHR: + case OpRayQueryGenerateIntersectionKHR: + case OpRayQueryConfirmIntersectionKHR: + case OpRayQueryProceedKHR: + // There are various getters in ray query, but they are considered pure. return false; // OpExtInst is potentially impure depending on extension, but GLSL builtins are at least pure. diff --git a/3rdparty/spirv-cross/spirv_cross.hpp b/3rdparty/spirv-cross/spirv_cross.hpp index 764c6c47b..d1688a67f 100644 --- a/3rdparty/spirv-cross/spirv_cross.hpp +++ b/3rdparty/spirv-cross/spirv_cross.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_HPP diff --git a/3rdparty/spirv-cross/spirv_cross_c.cpp b/3rdparty/spirv-cross/spirv_cross_c.cpp index 866c25d10..4d5615404 100644 --- a/3rdparty/spirv-cross/spirv_cross_c.cpp +++ b/3rdparty/spirv-cross/spirv_cross_c.cpp @@ -1,5 +1,6 @@ /* * Copyright 2019-2021 Hans-Kristian Arntzen + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_cross_c.h" @@ -472,6 +472,9 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c case SPVC_COMPILER_OPTION_GLSL_FORCE_FLATTENED_IO_BLOCKS: options->glsl.force_flattened_io_blocks = value != 0; break; + case SPVC_COMPILER_OPTION_GLSL_OVR_MULTIVIEW_VIEW_COUNT: + options->glsl.ovr_multiview_view_count = value; + break; #endif #if SPIRV_CROSS_C_API_HLSL diff --git a/3rdparty/spirv-cross/spirv_cross_c.h b/3rdparty/spirv-cross/spirv_cross_c.h index 1495a7eac..a590c805a 100644 --- a/3rdparty/spirv-cross/spirv_cross_c.h +++ b/3rdparty/spirv-cross/spirv_cross_c.h @@ -1,5 +1,6 @@ /* * Copyright 2019-2021 Hans-Kristian Arntzen + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_C_API_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 47 +#define SPVC_C_API_VERSION_MINOR 48 /* Bumped if internal implementation details change. */ #define SPVC_C_API_VERSION_PATCH 0 @@ -675,6 +675,8 @@ typedef enum spvc_compiler_option SPVC_COMPILER_OPTION_MSL_FORCE_SAMPLE_RATE_SHADING = 75 | SPVC_COMPILER_OPTION_MSL_BIT, SPVC_COMPILER_OPTION_MSL_IOS_SUPPORT_BASE_VERTEX_INSTANCE = 76 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_GLSL_OVR_MULTIVIEW_VIEW_COUNT = 77 | SPVC_COMPILER_OPTION_GLSL_BIT, + SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff } spvc_compiler_option; diff --git a/3rdparty/spirv-cross/spirv_cross_containers.hpp b/3rdparty/spirv-cross/spirv_cross_containers.hpp index b9c3737c9..f2179b4ed 100644 --- a/3rdparty/spirv-cross/spirv_cross_containers.hpp +++ b/3rdparty/spirv-cross/spirv_cross_containers.hpp @@ -1,5 +1,6 @@ /* * Copyright 2019-2021 Hans-Kristian Arntzen + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_CONTAINERS_HPP diff --git a/3rdparty/spirv-cross/spirv_cross_error_handling.hpp b/3rdparty/spirv-cross/spirv_cross_error_handling.hpp index 32af107eb..e96ebb9a7 100644 --- a/3rdparty/spirv-cross/spirv_cross_error_handling.hpp +++ b/3rdparty/spirv-cross/spirv_cross_error_handling.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_ERROR_HANDLING diff --git a/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp b/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp index e1a13c5e0..d6cea923e 100644 --- a/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp +++ b/3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp @@ -1,5 +1,6 @@ /* * Copyright 2018-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_cross_parsed_ir.hpp" diff --git a/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp b/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp index 88a069196..8971a9707 100644 --- a/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp +++ b/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp @@ -1,5 +1,6 @@ /* * Copyright 2018-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_PARSED_IR_HPP diff --git a/3rdparty/spirv-cross/spirv_cross_util.cpp b/3rdparty/spirv-cross/spirv_cross_util.cpp index 9ce6d4fb7..7cff010d1 100644 --- a/3rdparty/spirv-cross/spirv_cross_util.cpp +++ b/3rdparty/spirv-cross/spirv_cross_util.cpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_cross_util.hpp" diff --git a/3rdparty/spirv-cross/spirv_cross_util.hpp b/3rdparty/spirv-cross/spirv_cross_util.hpp index daa4a7900..e6e3fcdb6 100644 --- a/3rdparty/spirv-cross/spirv_cross_util.hpp +++ b/3rdparty/spirv-cross/spirv_cross_util.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_UTIL_HPP diff --git a/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/spirv-cross/spirv_glsl.cpp index bde261eb2..c5550ee59 100644 --- a/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/3rdparty/spirv-cross/spirv_glsl.cpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_glsl.hpp" @@ -465,7 +465,8 @@ void CompilerGLSL::find_static_extensions() // Need to figure out if we should target KHR or NV extension based on capabilities. for (auto &cap : ir.declared_capabilities) { - if (cap == CapabilityRayTracingKHR || cap == CapabilityRayQueryKHR) + if (cap == CapabilityRayTracingKHR || cap == CapabilityRayQueryKHR || + cap == CapabilityRayTraversalPrimitiveCullingKHR) { ray_tracing_is_khr = true; break; @@ -566,10 +567,46 @@ void CompilerGLSL::find_static_extensions() case CapabilityVariablePointersStorageBuffer: SPIRV_CROSS_THROW("VariablePointers capability is not supported in GLSL."); + case CapabilityMultiView: + if (options.vulkan_semantics) + require_extension_internal("GL_EXT_multiview"); + else + { + require_extension_internal("GL_OVR_multiview2"); + if (options.ovr_multiview_view_count == 0) + SPIRV_CROSS_THROW("ovr_multiview_view_count must be non-zero when using GL_OVR_multiview2."); + if (get_execution_model() != ExecutionModelVertex) + SPIRV_CROSS_THROW("OVR_multiview2 can only be used with Vertex shaders."); + } + break; + + case CapabilityRayQueryKHR: + if (options.es || options.version < 460 || !options.vulkan_semantics) + SPIRV_CROSS_THROW("RayQuery requires Vulkan GLSL 460."); + require_extension_internal("GL_EXT_ray_query"); + ray_tracing_is_khr = true; + break; + + case CapabilityRayTraversalPrimitiveCullingKHR: + if (options.es || options.version < 460 || !options.vulkan_semantics) + SPIRV_CROSS_THROW("RayQuery requires Vulkan GLSL 460."); + require_extension_internal("GL_EXT_ray_flags_primitive_culling"); + ray_tracing_is_khr = true; + break; + default: break; } } + + if (options.ovr_multiview_view_count) + { + if (options.vulkan_semantics) + SPIRV_CROSS_THROW("OVR_multiview2 cannot be used with Vulkan semantics."); + if (get_execution_model() != ExecutionModelVertex) + SPIRV_CROSS_THROW("OVR_multiview2 can only be used with Vertex shaders."); + require_extension_internal("GL_OVR_multiview2"); + } } void CompilerGLSL::ray_tracing_khr_fixup_locations() @@ -890,6 +927,10 @@ void CompilerGLSL::emit_header() switch (execution.model) { + case ExecutionModelVertex: + if (options.ovr_multiview_view_count) + inputs.push_back(join("num_views = ", options.ovr_multiview_view_count)); + break; case ExecutionModelGeometry: if ((execution.flags.get(ExecutionModeInvocations)) && execution.invocations != 1) inputs.push_back(join("invocations = ", execution.invocations)); @@ -1035,6 +1076,10 @@ void CompilerGLSL::emit_header() break; } + for (auto &cap : ir.declared_capabilities) + if (cap == CapabilityRayTraversalPrimitiveCullingKHR) + statement("layout(primitive_culling);"); + if (!inputs.empty()) statement("layout(", merge(inputs), ") in;"); if (!outputs.empty()) @@ -1110,8 +1155,22 @@ string CompilerGLSL::to_interpolation_qualifiers(const Bitset &flags) res += "sample "; if (flags.get(DecorationInvariant)) res += "invariant "; + if (flags.get(DecorationExplicitInterpAMD)) + { + require_extension_internal("GL_AMD_shader_explicit_vertex_parameter"); res += "__explicitInterpAMD "; + } + + if (flags.get(DecorationPerVertexNV)) + { + if (options.es && options.version < 320) + SPIRV_CROSS_THROW("pervertexNV requires ESSL 320."); + else if (!options.es && options.version < 450) + SPIRV_CROSS_THROW("pervertexNV requires GLSL 450."); + require_extension_internal("GL_NV_fragment_shader_barycentric"); + res += "pervertexNV "; + } return res; } @@ -1121,8 +1180,7 @@ string CompilerGLSL::layout_for_member(const SPIRType &type, uint32_t index) if (is_legacy()) return ""; - bool is_block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) || - ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock); + bool is_block = has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock); if (!is_block) return ""; @@ -6191,44 +6249,57 @@ bool CompilerGLSL::to_trivial_mix_op(const SPIRType &type, string &op, uint32_t if (cleft->specialization || cright->specialization) return false; - // We can only use trivial construction if we have a scalar - // (should be possible to do it for vectors as well, but that is overkill for now). - if (lerptype.basetype != SPIRType::Boolean || lerptype.vecsize > 1) + auto &value_type = get(cleft->constant_type); + + if (lerptype.basetype != SPIRType::Boolean) + return false; + if (value_type.basetype == SPIRType::Struct || is_array(value_type)) + return false; + if (!backend.use_constructor_splatting && value_type.vecsize != lerptype.vecsize) return false; // If our bool selects between 0 and 1, we can cast from bool instead, making our trivial constructor. - bool ret = false; - switch (type.basetype) + bool ret = true; + for (uint32_t col = 0; col < value_type.columns; col++) { - case SPIRType::Short: - case SPIRType::UShort: - ret = cleft->scalar_u16() == 0 && cright->scalar_u16() == 1; - break; + for (uint32_t row = 0; row < value_type.vecsize; row++) + { + switch (type.basetype) + { + case SPIRType::Short: + case SPIRType::UShort: + ret = cleft->scalar_u16(col, row) == 0 && cright->scalar_u16(col, row) == 1; + break; - case SPIRType::Int: - case SPIRType::UInt: - ret = cleft->scalar() == 0 && cright->scalar() == 1; - break; + case SPIRType::Int: + case SPIRType::UInt: + ret = cleft->scalar(col, row) == 0 && cright->scalar(col, row) == 1; + break; - case SPIRType::Half: - ret = cleft->scalar_f16() == 0.0f && cright->scalar_f16() == 1.0f; - break; + case SPIRType::Half: + ret = cleft->scalar_f16(col, row) == 0.0f && cright->scalar_f16(col, row) == 1.0f; + break; - case SPIRType::Float: - ret = cleft->scalar_f32() == 0.0f && cright->scalar_f32() == 1.0f; - break; + case SPIRType::Float: + ret = cleft->scalar_f32(col, row) == 0.0f && cright->scalar_f32(col, row) == 1.0f; + break; - case SPIRType::Double: - ret = cleft->scalar_f64() == 0.0 && cright->scalar_f64() == 1.0; - break; + case SPIRType::Double: + ret = cleft->scalar_f64(col, row) == 0.0 && cright->scalar_f64(col, row) == 1.0; + break; - case SPIRType::Int64: - case SPIRType::UInt64: - ret = cleft->scalar_u64() == 0 && cright->scalar_u64() == 1; - break; + case SPIRType::Int64: + case SPIRType::UInt64: + ret = cleft->scalar_u64(col, row) == 0 && cright->scalar_u64(col, row) == 1; + break; - default: - break; + default: + return false; + } + } + + if (!ret) + break; } if (ret) @@ -8231,13 +8302,9 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) } return "gl_BaseVertex"; } - else - { - // On regular GL, this is soft-enabled and we emit ifdefs in code. - require_extension_internal("GL_ARB_shader_draw_parameters"); - return "SPIRV_Cross_BaseVertex"; - } - break; + // On regular GL, this is soft-enabled and we emit ifdefs in code. + require_extension_internal("GL_ARB_shader_draw_parameters"); + return "SPIRV_Cross_BaseVertex"; case BuiltInBaseInstance: if (options.es) @@ -8252,13 +8319,9 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) } return "gl_BaseInstance"; } - else - { - // On regular GL, this is soft-enabled and we emit ifdefs in code. - require_extension_internal("GL_ARB_shader_draw_parameters"); - return "SPIRV_Cross_BaseInstance"; - } - break; + // On regular GL, this is soft-enabled and we emit ifdefs in code. + require_extension_internal("GL_ARB_shader_draw_parameters"); + return "SPIRV_Cross_BaseInstance"; case BuiltInDrawIndex: if (options.es) @@ -8273,13 +8336,9 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) } return "gl_DrawID"; } - else - { - // On regular GL, this is soft-enabled and we emit ifdefs in code. - require_extension_internal("GL_ARB_shader_draw_parameters"); - return "gl_DrawIDARB"; - } - break; + // On regular GL, this is soft-enabled and we emit ifdefs in code. + require_extension_internal("GL_ARB_shader_draw_parameters"); + return "gl_DrawIDARB"; case BuiltInSampleId: if (options.es && options.version < 320) @@ -8308,15 +8367,9 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) case BuiltInViewIndex: if (options.vulkan_semantics) - { - require_extension_internal("GL_EXT_multiview"); return "gl_ViewIndex"; - } else - { - require_extension_internal("GL_OVR_multiview2"); return "gl_ViewID_OVR"; - } case BuiltInNumSubgroups: request_subgroup_feature(ShaderSubgroupSupportHelper::NumSubgroups); @@ -12491,7 +12544,64 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) flush_control_dependent_expressions(current_emitting_block->self); break; + // Don't bother forwarding temporaries. Avoids having to test expression invalidation with ray query objects. + case OpRayQueryInitializeKHR: + flush_variable_declaration(ops[0]); + statement("rayQueryInitializeEXT(", + to_expression(ops[0]), ", ", to_expression(ops[1]), ", ", + to_expression(ops[2]), ", ", to_expression(ops[3]), ", ", + to_expression(ops[4]), ", ", to_expression(ops[5]), ", ", + to_expression(ops[6]), ", ", to_expression(ops[7]), ");"); + break; + case OpRayQueryProceedKHR: + flush_variable_declaration(ops[0]); + emit_op(ops[0], ops[1], join("rayQueryProceedEXT(", to_expression(ops[2]), ")"), false); + break; + case OpRayQueryTerminateKHR: + flush_variable_declaration(ops[0]); + statement("rayQueryTerminateEXT(", to_expression(ops[0]), ");"); + break; + case OpRayQueryGenerateIntersectionKHR: + flush_variable_declaration(ops[0]); + statement("rayQueryGenerateIntersectionEXT(", to_expression(ops[0]), ", ", to_expression(ops[1]), ");"); + break; + case OpRayQueryConfirmIntersectionKHR: + flush_variable_declaration(ops[0]); + statement("rayQueryConfirmIntersectionEXT(", to_expression(ops[0]), ");"); + break; +#define GLSL_RAY_QUERY_GET_OP(op) \ + case OpRayQueryGet##op##KHR: \ + flush_variable_declaration(ops[2]); \ + emit_op(ops[0], ops[1], join("rayQueryGet" #op "EXT(", to_expression(ops[2]), ")"), false); \ + break +#define GLSL_RAY_QUERY_GET_OP2(op) \ + case OpRayQueryGet##op##KHR: \ + flush_variable_declaration(ops[2]); \ + emit_op(ops[0], ops[1], join("rayQueryGet" #op "EXT(", to_expression(ops[2]), ", ", "bool(", to_expression(ops[3]), "))"), false); \ + break + GLSL_RAY_QUERY_GET_OP(RayTMin); + GLSL_RAY_QUERY_GET_OP(RayFlags); + GLSL_RAY_QUERY_GET_OP(WorldRayOrigin); + GLSL_RAY_QUERY_GET_OP(WorldRayDirection); + GLSL_RAY_QUERY_GET_OP(IntersectionCandidateAABBOpaque); + GLSL_RAY_QUERY_GET_OP2(IntersectionType); + GLSL_RAY_QUERY_GET_OP2(IntersectionT); + GLSL_RAY_QUERY_GET_OP2(IntersectionInstanceCustomIndex); + GLSL_RAY_QUERY_GET_OP2(IntersectionInstanceId); + GLSL_RAY_QUERY_GET_OP2(IntersectionInstanceShaderBindingTableRecordOffset); + GLSL_RAY_QUERY_GET_OP2(IntersectionGeometryIndex); + GLSL_RAY_QUERY_GET_OP2(IntersectionPrimitiveIndex); + GLSL_RAY_QUERY_GET_OP2(IntersectionBarycentrics); + GLSL_RAY_QUERY_GET_OP2(IntersectionFrontFace); + GLSL_RAY_QUERY_GET_OP2(IntersectionObjectRayDirection); + GLSL_RAY_QUERY_GET_OP2(IntersectionObjectRayOrigin); + GLSL_RAY_QUERY_GET_OP2(IntersectionObjectToWorld); + GLSL_RAY_QUERY_GET_OP2(IntersectionWorldToObject); +#undef GLSL_RAY_QUERY_GET_OP +#undef GLSL_RAY_QUERY_GET_OP2 + case OpConvertUToAccelerationStructureKHR: + require_extension_internal("GL_EXT_ray_tracing"); GLSL_UFOP(accelerationStructureEXT); break; @@ -12811,17 +12921,20 @@ string CompilerGLSL::flags_to_qualifiers_glsl(const SPIRType &type, const Bitset if (flags.get(DecorationRestrictPointerEXT)) return "restrict "; - // Structs do not have precision qualifiers, neither do doubles (desktop only anyways, so no mediump/highp). - if (type.basetype != SPIRType::Float && type.basetype != SPIRType::Int && type.basetype != SPIRType::UInt && - type.basetype != SPIRType::Image && type.basetype != SPIRType::SampledImage && - type.basetype != SPIRType::Sampler) - return ""; - string qual; - if (flags.get(DecorationNoContraction) && backend.support_precise_qualifier) + if (type_is_floating_point(type) && flags.get(DecorationNoContraction) && backend.support_precise_qualifier) qual = "precise "; + // Structs do not have precision qualifiers, neither do doubles (desktop only anyways, so no mediump/highp). + bool type_supports_precision = + type.basetype == SPIRType::Float || type.basetype == SPIRType::Int || type.basetype == SPIRType::UInt || + type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage || + type.basetype == SPIRType::Sampler; + + if (!type_supports_precision) + return qual; + if (options.es) { auto &execution = get_entry_point(); @@ -13312,6 +13425,9 @@ string CompilerGLSL::type_to_glsl(const SPIRType &type, uint32_t id) case SPIRType::AccelerationStructure: return ray_tracing_is_khr ? "accelerationStructureEXT" : "accelerationStructureNV"; + case SPIRType::RayQuery: + return "rayQueryEXT"; + case SPIRType::Void: return "void"; diff --git a/3rdparty/spirv-cross/spirv_glsl.hpp b/3rdparty/spirv-cross/spirv_glsl.hpp index 20b949351..83d4d72b6 100644 --- a/3rdparty/spirv-cross/spirv_glsl.hpp +++ b/3rdparty/spirv-cross/spirv_glsl.hpp @@ -1,5 +1,6 @@ /* * Copyright 2015-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_GLSL_HPP @@ -133,6 +133,9 @@ public: // what happens on legacy GLSL targets for blocks and structs. bool force_flattened_io_blocks = false; + // If non-zero, controls layout(num_views = N) in; in GL_OVR_multiview2. + uint32_t ovr_multiview_view_count = 0; + enum Precision { DontCare, diff --git a/3rdparty/spirv-cross/spirv_hlsl.cpp b/3rdparty/spirv-cross/spirv_hlsl.cpp index 9435c4e06..3ca4c2f90 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -1,5 +1,6 @@ /* * Copyright 2016-2021 Robert Konrad + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +20,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_hlsl.hpp" @@ -641,7 +641,6 @@ void CompilerHLSL::emit_builtin_outputs_in_struct() default: SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); - break; } if (type && semantic) @@ -770,7 +769,6 @@ void CompilerHLSL::emit_builtin_inputs_in_struct() default: SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); - break; } if (type && semantic) @@ -854,34 +852,25 @@ std::string CompilerHLSL::to_initializer_expression(const SPIRVariable &var) return CompilerGLSL::to_initializer_expression(var); } -void CompilerHLSL::emit_io_block(const SPIRVariable &var) +void CompilerHLSL::emit_interface_block_member_in_struct(const SPIRVariable &var, uint32_t member_index, + uint32_t location, + std::unordered_set &active_locations) { auto &execution = get_entry_point(); + auto type = get(var.basetype); + auto semantic = to_semantic(location, execution.model, var.storage); + auto mbr_name = join(to_name(type.self), "_", to_member_name(type, member_index)); + auto &mbr_type = get(type.member_types[member_index]); - auto &type = get(var.basetype); - add_resource_name(type.self); + statement(to_interpolation_qualifiers(get_member_decoration_bitset(type.self, member_index)), + type_to_glsl(mbr_type), + " ", mbr_name, type_to_array_glsl(mbr_type), + " : ", semantic, ";"); - statement("struct ", to_name(type.self)); - begin_scope(); - type.member_name_cache.clear(); - - for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++) - { - uint32_t location = get_accumulated_member_location(var, i, false); - string semantic = join(" : ", to_semantic(location, execution.model, var.storage)); - - add_member_name(type, i); - - auto &membertype = get(type.member_types[i]); - statement(to_interpolation_qualifiers(get_member_decoration_bitset(type.self, i)), - variable_decl(membertype, to_member_name(type, i)), semantic, ";"); - } - - end_scope_decl(); - statement(""); - - statement("static ", variable_decl(var), ";"); - statement(""); + // Structs and arrays should consume more locations. + uint32_t consumed_locations = type_to_consumed_locations(mbr_type); + for (uint32_t i = 0; i < consumed_locations; i++) + active_locations.insert(location + i); } void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unordered_set &active_locations) @@ -916,7 +905,6 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord bool need_matrix_unroll = var.storage == StorageClassInput && execution.model == ExecutionModelVertex; - auto &m = ir.meta[var.self].decoration; auto name = to_name(var.self); if (use_location_number) { @@ -924,8 +912,8 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord // If an explicit location exists, use it with TEXCOORD[N] semantic. // Otherwise, pick a vacant location. - if (m.decoration_flags.get(DecorationLocation)) - location_number = m.location; + if (has_decoration(var.self, DecorationLocation)) + location_number = get_decoration(var.self, DecorationLocation); else location_number = get_vacant_location(); @@ -1174,10 +1162,10 @@ void CompilerHLSL::emit_composite_constants() auto &type = this->get(c.constant_type); - // Cannot declare block type constants here. - // We do not have the struct type yet. - bool is_block = has_decoration(type.self, DecorationBlock); - if (!is_block && (type.basetype == SPIRType::Struct || !type.array.empty())) + if (type.basetype == SPIRType::Struct && is_builtin_type(type)) + return; + + if (type.basetype == SPIRType::Struct || !type.array.empty()) { auto name = to_name(c.self); statement("static const ", variable_decl(type, name), " = ", constant_expression(c), ";"); @@ -1195,6 +1183,18 @@ void CompilerHLSL::emit_specialization_constants_and_structs() SpecializationConstant wg_x, wg_y, wg_z; ID workgroup_size_id = get_work_group_size_specialization_constants(wg_x, wg_y, wg_z); + std::unordered_set io_block_types; + ir.for_each_typed_id([&](uint32_t, const SPIRVariable &var) { + auto &type = this->get(var.basetype); + if ((var.storage == StorageClassInput || var.storage == StorageClassOutput) && + !var.remapped_variable && type.pointer && !is_builtin_variable(var) && + interface_variable_exists_in_entry_point(var.self) && + has_decoration(type.self, DecorationBlock)) + { + io_block_types.insert(type.self); + } + }); + auto loop_lock = ir.create_loop_hard_lock(); for (auto &id_ : ir.ids_for_constant_or_type) { @@ -1237,9 +1237,11 @@ void CompilerHLSL::emit_specialization_constants_and_structs() else if (id.get_type() == TypeType) { auto &type = id.get(); - if (type.basetype == SPIRType::Struct && type.array.empty() && !type.pointer && - (!ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) && - !ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock))) + bool is_non_io_block = has_decoration(type.self, DecorationBlock) && + io_block_types.count(type.self) == 0; + bool is_buffer_block = has_decoration(type.self, DecorationBufferBlock); + if (type.basetype == SPIRType::Struct && type.array.empty() && + !type.pointer && !is_non_io_block && !is_buffer_block) { if (emitted) statement(""); @@ -1365,16 +1367,12 @@ void CompilerHLSL::emit_resources() ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { auto &type = this->get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); - // Do not emit I/O blocks here. - // I/O blocks can be arrayed, so we must deal with them separately to support geometry shaders - // and tessellation down the line. - if (!block && var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && + if (var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && (var.storage == StorageClassInput || var.storage == StorageClassOutput) && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) { - // Only emit non-builtins which are not blocks here. Builtin variables are handled separately. + // Builtin variables are handled separately. emit_interface_block_globally(var); emitted = true; } @@ -1388,69 +1386,72 @@ void CompilerHLSL::emit_resources() require_output = false; unordered_set active_inputs; unordered_set active_outputs; - SmallVector input_variables; - SmallVector output_variables; + + struct IOVariable + { + const SPIRVariable *var; + uint32_t location; + uint32_t block_member_index; + bool block; + }; + + SmallVector input_variables; + SmallVector output_variables; + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { auto &type = this->get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + bool block = has_decoration(type.self, DecorationBlock); if (var.storage != StorageClassInput && var.storage != StorageClassOutput) return; - // Do not emit I/O blocks here. - // I/O blocks can be arrayed, so we must deal with them separately to support geometry shaders - // and tessellation down the line. - if (!block && !var.remapped_variable && type.pointer && !is_builtin_variable(var) && + if (!var.remapped_variable && type.pointer && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) { - if (var.storage == StorageClassInput) - input_variables.push_back(&var); - else - output_variables.push_back(&var); - } - - // Reserve input and output locations for block variables as necessary. - if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) - { - auto &active = var.storage == StorageClassInput ? active_inputs : active_outputs; - for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++) + if (block) { - if (has_member_decoration(type.self, i, DecorationLocation)) + for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++) { - uint32_t location = get_member_decoration(type.self, i, DecorationLocation); - active.insert(location); + uint32_t location = get_declared_member_location(var, i, false); + if (var.storage == StorageClassInput) + input_variables.push_back({ &var, location, i, true }); + else + output_variables.push_back({ &var, location, i, true }); } } - - // Emit the block struct and a global variable here. - emit_io_block(var); + else + { + uint32_t location = get_decoration(var.self, DecorationLocation); + if (var.storage == StorageClassInput) + input_variables.push_back({ &var, location, 0, false }); + else + output_variables.push_back({ &var, location, 0, false }); + } } }); - const auto variable_compare = [&](const SPIRVariable *a, const SPIRVariable *b) -> bool { + const auto variable_compare = [&](const IOVariable &a, const IOVariable &b) -> bool { // Sort input and output variables based on, from more robust to less robust: // - Location // - Variable has a location // - Name comparison // - Variable has a name // - Fallback: ID - bool has_location_a = has_decoration(a->self, DecorationLocation); - bool has_location_b = has_decoration(b->self, DecorationLocation); + bool has_location_a = a.block || has_decoration(a.var->self, DecorationLocation); + bool has_location_b = b.block || has_decoration(b.var->self, DecorationLocation); if (has_location_a && has_location_b) - { - return get_decoration(a->self, DecorationLocation) < get_decoration(b->self, DecorationLocation); - } + return a.location < b.location; else if (has_location_a && !has_location_b) return true; else if (!has_location_a && has_location_b) return false; - const auto &name1 = to_name(a->self); - const auto &name2 = to_name(b->self); + const auto &name1 = to_name(a.var->self); + const auto &name2 = to_name(b.var->self); if (name1.empty() && name2.empty()) - return a->self < b->self; + return a.var->self < b.var->self; else if (name1.empty()) return true; else if (name2.empty()) @@ -1477,8 +1478,13 @@ void CompilerHLSL::emit_resources() begin_scope(); sort(input_variables.begin(), input_variables.end(), variable_compare); - for (auto var : input_variables) - emit_interface_block_in_struct(*var, active_inputs); + for (auto &var : input_variables) + { + if (var.block) + emit_interface_block_member_in_struct(*var.var, var.block_member_index, var.location, active_inputs); + else + emit_interface_block_in_struct(*var.var, active_inputs); + } emit_builtin_inputs_in_struct(); end_scope_decl(); statement(""); @@ -1490,10 +1496,14 @@ void CompilerHLSL::emit_resources() statement("struct SPIRV_Cross_Output"); begin_scope(); - // FIXME: Use locations properly if they exist. sort(output_variables.begin(), output_variables.end(), variable_compare); - for (auto var : output_variables) - emit_interface_block_in_struct(*var, active_outputs); + for (auto &var : output_variables) + { + if (var.block) + emit_interface_block_member_in_struct(*var.var, var.block_member_index, var.location, active_outputs); + else + emit_interface_block_in_struct(*var.var, active_outputs); + } emit_builtin_outputs_in_struct(); end_scope_decl(); statement(""); @@ -1930,6 +1940,28 @@ void CompilerHLSL::emit_resources() end_scope(); statement(""); } + + for (TypeID type_id : composite_selection_workaround_types) + { + // Need out variable since HLSL does not support returning arrays. + auto &type = get(type_id); + auto type_str = type_to_glsl(type); + auto type_arr_str = type_to_array_glsl(type); + statement("void spvSelectComposite(out ", type_str, " out_value", type_arr_str, ", bool cond, ", + type_str, " true_val", type_arr_str, ", ", + type_str, " false_val", type_arr_str, ")"); + begin_scope(); + statement("if (cond)"); + begin_scope(); + statement("out_value = true_val;"); + end_scope(); + statement("else"); + begin_scope(); + statement("out_value = false_val;"); + end_scope(); + end_scope(); + statement(""); + } } void CompilerHLSL::emit_texture_size_variants(uint64_t variant_mask, const char *vecsize_qualifier, bool uav, @@ -2037,13 +2069,6 @@ void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type if (index < memb.size()) memberflags = memb[index].decoration_flags; - string qualifiers; - bool is_block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock) || - ir.meta[type.self].decoration.decoration_flags.get(DecorationBufferBlock); - - if (is_block) - qualifiers = to_interpolation_qualifiers(memberflags); - string packing_offset; bool is_push_constant = type.storage == StorageClassPushConstant; @@ -2058,7 +2083,7 @@ void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type packing_offset = join(" : packoffset(c", offset / 16, packing_swizzle[(offset & 15) >> 2], ")"); } - statement(layout_for_member(type, index), qualifiers, qualifier, + statement(layout_for_member(type, index), qualifier, variable_decl(membertype, to_member_name(type, index)), packing_offset, ";"); } @@ -2393,27 +2418,6 @@ void CompilerHLSL::emit_hlsl_entry_point() if (require_input) arguments.push_back("SPIRV_Cross_Input stage_input"); - // Add I/O blocks as separate arguments with appropriate storage qualifier. - ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { - auto &type = this->get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); - - if (var.storage != StorageClassInput && var.storage != StorageClassOutput) - return; - - if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) - { - if (var.storage == StorageClassInput) - { - arguments.push_back(join("in ", variable_decl(type, join("stage_input", to_name(var.self))))); - } - else if (var.storage == StorageClassOutput) - { - arguments.push_back(join("out ", variable_decl(type, join("stage_output", to_name(var.self))))); - } - } - }); - auto &execution = get_entry_point(); switch (execution.model) @@ -2574,36 +2578,43 @@ void CompilerHLSL::emit_hlsl_entry_point() // Copy from stage input struct to globals. ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { auto &type = this->get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + bool block = has_decoration(type.self, DecorationBlock); if (var.storage != StorageClassInput) return; bool need_matrix_unroll = var.storage == StorageClassInput && execution.model == ExecutionModelVertex; - if (!block && !var.remapped_variable && type.pointer && !is_builtin_variable(var) && + if (!var.remapped_variable && type.pointer && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) { - auto name = to_name(var.self); - auto &mtype = this->get(var.basetype); - if (need_matrix_unroll && mtype.columns > 1) + if (block) { - // Unroll matrices. - for (uint32_t col = 0; col < mtype.columns; col++) - statement(name, "[", col, "] = stage_input.", name, "_", col, ";"); + auto type_name = to_name(type.self); + auto var_name = to_name(var.self); + 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, ";"); + } } else { - statement(name, " = stage_input.", name, ";"); + auto name = to_name(var.self); + auto &mtype = this->get(var.basetype); + if (need_matrix_unroll && mtype.columns > 1) + { + // Unroll matrices. + for (uint32_t col = 0; col < mtype.columns; col++) + statement(name, "[", col, "] = stage_input.", name, "_", col, ";"); + } + else + { + statement(name, " = stage_input.", name, ";"); + } } } - - // I/O blocks don't use the common stage input/output struct, but separate outputs. - if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) - { - auto name = to_name(var.self); - statement(name, " = stage_input", name, ";"); - } }); // Run the shader. @@ -2616,22 +2627,6 @@ void CompilerHLSL::emit_hlsl_entry_point() else SPIRV_CROSS_THROW("Unsupported shader stage."); - // Copy block outputs. - ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { - auto &type = this->get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); - - if (var.storage != StorageClassOutput) - return; - - // I/O blocks don't use the common stage input/output struct, but separate outputs. - if (block && !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) - { - auto name = to_name(var.self); - statement("stage_output", name, " = ", name, ";"); - } - }); - // Copy stage outputs. if (require_output) { @@ -2668,27 +2663,43 @@ void CompilerHLSL::emit_hlsl_entry_point() ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { auto &type = this->get(var.basetype); - bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock); + bool block = has_decoration(type.self, DecorationBlock); if (var.storage != StorageClassOutput) return; - if (!block && var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && - !is_builtin_variable(var) && interface_variable_exists_in_entry_point(var.self)) + if (!var.remapped_variable && type.pointer && + !is_builtin_variable(var) && + interface_variable_exists_in_entry_point(var.self)) { - auto name = to_name(var.self); - - if (legacy && execution.model == ExecutionModelFragment) + if (block) { - string output_filler; - for (uint32_t size = type.vecsize; size < 4; ++size) - output_filler += ", 0.0"; - - statement("stage_output.", name, " = float4(", name, output_filler, ");"); + // I/O blocks need to flatten output. + auto type_name = to_name(type.self); + auto var_name = to_name(var.self); + 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("stage_output.", flat_name, " = ", var_name, ".", mbr_name, ";"); + } } else { - statement("stage_output.", name, " = ", name, ";"); + auto name = to_name(var.self); + + if (legacy && execution.model == ExecutionModelFragment) + { + string output_filler; + for (uint32_t size = type.vecsize; size < 4; ++size) + output_filler += ", 0.0"; + + statement("stage_output.", name, " = float4(", name, output_filler, ");"); + } + else + { + statement("stage_output.", name, " = ", name, ";"); + } } } }); @@ -4575,19 +4586,15 @@ void CompilerHLSL::emit_subgroup_op(const Instruction &i) case OpGroupNonUniformInverseBallot: SPIRV_CROSS_THROW("Cannot trivially implement InverseBallot in HLSL."); - break; case OpGroupNonUniformBallotBitExtract: SPIRV_CROSS_THROW("Cannot trivially implement BallotBitExtract in HLSL."); - break; case OpGroupNonUniformBallotFindLSB: SPIRV_CROSS_THROW("Cannot trivially implement BallotFindLSB in HLSL."); - break; case OpGroupNonUniformBallotFindMSB: SPIRV_CROSS_THROW("Cannot trivially implement BallotFindMSB in HLSL."); - break; case OpGroupNonUniformBallotBitCount: { @@ -4787,6 +4794,34 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) break; } + case OpSelect: + { + auto &value_type = expression_type(ops[3]); + if (value_type.basetype == SPIRType::Struct || is_array(value_type)) + { + // HLSL does not support ternary expressions on composites. + // Cannot use branches, since we might be in a continue block + // where explicit control flow is prohibited. + // Emit a helper function where we can use control flow. + TypeID value_type_id = expression_type_id(ops[3]); + auto itr = std::find(composite_selection_workaround_types.begin(), + composite_selection_workaround_types.end(), + value_type_id); + if (itr == composite_selection_workaround_types.end()) + { + composite_selection_workaround_types.push_back(value_type_id); + force_recompile(); + } + emit_uninitialized_temporary_expression(ops[0], ops[1]); + statement("spvSelectComposite(", + to_expression(ops[1]), ", ", to_expression(ops[2]), ", ", + to_expression(ops[3]), ", ", to_expression(ops[4]), ");"); + } + else + CompilerGLSL::emit_instruction(instruction); + break; + } + case OpStore: { emit_store(instruction); diff --git a/3rdparty/spirv-cross/spirv_hlsl.hpp b/3rdparty/spirv-cross/spirv_hlsl.hpp index f46b1868a..54a49dafa 100644 --- a/3rdparty/spirv-cross/spirv_hlsl.hpp +++ b/3rdparty/spirv-cross/spirv_hlsl.hpp @@ -1,5 +1,6 @@ /* * Copyright 2016-2021 Robert Konrad + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_HLSL_HPP @@ -219,7 +219,10 @@ private: void emit_resources(); void declare_undefined_values() override; void emit_interface_block_globally(const SPIRVariable &type); - void emit_interface_block_in_struct(const SPIRVariable &type, std::unordered_set &active_locations); + void emit_interface_block_in_struct(const SPIRVariable &var, std::unordered_set &active_locations); + void emit_interface_block_member_in_struct(const SPIRVariable &var, uint32_t member_index, + uint32_t location, + std::unordered_set &active_locations); void emit_builtin_inputs_in_struct(); void emit_builtin_outputs_in_struct(); void emit_texture_op(const Instruction &i, bool sparse) override; @@ -347,7 +350,6 @@ private: uint32_t type_to_consumed_locations(const SPIRType &type) const; - void emit_io_block(const SPIRVariable &var); std::string to_semantic(uint32_t location, spv::ExecutionModel em, spv::StorageClass sc); uint32_t num_workgroups_builtin = 0; @@ -369,6 +371,8 @@ private: // Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but SV_Coverage is a scalar in HLSL. bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override; + + std::vector composite_selection_workaround_types; }; } // namespace SPIRV_CROSS_NAMESPACE diff --git a/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/spirv-cross/spirv_msl.cpp index 8a791d7d4..76c55652b 100644 --- a/3rdparty/spirv-cross/spirv_msl.cpp +++ b/3rdparty/spirv-cross/spirv_msl.cpp @@ -1,5 +1,6 @@ /* * Copyright 2016-2021 The Brenwill Workshop Ltd. + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_msl.hpp" @@ -109,7 +109,6 @@ void CompilerMSL::add_msl_resource_binding(const MSLResourceBinding &binding) default: SPIRV_CROSS_THROW("Unexpected argument buffer resource base type. When padding argument buffer elements, " "all descriptor set resources must be supplied with a base type by the app."); - break; } #undef ADD_ARG_IDX_TO_BINDING_NUM_LOOKUP } @@ -231,13 +230,12 @@ void CompilerMSL::build_implicit_builtins() (active_input_builtins.get(BuiltInVertexId) || active_input_builtins.get(BuiltInVertexIndex) || active_input_builtins.get(BuiltInBaseVertex) || active_input_builtins.get(BuiltInInstanceId) || active_input_builtins.get(BuiltInInstanceIndex) || active_input_builtins.get(BuiltInBaseInstance)); - bool need_sample_mask = msl_options.additional_fixed_sample_mask != 0xffffffff; bool need_local_invocation_index = msl_options.emulate_subgroups && active_input_builtins.get(BuiltInSubgroupId); bool need_workgroup_size = msl_options.emulate_subgroups && active_input_builtins.get(BuiltInNumSubgroups); if (need_subpass_input || need_sample_pos || need_subgroup_mask || need_vertex_params || need_tesc_params || need_multiview || need_dispatch_base || need_vertex_base_params || need_grid_params || needs_sample_id || - needs_subgroup_invocation_id || needs_subgroup_size || need_sample_mask || need_local_invocation_index || + needs_subgroup_invocation_id || needs_subgroup_size || has_additional_fixed_sample_mask() || need_local_invocation_index || need_workgroup_size) { bool has_frag_coord = false; @@ -268,7 +266,7 @@ void CompilerMSL::build_implicit_builtins() if (var.storage == StorageClassOutput) { - if (need_sample_mask && builtin == BuiltInSampleMask) + if (has_additional_fixed_sample_mask() && builtin == BuiltInSampleMask) { builtin_sample_mask_id = var.self; mark_implicit_builtin(StorageClassOutput, BuiltInSampleMask, var.self); @@ -758,7 +756,7 @@ void CompilerMSL::build_implicit_builtins() builtin_dispatch_base_id = var_id; } - if (need_sample_mask && !does_shader_write_sample_mask) + if (has_additional_fixed_sample_mask() && !does_shader_write_sample_mask) { uint32_t offset = ir.increase_bound_by(2); uint32_t var_id = offset + 1; @@ -5385,9 +5383,7 @@ void CompilerMSL::emit_custom_functions() statement("// SPIR-V callers expect a uint4. We must convert."); statement("// FIXME: This won't include higher bits if Apple ever supports"); statement("// 128 lanes in an SIMD-group."); - statement( - "return uint4((uint)((simd_vote::vote_t)vote & 0xFFFFFFFF), (uint)(((simd_vote::vote_t)vote >> " - "32) & 0xFFFFFFFF), 0, 0);"); + statement("return uint4(as_type((simd_vote::vote_t)vote), 0, 0);"); } end_scope(); statement(""); @@ -7450,7 +7446,7 @@ void CompilerMSL::fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t // for that getting the base index. for (uint32_t i = 3; i < length; ++i) { - if (is_vector(*type) && is_scalar(result_type)) + if (is_vector(*type) && !is_array(*type) && is_scalar(result_type)) { // We don't want to combine the next index. Actually, we need to save it // so we know to apply a swizzle to the result of the interpolation. @@ -9912,7 +9908,6 @@ string CompilerMSL::to_component_argument(uint32_t id) default: SPIRV_CROSS_THROW("The value (" + to_string(component_index) + ") of OpConstant ID " + to_string(id) + " is not a valid Component index, which must be one of 0, 1, 2, or 3."); - return "component::x"; } } @@ -10120,7 +10115,6 @@ static string create_swizzle(MSLComponentSwizzle swizzle) return "spvSwizzle::alpha"; default: SPIRV_CROSS_THROW("Invalid component swizzle."); - return ""; } } @@ -12314,29 +12308,17 @@ void CompilerMSL::fix_up_shader_inputs_outputs() break; } } - else if (var.storage == StorageClassOutput && is_builtin_variable(var) && active_output_builtins.get(bi_type)) + else if (var.storage == StorageClassOutput && get_execution_model() == ExecutionModelFragment && + is_builtin_variable(var) && active_output_builtins.get(bi_type) && + bi_type == BuiltInSampleMask && has_additional_fixed_sample_mask()) { - if (bi_type == BuiltInSampleMask && get_execution_model() == ExecutionModelFragment && - msl_options.additional_fixed_sample_mask != 0xffffffff) - { - // If the additional fixed sample mask was set, we need to adjust the sample_mask - // output to reflect that. If the shader outputs the sample_mask itself too, we need - // to AND the two masks to get the final one. - if (does_shader_write_sample_mask) - { - entry_func.fixup_hooks_out.push_back([=]() { - statement(to_expression(builtin_sample_mask_id), - " &= ", msl_options.additional_fixed_sample_mask, ";"); - }); - } - else - { - entry_func.fixup_hooks_out.push_back([=]() { - statement(to_expression(builtin_sample_mask_id), " = ", - msl_options.additional_fixed_sample_mask, ";"); - }); - } - } + // If the additional fixed sample mask was set, we need to adjust the sample_mask + // output to reflect that. If the shader outputs the sample_mask itself too, we need + // to AND the two masks to get the final one. + string op_str = does_shader_write_sample_mask ? " &= " : " = "; + entry_func.fixup_hooks_out.push_back([=]() { + statement(to_expression(builtin_sample_mask_id), op_str, additional_fixed_sample_mask_str(), ";"); + }); } }); } @@ -13745,7 +13727,6 @@ void CompilerMSL::emit_subgroup_op(const Instruction &i) break; default: SPIRV_CROSS_THROW("Invalid BitCount operation."); - break; } break; } @@ -14054,7 +14035,6 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) case BuiltInClipDistance: case BuiltInCullDistance: case BuiltInLayer: - case BuiltInSampleMask: if (get_execution_model() == ExecutionModelTessellationControl) break; if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point) && @@ -14062,6 +14042,24 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage); break; + case BuiltInSampleMask: + if (storage == StorageClassInput && current_function && (current_function->self == ir.default_entry_point) && + (has_additional_fixed_sample_mask() || needs_sample_id)) + { + string samp_mask_in; + samp_mask_in += "(" + CompilerGLSL::builtin_to_glsl(builtin, storage); + if (has_additional_fixed_sample_mask()) + samp_mask_in += " & " + additional_fixed_sample_mask_str(); + if (needs_sample_id) + samp_mask_in += " & (1 << gl_SampleID)"; + samp_mask_in += ")"; + return samp_mask_in; + } + if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point) && + !is_stage_output_builtin_masked(builtin)) + return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage); + break; + case BuiltInBaryCoordNV: case BuiltInBaryCoordNoPerspNV: if (storage == StorageClassInput && current_function && (current_function->self == ir.default_entry_point)) @@ -15940,3 +15938,10 @@ const char *CompilerMSL::get_combined_sampler_suffix() const void CompilerMSL::emit_block_hints(const SPIRBlock &) { } + +string CompilerMSL::additional_fixed_sample_mask_str() const +{ + char print_buffer[32]; + sprintf(print_buffer, "0x%x", msl_options.additional_fixed_sample_mask); + return print_buffer; +} diff --git a/3rdparty/spirv-cross/spirv_msl.hpp b/3rdparty/spirv-cross/spirv_msl.hpp index 21588de7e..199712720 100644 --- a/3rdparty/spirv-cross/spirv_msl.hpp +++ b/3rdparty/spirv-cross/spirv_msl.hpp @@ -1,5 +1,6 @@ /* * Copyright 2016-2021 The Brenwill Workshop Ltd. + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_MSL_HPP @@ -1093,6 +1093,9 @@ protected: bool variable_storage_requires_stage_io(spv::StorageClass storage) const; + bool has_additional_fixed_sample_mask() const { return msl_options.additional_fixed_sample_mask != 0xffffffff; } + std::string additional_fixed_sample_mask_str() const; + // OpcodeHandler that handles several MSL preprocessing operations. struct OpCodePreprocessor : OpcodeHandler { diff --git a/3rdparty/spirv-cross/spirv_parser.cpp b/3rdparty/spirv-cross/spirv_parser.cpp index 86f7fd350..d50d2e842 100644 --- a/3rdparty/spirv-cross/spirv_parser.cpp +++ b/3rdparty/spirv-cross/spirv_parser.cpp @@ -1,5 +1,6 @@ /* * Copyright 2018-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_parser.hpp" diff --git a/3rdparty/spirv-cross/spirv_parser.hpp b/3rdparty/spirv-cross/spirv_parser.hpp index 7f4a7d856..d72fc71d8 100644 --- a/3rdparty/spirv-cross/spirv_parser.hpp +++ b/3rdparty/spirv-cross/spirv_parser.hpp @@ -1,5 +1,6 @@ /* * Copyright 2018-2021 Arm Limited + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_PARSER_HPP diff --git a/3rdparty/spirv-cross/spirv_reflect.cpp b/3rdparty/spirv-cross/spirv_reflect.cpp index 447bff1c9..ee2fe930d 100644 --- a/3rdparty/spirv-cross/spirv_reflect.cpp +++ b/3rdparty/spirv-cross/spirv_reflect.cpp @@ -1,5 +1,6 @@ /* * Copyright 2018-2021 Bradley Austin Davis + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #include "spirv_reflect.hpp" diff --git a/3rdparty/spirv-cross/spirv_reflect.hpp b/3rdparty/spirv-cross/spirv_reflect.hpp index 8acbd2804..a129ba54d 100644 --- a/3rdparty/spirv-cross/spirv_reflect.hpp +++ b/3rdparty/spirv-cross/spirv_reflect.hpp @@ -1,5 +1,6 @@ /* * Copyright 2018-2021 Bradley Austin Davis + * SPDX-License-Identifier: Apache-2.0 OR MIT * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +19,6 @@ * At your option, you may choose to accept this material under either: * 1. The Apache License, Version 2.0, found at , or * 2. The MIT License, found at . - * SPDX-License-Identifier: Apache-2.0 OR MIT. */ #ifndef SPIRV_CROSS_REFLECT_HPP