Бранимир Караџић пре 5 година
родитељ
комит
aa9ab978a1

+ 25 - 2
3rdparty/spirv-cross/main.cpp

@@ -566,6 +566,10 @@ struct CLIArguments
 	uint32_t msl_r32ui_linear_texture_alignment = 4;
 	uint32_t msl_r32ui_linear_texture_alignment = 4;
 	uint32_t msl_r32ui_alignment_constant_id = 65535;
 	uint32_t msl_r32ui_alignment_constant_id = 65535;
 	bool msl_texture_1d_as_2d = false;
 	bool msl_texture_1d_as_2d = false;
+	bool msl_ios_use_simdgroup_functions = false;
+	bool msl_emulate_subgroups = false;
+	uint32_t msl_fixed_subgroup_size = 0;
+	bool msl_force_sample_rate_shading = false;
 	bool glsl_emit_push_constant_as_ubo = false;
 	bool glsl_emit_push_constant_as_ubo = false;
 	bool glsl_emit_ubo_as_plain_uniforms = false;
 	bool glsl_emit_ubo_as_plain_uniforms = false;
 	bool glsl_force_flattened_io_blocks = false;
 	bool glsl_force_flattened_io_blocks = false;
@@ -779,7 +783,16 @@ static void print_help_msl()
 	                "\t[--msl-r32ui-linear-texture-align-constant-id <id>]:\n\t\tThe function constant ID to use for the linear texture alignment.\n"
 	                "\t[--msl-r32ui-linear-texture-align-constant-id <id>]:\n\t\tThe function constant ID to use for the linear texture alignment.\n"
 	                "\t\tOn MSL 1.2 or later, you can override the alignment by setting this function constant.\n"
 	                "\t\tOn MSL 1.2 or later, you can override the alignment by setting this function constant.\n"
 	                "\t[--msl-texture-1d-as-2d]:\n\t\tEmit Image variables of dimension Dim1D as texture2d.\n"
 	                "\t[--msl-texture-1d-as-2d]:\n\t\tEmit Image variables of dimension Dim1D as texture2d.\n"
-	                "\t\tIn Metal, 1D textures do not support all features that 2D textures do. Use this option if your code relies on these features.\n");
+	                "\t\tIn Metal, 1D textures do not support all features that 2D textures do. Use this option if your code relies on these features.\n"
+	                "\t[--msl-ios-use-simdgroup-functions]:\n\t\tUse simd_*() functions for subgroup ops instead of quad_*().\n"
+	                "\t\tRecent Apple GPUs support SIMD-groups larger than a quad. Use this option to take advantage of this support.\n"
+	                "\t[--msl-emulate-subgroups]:\n\t\tAssume subgroups of size 1.\n"
+	                "\t\tIntended for Vulkan Portability implementations where Metal support for SIMD-groups is insufficient for true subgroups.\n"
+	                "\t[--msl-fixed-subgroup-size <size>]:\n\t\tAssign a constant <size> to the SubgroupSize builtin.\n"
+	                "\t\tIntended for Vulkan Portability implementations where VK_EXT_subgroup_size_control is not supported or disabled.\n"
+	                "\t\tIf 0, assume variable subgroup size as actually exposed by Metal.\n"
+	                "\t[--msl-force-sample-rate-shading]:\n\t\tForce fragment shaders to run per sample.\n"
+	                "\t\tThis adds a [[sample_id]] parameter if none is already present.\n");
 	// clang-format on
 	// clang-format on
 }
 }
 
 
@@ -1021,6 +1034,10 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
 		msl_opts.r32ui_linear_texture_alignment = args.msl_r32ui_linear_texture_alignment;
 		msl_opts.r32ui_linear_texture_alignment = args.msl_r32ui_linear_texture_alignment;
 		msl_opts.r32ui_alignment_constant_id = args.msl_r32ui_alignment_constant_id;
 		msl_opts.r32ui_alignment_constant_id = args.msl_r32ui_alignment_constant_id;
 		msl_opts.texture_1D_as_2D = args.msl_texture_1d_as_2d;
 		msl_opts.texture_1D_as_2D = args.msl_texture_1d_as_2d;
+		msl_opts.ios_use_simdgroup_functions = args.msl_ios_use_simdgroup_functions;
+		msl_opts.emulate_subgroups = args.msl_emulate_subgroups;
+		msl_opts.fixed_subgroup_size = args.msl_fixed_subgroup_size;
+		msl_opts.force_sample_rate_shading = args.msl_force_sample_rate_shading;
 		msl_comp->set_msl_options(msl_opts);
 		msl_comp->set_msl_options(msl_opts);
 		for (auto &v : args.msl_discrete_descriptor_sets)
 		for (auto &v : args.msl_discrete_descriptor_sets)
 			msl_comp->add_discrete_descriptor_set(v);
 			msl_comp->add_discrete_descriptor_set(v);
@@ -1370,7 +1387,8 @@ static int main_inner(int argc, char *argv[])
 	cbs.add("--hlsl-nonwritable-uav-texture-as-srv",
 	cbs.add("--hlsl-nonwritable-uav-texture-as-srv",
 	        [&args](CLIParser &) { args.hlsl_nonwritable_uav_texture_as_srv = true; });
 	        [&args](CLIParser &) { args.hlsl_nonwritable_uav_texture_as_srv = true; });
 	cbs.add("--hlsl-enable-16bit-types", [&args](CLIParser &) { args.hlsl_enable_16bit_types = true; });
 	cbs.add("--hlsl-enable-16bit-types", [&args](CLIParser &) { args.hlsl_enable_16bit_types = true; });
-	cbs.add("--hlsl-flatten-matrix-vertex-input-semantics", [&args](CLIParser &) { args.hlsl_flatten_matrix_vertex_input_semantics = true; });
+	cbs.add("--hlsl-flatten-matrix-vertex-input-semantics",
+	        [&args](CLIParser &) { args.hlsl_flatten_matrix_vertex_input_semantics = true; });
 	cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
 	cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
 	cbs.add("-V", [&args](CLIParser &) { args.vulkan_semantics = true; });
 	cbs.add("-V", [&args](CLIParser &) { args.vulkan_semantics = true; });
 	cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
 	cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
@@ -1448,6 +1466,11 @@ static int main_inner(int argc, char *argv[])
 	cbs.add("--msl-r32ui-linear-texture-align-constant-id",
 	cbs.add("--msl-r32ui-linear-texture-align-constant-id",
 	        [&args](CLIParser &parser) { args.msl_r32ui_alignment_constant_id = parser.next_uint(); });
 	        [&args](CLIParser &parser) { args.msl_r32ui_alignment_constant_id = parser.next_uint(); });
 	cbs.add("--msl-texture-1d-as-2d", [&args](CLIParser &) { args.msl_texture_1d_as_2d = true; });
 	cbs.add("--msl-texture-1d-as-2d", [&args](CLIParser &) { args.msl_texture_1d_as_2d = true; });
+	cbs.add("--msl-ios-use-simdgroup-functions", [&args](CLIParser &) { args.msl_ios_use_simdgroup_functions = true; });
+	cbs.add("--msl-emulate-subgroups", [&args](CLIParser &) { args.msl_emulate_subgroups = true; });
+	cbs.add("--msl-fixed-subgroup-size",
+	        [&args](CLIParser &parser) { args.msl_fixed_subgroup_size = parser.next_uint(); });
+	cbs.add("--msl-force-sample-rate-shading", [&args](CLIParser &) { args.msl_force_sample_rate_shading = true; });
 	cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); });
 	cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); });
 	cbs.add("--rename-entry-point", [&args](CLIParser &parser) {
 	cbs.add("--rename-entry-point", [&args](CLIParser &parser) {
 		auto old_name = parser.next_string();
 		auto old_name = parser.next_string();

+ 43 - 30
3rdparty/spirv-cross/spirv_cross.cpp

@@ -1682,8 +1682,13 @@ size_t Compiler::get_declared_struct_size_runtime_array(const SPIRType &type, si
 uint32_t Compiler::evaluate_spec_constant_u32(const SPIRConstantOp &spec) const
 uint32_t Compiler::evaluate_spec_constant_u32(const SPIRConstantOp &spec) const
 {
 {
 	auto &result_type = get<SPIRType>(spec.basetype);
 	auto &result_type = get<SPIRType>(spec.basetype);
-	if (result_type.basetype != SPIRType::UInt && result_type.basetype != SPIRType::Int && result_type.basetype != SPIRType::Boolean)
-		SPIRV_CROSS_THROW("Only 32-bit integers and booleans are currently supported when evaluating specialization constants.\n");
+	if (result_type.basetype != SPIRType::UInt && result_type.basetype != SPIRType::Int &&
+	    result_type.basetype != SPIRType::Boolean)
+	{
+		SPIRV_CROSS_THROW(
+		    "Only 32-bit integers and booleans are currently supported when evaluating specialization constants.\n");
+	}
+
 	if (!is_scalar(result_type))
 	if (!is_scalar(result_type))
 		SPIRV_CROSS_THROW("Spec constant evaluation must be a scalar.\n");
 		SPIRV_CROSS_THROW("Spec constant evaluation must be a scalar.\n");
 
 
@@ -1692,7 +1697,11 @@ uint32_t Compiler::evaluate_spec_constant_u32(const SPIRConstantOp &spec) const
 	const auto eval_u32 = [&](uint32_t id) -> uint32_t {
 	const auto eval_u32 = [&](uint32_t id) -> uint32_t {
 		auto &type = expression_type(id);
 		auto &type = expression_type(id);
 		if (type.basetype != SPIRType::UInt && type.basetype != SPIRType::Int && type.basetype != SPIRType::Boolean)
 		if (type.basetype != SPIRType::UInt && type.basetype != SPIRType::Int && type.basetype != SPIRType::Boolean)
-			SPIRV_CROSS_THROW("Only 32-bit integers and booleans are currently supported when evaluating specialization constants.\n");
+		{
+			SPIRV_CROSS_THROW("Only 32-bit integers and booleans are currently supported when evaluating "
+			                  "specialization constants.\n");
+		}
+
 		if (!is_scalar(type))
 		if (!is_scalar(type))
 			SPIRV_CROSS_THROW("Spec constant evaluation must be a scalar.\n");
 			SPIRV_CROSS_THROW("Spec constant evaluation must be a scalar.\n");
 		if (const auto *c = this->maybe_get<SPIRConstant>(id))
 		if (const auto *c = this->maybe_get<SPIRConstant>(id))
@@ -1701,37 +1710,41 @@ uint32_t Compiler::evaluate_spec_constant_u32(const SPIRConstantOp &spec) const
 			return evaluate_spec_constant_u32(this->get<SPIRConstantOp>(id));
 			return evaluate_spec_constant_u32(this->get<SPIRConstantOp>(id));
 	};
 	};
 
 
-#define binary_spec_op(op, binary_op) \
-	case Op##op: value = eval_u32(spec.arguments[0]) binary_op eval_u32(spec.arguments[1]); break
-#define binary_spec_op_cast(op, binary_op, type) \
-	case Op##op: value = uint32_t(type(eval_u32(spec.arguments[0])) binary_op type(eval_u32(spec.arguments[1]))); break
+#define binary_spec_op(op, binary_op)                                              \
+	case Op##op:                                                                   \
+		value = eval_u32(spec.arguments[0]) binary_op eval_u32(spec.arguments[1]); \
+		break
+#define binary_spec_op_cast(op, binary_op, type)                                                         \
+	case Op##op:                                                                                         \
+		value = uint32_t(type(eval_u32(spec.arguments[0])) binary_op type(eval_u32(spec.arguments[1]))); \
+		break
 
 
 	// Support the basic opcodes which are typically used when computing array sizes.
 	// Support the basic opcodes which are typically used when computing array sizes.
 	switch (spec.opcode)
 	switch (spec.opcode)
 	{
 	{
-	binary_spec_op(IAdd, +);
-	binary_spec_op(ISub, -);
-	binary_spec_op(IMul, *);
-	binary_spec_op(BitwiseAnd, &);
-	binary_spec_op(BitwiseOr, |);
-	binary_spec_op(BitwiseXor, ^);
-	binary_spec_op(LogicalAnd, &);
-	binary_spec_op(LogicalOr, |);
-	binary_spec_op(ShiftLeftLogical, <<);
-	binary_spec_op(ShiftRightLogical, >>);
-	binary_spec_op_cast(ShiftRightArithmetic, >>, int32_t);
-	binary_spec_op(LogicalEqual, ==);
-	binary_spec_op(LogicalNotEqual, !=);
-	binary_spec_op(IEqual, ==);
-	binary_spec_op(INotEqual, !=);
-	binary_spec_op(ULessThan, <);
-	binary_spec_op(ULessThanEqual, <=);
-	binary_spec_op(UGreaterThan, >);
-	binary_spec_op(UGreaterThanEqual, >=);
-	binary_spec_op_cast(SLessThan, <, int32_t);
-	binary_spec_op_cast(SLessThanEqual, <=, int32_t);
-	binary_spec_op_cast(SGreaterThan, >, int32_t);
-	binary_spec_op_cast(SGreaterThanEqual, >=, int32_t);
+		binary_spec_op(IAdd, +);
+		binary_spec_op(ISub, -);
+		binary_spec_op(IMul, *);
+		binary_spec_op(BitwiseAnd, &);
+		binary_spec_op(BitwiseOr, |);
+		binary_spec_op(BitwiseXor, ^);
+		binary_spec_op(LogicalAnd, &);
+		binary_spec_op(LogicalOr, |);
+		binary_spec_op(ShiftLeftLogical, <<);
+		binary_spec_op(ShiftRightLogical, >>);
+		binary_spec_op_cast(ShiftRightArithmetic, >>, int32_t);
+		binary_spec_op(LogicalEqual, ==);
+		binary_spec_op(LogicalNotEqual, !=);
+		binary_spec_op(IEqual, ==);
+		binary_spec_op(INotEqual, !=);
+		binary_spec_op(ULessThan, <);
+		binary_spec_op(ULessThanEqual, <=);
+		binary_spec_op(UGreaterThan, >);
+		binary_spec_op(UGreaterThanEqual, >=);
+		binary_spec_op_cast(SLessThan, <, int32_t);
+		binary_spec_op_cast(SLessThanEqual, <=, int32_t);
+		binary_spec_op_cast(SGreaterThan, >, int32_t);
+		binary_spec_op_cast(SGreaterThanEqual, >=, int32_t);
 #undef binary_spec_op
 #undef binary_spec_op
 #undef binary_spec_op_cast
 #undef binary_spec_op_cast
 
 

+ 16 - 0
3rdparty/spirv-cross/spirv_cross_c.cpp

@@ -678,6 +678,22 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c
 	case SPVC_COMPILER_OPTION_MSL_R32UI_ALIGNMENT_CONSTANT_ID:
 	case SPVC_COMPILER_OPTION_MSL_R32UI_ALIGNMENT_CONSTANT_ID:
 		options->msl.r32ui_alignment_constant_id = value;
 		options->msl.r32ui_alignment_constant_id = value;
 		break;
 		break;
+
+	case SPVC_COMPILER_OPTION_MSL_IOS_USE_SIMDGROUP_FUNCTIONS:
+		options->msl.ios_use_simdgroup_functions = value != 0;
+		break;
+
+	case SPVC_COMPILER_OPTION_MSL_EMULATE_SUBGROUPS:
+		options->msl.emulate_subgroups = value != 0;
+		break;
+
+	case SPVC_COMPILER_OPTION_MSL_FIXED_SUBGROUP_SIZE:
+		options->msl.fixed_subgroup_size = value;
+		break;
+
+	case SPVC_COMPILER_OPTION_MSL_FORCE_SAMPLE_RATE_SHADING:
+		options->msl.force_sample_rate_shading = value != 0;
+		break;
 #endif
 #endif
 
 
 	default:
 	default:

+ 6 - 1
3rdparty/spirv-cross/spirv_cross_c.h

@@ -33,7 +33,7 @@ extern "C" {
 /* Bumped if ABI or API breaks backwards compatibility. */
 /* Bumped if ABI or API breaks backwards compatibility. */
 #define SPVC_C_API_VERSION_MAJOR 0
 #define SPVC_C_API_VERSION_MAJOR 0
 /* Bumped if APIs or enumerations are added in a backwards compatible way. */
 /* Bumped if APIs or enumerations are added in a backwards compatible way. */
-#define SPVC_C_API_VERSION_MINOR 42
+#define SPVC_C_API_VERSION_MINOR 44
 /* Bumped if internal implementation details change. */
 /* Bumped if internal implementation details change. */
 #define SPVC_C_API_VERSION_PATCH 0
 #define SPVC_C_API_VERSION_PATCH 0
 
 
@@ -647,6 +647,11 @@ typedef enum spvc_compiler_option
 
 
 	SPVC_COMPILER_OPTION_HLSL_FLATTEN_MATRIX_VERTEX_INPUT_SEMANTICS = 71 | SPVC_COMPILER_OPTION_HLSL_BIT,
 	SPVC_COMPILER_OPTION_HLSL_FLATTEN_MATRIX_VERTEX_INPUT_SEMANTICS = 71 | SPVC_COMPILER_OPTION_HLSL_BIT,
 
 
+	SPVC_COMPILER_OPTION_MSL_IOS_USE_SIMDGROUP_FUNCTIONS = 72 | SPVC_COMPILER_OPTION_MSL_BIT,
+	SPVC_COMPILER_OPTION_MSL_EMULATE_SUBGROUPS = 73 | SPVC_COMPILER_OPTION_MSL_BIT,
+	SPVC_COMPILER_OPTION_MSL_FIXED_SUBGROUP_SIZE = 74 | SPVC_COMPILER_OPTION_MSL_BIT,
+	SPVC_COMPILER_OPTION_MSL_FORCE_SAMPLE_RATE_SHADING = 75 | SPVC_COMPILER_OPTION_MSL_BIT,
+
 	SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
 	SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff
 } spvc_compiler_option;
 } spvc_compiler_option;
 
 

+ 2 - 1
3rdparty/spirv-cross/spirv_cross_containers.hpp

@@ -63,7 +63,8 @@ public:
 private:
 private:
 #if defined(_MSC_VER) && _MSC_VER < 1900
 #if defined(_MSC_VER) && _MSC_VER < 1900
 	// MSVC 2013 workarounds, sigh ...
 	// MSVC 2013 workarounds, sigh ...
-	union {
+	union
+	{
 		char aligned_char[sizeof(T) * N];
 		char aligned_char[sizeof(T) * N];
 		double dummy_aligner;
 		double dummy_aligner;
 	} u;
 	} u;

+ 12 - 4
3rdparty/spirv-cross/spirv_cross_parsed_ir.cpp

@@ -526,6 +526,17 @@ void ParsedIR::mark_used_as_array_length(ID id)
 	}
 	}
 }
 }
 
 
+Bitset ParsedIR::get_buffer_block_type_flags(const SPIRType &type) const
+{
+	if (type.member_types.empty())
+		return {};
+
+	Bitset all_members_flags = get_member_decoration_bitset(type.self, 0);
+	for (uint32_t i = 1; i < uint32_t(type.member_types.size()); i++)
+		all_members_flags.merge_and(get_member_decoration_bitset(type.self, i));
+	return all_members_flags;
+}
+
 Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const
 Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const
 {
 {
 	auto &type = get<SPIRType>(var.basetype);
 	auto &type = get<SPIRType>(var.basetype);
@@ -542,10 +553,7 @@ Bitset ParsedIR::get_buffer_block_flags(const SPIRVariable &var) const
 	if (type.member_types.empty())
 	if (type.member_types.empty())
 		return base_flags;
 		return base_flags;
 
 
-	Bitset all_members_flags = get_member_decoration_bitset(type.self, 0);
-	for (uint32_t i = 1; i < uint32_t(type.member_types.size()); i++)
-		all_members_flags.merge_and(get_member_decoration_bitset(type.self, i));
-
+	auto all_members_flags = get_buffer_block_type_flags(type);
 	base_flags.merge_or(all_members_flags);
 	base_flags.merge_or(all_members_flags);
 	return base_flags;
 	return base_flags;
 }
 }

+ 1 - 0
3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp

@@ -139,6 +139,7 @@ public:
 	void mark_used_as_array_length(ID id);
 	void mark_used_as_array_length(ID id);
 	uint32_t increase_bound_by(uint32_t count);
 	uint32_t increase_bound_by(uint32_t count);
 	Bitset get_buffer_block_flags(const SPIRVariable &var) const;
 	Bitset get_buffer_block_flags(const SPIRVariable &var) const;
+	Bitset get_buffer_block_type_flags(const SPIRType &type) const;
 
 
 	void add_typed_id(Types type, ID id);
 	void add_typed_id(Types type, ID id);
 	void remove_typed_id(Types type, ID id);
 	void remove_typed_id(Types type, ID id);

+ 124 - 59
3rdparty/spirv-cross/spirv_glsl.cpp

@@ -1718,8 +1718,7 @@ string CompilerGLSL::layout_for_variable(const SPIRVariable &var)
 	}
 	}
 	else if (var.storage == StorageClassOutput)
 	else if (var.storage == StorageClassOutput)
 	{
 	{
-		if (flags.get(DecorationXfbBuffer) && flags.get(DecorationXfbStride) &&
-		    flags.get(DecorationOffset))
+		if (flags.get(DecorationXfbBuffer) && flags.get(DecorationXfbStride) && flags.get(DecorationOffset))
 		{
 		{
 			// XFB for standalone variables, we can emit all decorations.
 			// XFB for standalone variables, we can emit all decorations.
 			attr.push_back(join("xfb_buffer = ", get_decoration(var.self, DecorationXfbBuffer)));
 			attr.push_back(join("xfb_buffer = ", get_decoration(var.self, DecorationXfbBuffer)));
@@ -2013,6 +2012,9 @@ void CompilerGLSL::emit_buffer_reference_block(SPIRType &type, bool forward_decl
 
 
 		block_names.insert(buffer_name);
 		block_names.insert(buffer_name);
 		block_ssbo_names.insert(buffer_name);
 		block_ssbo_names.insert(buffer_name);
+
+		// Ensure we emit the correct name when emitting non-forward pointer type.
+		ir.meta[type.self].decoration.alias = buffer_name;
 	}
 	}
 	else if (type.basetype != SPIRType::Struct)
 	else if (type.basetype != SPIRType::Struct)
 		buffer_name = type_to_glsl(type);
 		buffer_name = type_to_glsl(type);
@@ -2022,7 +2024,20 @@ void CompilerGLSL::emit_buffer_reference_block(SPIRType &type, bool forward_decl
 	if (!forward_declaration)
 	if (!forward_declaration)
 	{
 	{
 		if (type.basetype == SPIRType::Struct)
 		if (type.basetype == SPIRType::Struct)
-			statement("layout(buffer_reference, ", buffer_to_packing_standard(type, true), ") buffer ", buffer_name);
+		{
+			auto flags = ir.get_buffer_block_type_flags(type);
+			string decorations;
+			if (flags.get(DecorationRestrict))
+				decorations += " restrict";
+			if (flags.get(DecorationCoherent))
+				decorations += " coherent";
+			if (flags.get(DecorationNonReadable))
+				decorations += " writeonly";
+			if (flags.get(DecorationNonWritable))
+				decorations += " readonly";
+			statement("layout(buffer_reference, ", buffer_to_packing_standard(type, true),
+			          ")", decorations, " buffer ", buffer_name);
+		}
 		else
 		else
 			statement("layout(buffer_reference) buffer ", buffer_name);
 			statement("layout(buffer_reference) buffer ", buffer_name);
 
 
@@ -2306,6 +2321,12 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var)
 {
 {
 	auto &type = get<SPIRType>(var.basetype);
 	auto &type = get<SPIRType>(var.basetype);
 
 
+	if (var.storage == StorageClassInput && type.basetype == SPIRType::Double &&
+	    !options.es && options.version < 410)
+	{
+		require_extension_internal("GL_ARB_vertex_attrib_64bit");
+	}
+
 	// Either make it plain in/out or in/out blocks depending on what shader is doing ...
 	// Either make it plain in/out or in/out blocks depending on what shader is doing ...
 	bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock);
 	bool block = ir.meta[type.self].decoration.decoration_flags.get(DecorationBlock);
 	const char *qual = to_storage_qualifiers_glsl(var);
 	const char *qual = to_storage_qualifiers_glsl(var);
@@ -3399,10 +3420,8 @@ void CompilerGLSL::emit_resources()
 
 
 void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model)
 void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model)
 {
 {
-	static const char *workaround_types[] = {
-		"int", "ivec2", "ivec3", "ivec4", "uint", "uvec2", "uvec3", "uvec4",
-		"float", "vec2",  "vec3",  "vec4",  "double", "dvec2", "dvec3", "dvec4"
-	};
+	static const char *workaround_types[] = { "int",   "ivec2", "ivec3", "ivec4", "uint",   "uvec2", "uvec3", "uvec4",
+		                                      "float", "vec2",  "vec3",  "vec4",  "double", "dvec2", "dvec3", "dvec4" };
 
 
 	if (!options.vulkan_semantics)
 	if (!options.vulkan_semantics)
 	{
 	{
@@ -3809,7 +3828,7 @@ void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model)
 		for (auto &type_id : workaround_ubo_load_overload_types)
 		for (auto &type_id : workaround_ubo_load_overload_types)
 		{
 		{
 			auto &type = get<SPIRType>(type_id);
 			auto &type = get<SPIRType>(type_id);
-			statement(type_to_glsl(type), " SPIRV_Cross_workaround_load_row_major(", type_to_glsl(type),
+			statement(type_to_glsl(type), " spvWorkaroundRowMajor(", type_to_glsl(type),
 			          " wrap) { return wrap; }");
 			          " wrap) { return wrap; }");
 		}
 		}
 		statement("");
 		statement("");
@@ -3817,7 +3836,7 @@ void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model)
 
 
 	if (requires_transpose_2x2)
 	if (requires_transpose_2x2)
 	{
 	{
-		statement("mat2 SPIRV_Cross_Transpose(mat2 m)");
+		statement("mat2 spvTranspose(mat2 m)");
 		begin_scope();
 		begin_scope();
 		statement("return mat2(m[0][0], m[1][0], m[0][1], m[1][1]);");
 		statement("return mat2(m[0][0], m[1][0], m[0][1], m[1][1]);");
 		end_scope();
 		end_scope();
@@ -3826,7 +3845,7 @@ void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model)
 
 
 	if (requires_transpose_3x3)
 	if (requires_transpose_3x3)
 	{
 	{
-		statement("mat3 SPIRV_Cross_Transpose(mat3 m)");
+		statement("mat3 spvTranspose(mat3 m)");
 		begin_scope();
 		begin_scope();
 		statement("return mat3(m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]);");
 		statement("return mat3(m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]);");
 		end_scope();
 		end_scope();
@@ -3835,9 +3854,10 @@ void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model)
 
 
 	if (requires_transpose_4x4)
 	if (requires_transpose_4x4)
 	{
 	{
-		statement("mat4 SPIRV_Cross_Transpose(mat4 m)");
+		statement("mat4 spvTranspose(mat4 m)");
 		begin_scope();
 		begin_scope();
-		statement("return mat4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);");
+		statement("return mat4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], "
+		          "m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);");
 		end_scope();
 		end_scope();
 		statement("");
 		statement("");
 	}
 	}
@@ -5726,7 +5746,8 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp
 	// GLES has very limited support for shadow samplers.
 	// GLES has very limited support for shadow samplers.
 	// Basically shadow2D and shadow2DProj work through EXT_shadow_samplers,
 	// Basically shadow2D and shadow2DProj work through EXT_shadow_samplers,
 	// everything else can just throw
 	// everything else can just throw
-	if (image_is_comparison(imgtype, tex) && is_legacy_es())
+	bool is_comparison = image_is_comparison(imgtype, tex);
+	if (is_comparison && is_legacy_es())
 	{
 	{
 		if (op == "texture" || op == "textureProj")
 		if (op == "texture" || op == "textureProj")
 			require_extension_internal("GL_EXT_shadow_samplers");
 			require_extension_internal("GL_EXT_shadow_samplers");
@@ -5734,8 +5755,20 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp
 			SPIRV_CROSS_THROW(join(op, " not allowed on depth samplers in legacy ES"));
 			SPIRV_CROSS_THROW(join(op, " not allowed on depth samplers in legacy ES"));
 	}
 	}
 
 
-	bool is_es_and_depth = is_legacy_es() && image_is_comparison(imgtype, tex);
-	std::string type_prefix = image_is_comparison(imgtype, tex) ? "shadow" : "texture";
+	if (op == "textureSize")
+	{
+		if (is_legacy_es())
+			SPIRV_CROSS_THROW("textureSize not supported in legacy ES");
+		if (is_comparison)
+			SPIRV_CROSS_THROW("textureSize not supported on shadow sampler in legacy GLSL");
+		require_extension_internal("GL_EXT_gpu_shader4");
+	}
+
+	if (op == "texelFetch" && is_legacy_es())
+		SPIRV_CROSS_THROW("texelFetch not supported in legacy ES");
+
+	bool is_es_and_depth = is_legacy_es() && is_comparison;
+	std::string type_prefix = is_comparison ? "shadow" : "texture";
 
 
 	if (op == "texture")
 	if (op == "texture")
 		return is_es_and_depth ? join(type_prefix, type, "EXT") : join(type_prefix, type);
 		return is_es_and_depth ? join(type_prefix, type, "EXT") : join(type_prefix, type);
@@ -5754,6 +5787,10 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp
 		            is_legacy_es() ? "ProjGradEXT" : is_legacy_desktop() ? "ProjGradARB" : "ProjGrad");
 		            is_legacy_es() ? "ProjGradEXT" : is_legacy_desktop() ? "ProjGradARB" : "ProjGrad");
 	else if (op == "textureProjLodOffset")
 	else if (op == "textureProjLodOffset")
 		return join(type_prefix, type, "ProjLodOffset");
 		return join(type_prefix, type, "ProjLodOffset");
+	else if (op == "textureSize")
+		return join("textureSize", type);
+	else if (op == "texelFetch")
+		return join("texelFetch", type);
 	else
 	else
 	{
 	{
 		SPIRV_CROSS_THROW(join("Unsupported legacy texture op: ", op));
 		SPIRV_CROSS_THROW(join("Unsupported legacy texture op: ", op));
@@ -6162,6 +6199,10 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool
 		opt = &ops[5];
 		opt = &ops[5];
 		length -= 5;
 		length -= 5;
 		gather = true;
 		gather = true;
+		if (options.es && options.version < 310)
+			SPIRV_CROSS_THROW("textureGather requires ESSL 310.");
+		else if (!options.es && options.version < 400)
+			SPIRV_CROSS_THROW("textureGather with depth compare requires GLSL 400.");
 		break;
 		break;
 
 
 	case OpImageGather:
 	case OpImageGather:
@@ -6170,6 +6211,14 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool
 		opt = &ops[5];
 		opt = &ops[5];
 		length -= 5;
 		length -= 5;
 		gather = true;
 		gather = true;
+		if (options.es && options.version < 310)
+			SPIRV_CROSS_THROW("textureGather requires ESSL 310.");
+		else if (!options.es && options.version < 400)
+		{
+			if (!expression_is_constant_null(comp))
+				SPIRV_CROSS_THROW("textureGather with component requires GLSL 400.");
+			require_extension_internal("GL_ARB_texture_gather");
+		}
 		break;
 		break;
 
 
 	case OpImageFetch:
 	case OpImageFetch:
@@ -6438,7 +6487,7 @@ string CompilerGLSL::to_function_name(const TextureFunctionNameArguments &args)
 	if (args.is_sparse_feedback || args.has_min_lod)
 	if (args.is_sparse_feedback || args.has_min_lod)
 		fname += "ARB";
 		fname += "ARB";
 
 
-	return is_legacy() ? legacy_tex_op(fname, imgtype, tex) : fname;
+	return (is_legacy() && !args.base.is_gather) ? legacy_tex_op(fname, imgtype, tex) : fname;
 }
 }
 
 
 std::string CompilerGLSL::convert_separate_image_to_expression(uint32_t id)
 std::string CompilerGLSL::convert_separate_image_to_expression(uint32_t id)
@@ -6685,7 +6734,7 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool
 		farg_str += to_expression(args.bias);
 		farg_str += to_expression(args.bias);
 	}
 	}
 
 
-	if (args.component)
+	if (args.component && !expression_is_constant_null(args.component))
 	{
 	{
 		forward = forward && should_forward(args.component);
 		forward = forward && should_forward(args.component);
 		farg_str += ", ";
 		farg_str += ", ";
@@ -10488,7 +10537,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
 	{
 	{
 		auto &type = get<SPIRType>(ops[0]);
 		auto &type = get<SPIRType>(ops[0]);
 		if (type.vecsize > 1)
 		if (type.vecsize > 1)
-			GLSL_UFOP(not);
+			GLSL_UFOP(not );
 		else
 		else
 			GLSL_UOP(!);
 			GLSL_UOP(!);
 		break;
 		break;
@@ -11151,8 +11200,19 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
 	{
 	{
 		uint32_t result_type = ops[0];
 		uint32_t result_type = ops[0];
 		uint32_t id = ops[1];
 		uint32_t id = ops[1];
+		uint32_t img = ops[2];
 
 
-		auto expr = join("textureSize(", convert_separate_image_to_expression(ops[2]), ", ",
+		std::string fname = "textureSize";
+		if (is_legacy_desktop())
+		{
+			auto &type = expression_type(img);
+			auto &imgtype = get<SPIRType>(type.self);
+			fname = legacy_tex_op(fname, imgtype, img);
+		}
+		else if (is_legacy_es())
+			SPIRV_CROSS_THROW("textureSize is not supported in ESSL 100.");
+
+		auto expr = join(fname, "(", convert_separate_image_to_expression(img), ", ",
 		                 bitcast_expression(SPIRType::Int, ops[3]), ")");
 		                 bitcast_expression(SPIRType::Int, ops[3]), ")");
 		auto &restype = get<SPIRType>(ops[0]);
 		auto &restype = get<SPIRType>(ops[0]);
 		expr = bitcast_expression(restype, SPIRType::Int, expr);
 		expr = bitcast_expression(restype, SPIRType::Int, expr);
@@ -11413,13 +11473,24 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
 			string expr;
 			string expr;
 			if (type.image.sampled == 2)
 			if (type.image.sampled == 2)
 			{
 			{
+				if (!options.es && options.version < 430)
+					require_extension_internal("GL_ARB_shader_image_size");
+				else if (options.es && options.version < 310)
+					SPIRV_CROSS_THROW("At least ESSL 3.10 required for imageSize.");
+
 				// The size of an image is always constant.
 				// The size of an image is always constant.
 				expr = join("imageSize(", to_expression(ops[2]), ")");
 				expr = join("imageSize(", to_expression(ops[2]), ")");
 			}
 			}
 			else
 			else
 			{
 			{
 				// This path is hit for samplerBuffers and multisampled images which do not have LOD.
 				// This path is hit for samplerBuffers and multisampled images which do not have LOD.
-				expr = join("textureSize(", convert_separate_image_to_expression(ops[2]), ")");
+				std::string fname = "textureSize";
+				if (is_legacy())
+				{
+					auto &imgtype = get<SPIRType>(type.self);
+					fname = legacy_tex_op(fname, imgtype, ops[2]);
+				}
+				expr = join(fname, "(", convert_separate_image_to_expression(ops[2]), ")");
 			}
 			}
 
 
 			auto &restype = get<SPIRType>(ops[0]);
 			auto &restype = get<SPIRType>(ops[0]);
@@ -12199,7 +12270,7 @@ string CompilerGLSL::convert_row_major_matrix(string exp_str, const SPIRType &ex
 		}
 		}
 		else
 		else
 			SPIRV_CROSS_THROW("Non-square matrices are not supported in legacy GLSL, cannot transpose.");
 			SPIRV_CROSS_THROW("Non-square matrices are not supported in legacy GLSL, cannot transpose.");
-		return join("SPIRV_Cross_Transpose(", exp_str, ")");
+		return join("spvTranspose(", exp_str, ")");
 	}
 	}
 	else
 	else
 		return join("transpose(", exp_str, ")");
 		return join("transpose(", exp_str, ")");
@@ -14177,8 +14248,8 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
 			if (is_legacy_es())
 			if (is_legacy_es())
 			{
 			{
 				uint32_t counter = statement_count;
 				uint32_t counter = statement_count;
-				statement("for (int SPIRV_Cross_Dummy", counter, " = 0; SPIRV_Cross_Dummy", counter,
-				          " < 1; SPIRV_Cross_Dummy", counter, "++)");
+				statement("for (int spvDummy", counter, " = 0; spvDummy", counter,
+				          " < 1; spvDummy", counter, "++)");
 			}
 			}
 			else
 			else
 				statement("do");
 				statement("do");
@@ -14304,7 +14375,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
 				// The backend is responsible for setting this up, and redirection the return values as appropriate.
 				// The backend is responsible for setting this up, and redirection the return values as appropriate.
 				if (ir.ids[block.return_value].get_type() != TypeUndef)
 				if (ir.ids[block.return_value].get_type() != TypeUndef)
 				{
 				{
-					emit_array_copy("SPIRV_Cross_return_value", block.return_value, StorageClassFunction,
+					emit_array_copy("spvReturnValue", block.return_value, StorageClassFunction,
 					                get_expression_effective_storage_class(block.return_value));
 					                get_expression_effective_storage_class(block.return_value));
 				}
 				}
 
 
@@ -15006,17 +15077,15 @@ bool CompilerGLSL::variable_is_depth_or_compare(VariableID id) const
 
 
 const char *CompilerGLSL::ShaderSubgroupSupportHelper::get_extension_name(Candidate c)
 const char *CompilerGLSL::ShaderSubgroupSupportHelper::get_extension_name(Candidate c)
 {
 {
-	static const char * const retval[CandidateCount] = {
-		"GL_KHR_shader_subgroup_ballot",
-		"GL_KHR_shader_subgroup_basic",
-		"GL_KHR_shader_subgroup_vote",
-		"GL_NV_gpu_shader_5",
-		"GL_NV_shader_thread_group",
-		"GL_NV_shader_thread_shuffle",
-		"GL_ARB_shader_ballot",
-		"GL_ARB_shader_group_vote",
-		"GL_AMD_gcn_shader"
-	};
+	static const char *const retval[CandidateCount] = { "GL_KHR_shader_subgroup_ballot",
+		                                                "GL_KHR_shader_subgroup_basic",
+		                                                "GL_KHR_shader_subgroup_vote",
+		                                                "GL_NV_gpu_shader_5",
+		                                                "GL_NV_shader_thread_group",
+		                                                "GL_NV_shader_thread_shuffle",
+		                                                "GL_ARB_shader_ballot",
+		                                                "GL_ARB_shader_group_vote",
+		                                                "GL_AMD_gcn_shader" };
 	return retval[c];
 	return retval[c];
 }
 }
 
 
@@ -15046,8 +15115,8 @@ const char *CompilerGLSL::ShaderSubgroupSupportHelper::get_extra_required_extens
 	}
 	}
 }
 }
 
 
-CompilerGLSL::ShaderSubgroupSupportHelper::FeatureVector
-CompilerGLSL::ShaderSubgroupSupportHelper::get_feature_dependencies(Feature feature)
+CompilerGLSL::ShaderSubgroupSupportHelper::FeatureVector CompilerGLSL::ShaderSubgroupSupportHelper::
+    get_feature_dependencies(Feature feature)
 {
 {
 	switch (feature)
 	switch (feature)
 	{
 	{
@@ -15064,27 +15133,25 @@ CompilerGLSL::ShaderSubgroupSupportHelper::get_feature_dependencies(Feature feat
 	}
 	}
 }
 }
 
 
-CompilerGLSL::ShaderSubgroupSupportHelper::FeatureMask
-CompilerGLSL::ShaderSubgroupSupportHelper::get_feature_dependency_mask(Feature feature)
+CompilerGLSL::ShaderSubgroupSupportHelper::FeatureMask CompilerGLSL::ShaderSubgroupSupportHelper::
+    get_feature_dependency_mask(Feature feature)
 {
 {
 	return build_mask(get_feature_dependencies(feature));
 	return build_mask(get_feature_dependencies(feature));
 }
 }
 
 
 bool CompilerGLSL::ShaderSubgroupSupportHelper::can_feature_be_implemented_without_extensions(Feature feature)
 bool CompilerGLSL::ShaderSubgroupSupportHelper::can_feature_be_implemented_without_extensions(Feature feature)
 {
 {
-	static const bool retval[FeatureCount] = {
-		false, false, false, false, false, false,
-		true, // SubgroupBalloFindLSB_MSB
-		false, false, false, false,
-		true, // SubgroupMemBarrier - replaced with workgroup memory barriers
-		false, false, true,  false
-	};
+	static const bool retval[FeatureCount] = { false, false, false, false, false, false,
+		                                       true, // SubgroupBalloFindLSB_MSB
+		                                       false, false, false, false,
+		                                       true, // SubgroupMemBarrier - replaced with workgroup memory barriers
+		                                       false, false, true,  false };
 
 
 	return retval[feature];
 	return retval[feature];
 }
 }
 
 
-CompilerGLSL::ShaderSubgroupSupportHelper::Candidate
-CompilerGLSL::ShaderSubgroupSupportHelper::get_KHR_extension_for_feature(Feature feature)
+CompilerGLSL::ShaderSubgroupSupportHelper::Candidate CompilerGLSL::ShaderSubgroupSupportHelper::
+    get_KHR_extension_for_feature(Feature feature)
 {
 {
 	static const Candidate extensions[FeatureCount] = {
 	static const Candidate extensions[FeatureCount] = {
 		KHR_shader_subgroup_ballot, KHR_shader_subgroup_basic,  KHR_shader_subgroup_basic,  KHR_shader_subgroup_basic,
 		KHR_shader_subgroup_ballot, KHR_shader_subgroup_basic,  KHR_shader_subgroup_basic,  KHR_shader_subgroup_basic,
@@ -15106,8 +15173,7 @@ bool CompilerGLSL::ShaderSubgroupSupportHelper::is_feature_requested(Feature fea
 	return (feature_mask & (1u << feature)) != 0;
 	return (feature_mask & (1u << feature)) != 0;
 }
 }
 
 
-CompilerGLSL::ShaderSubgroupSupportHelper::Result
-CompilerGLSL::ShaderSubgroupSupportHelper::resolve() const
+CompilerGLSL::ShaderSubgroupSupportHelper::Result CompilerGLSL::ShaderSubgroupSupportHelper::resolve() const
 {
 {
 	Result res;
 	Result res;
 
 
@@ -15137,8 +15203,8 @@ CompilerGLSL::ShaderSubgroupSupportHelper::resolve() const
 	return res;
 	return res;
 }
 }
 
 
-CompilerGLSL::ShaderSubgroupSupportHelper::CandidateVector
-CompilerGLSL::ShaderSubgroupSupportHelper::get_candidates_for_feature(Feature ft, const Result &r)
+CompilerGLSL::ShaderSubgroupSupportHelper::CandidateVector CompilerGLSL::ShaderSubgroupSupportHelper::
+    get_candidates_for_feature(Feature ft, const Result &r)
 {
 {
 	auto c = get_candidates_for_feature(ft);
 	auto c = get_candidates_for_feature(ft);
 	auto cmp = [&r](Candidate a, Candidate b) {
 	auto cmp = [&r](Candidate a, Candidate b) {
@@ -15150,8 +15216,8 @@ CompilerGLSL::ShaderSubgroupSupportHelper::get_candidates_for_feature(Feature ft
 	return c;
 	return c;
 }
 }
 
 
-CompilerGLSL::ShaderSubgroupSupportHelper::CandidateVector
-CompilerGLSL::ShaderSubgroupSupportHelper::get_candidates_for_feature(Feature feature)
+CompilerGLSL::ShaderSubgroupSupportHelper::CandidateVector CompilerGLSL::ShaderSubgroupSupportHelper::
+    get_candidates_for_feature(Feature feature)
 {
 {
 	switch (feature)
 	switch (feature)
 	{
 	{
@@ -15192,8 +15258,8 @@ CompilerGLSL::ShaderSubgroupSupportHelper::get_candidates_for_feature(Feature fe
 	}
 	}
 }
 }
 
 
-CompilerGLSL::ShaderSubgroupSupportHelper::FeatureMask
-CompilerGLSL::ShaderSubgroupSupportHelper::build_mask(const SmallVector<Feature> &features)
+CompilerGLSL::ShaderSubgroupSupportHelper::FeatureMask CompilerGLSL::ShaderSubgroupSupportHelper::build_mask(
+    const SmallVector<Feature> &features)
 {
 {
 	FeatureMask mask = 0;
 	FeatureMask mask = 0;
 	for (Feature f : features)
 	for (Feature f : features)
@@ -15234,8 +15300,7 @@ void CompilerGLSL::rewrite_load_for_wrapped_row_major(std::string &expr, TypeID
 		return;
 		return;
 
 
 	auto &backing_type = get<SPIRType>(var->basetype);
 	auto &backing_type = get<SPIRType>(var->basetype);
-	bool is_ubo = backing_type.basetype == SPIRType::Struct &&
-	              backing_type.storage == StorageClassUniform &&
+	bool is_ubo = backing_type.basetype == SPIRType::Struct && backing_type.storage == StorageClassUniform &&
 	              has_decoration(backing_type.self, DecorationBlock);
 	              has_decoration(backing_type.self, DecorationBlock);
 	if (!is_ubo)
 	if (!is_ubo)
 		return;
 		return;
@@ -15269,6 +15334,6 @@ void CompilerGLSL::rewrite_load_for_wrapped_row_major(std::string &expr, TypeID
 	if (rewrite)
 	if (rewrite)
 	{
 	{
 		request_workaround_wrapper_overload(loaded_type);
 		request_workaround_wrapper_overload(loaded_type);
-		expr = join("SPIRV_Cross_workaround_load_row_major(", expr, ")");
+		expr = join("spvWorkaroundRowMajor(", expr, ")");
 	}
 	}
 }
 }

+ 0 - 1
3rdparty/spirv-cross/spirv_glsl.hpp

@@ -243,7 +243,6 @@ public:
 	// - Images which are statically used at least once with Dref opcodes.
 	// - Images which are statically used at least once with Dref opcodes.
 	bool variable_is_depth_or_compare(VariableID id) const;
 	bool variable_is_depth_or_compare(VariableID id) const;
 
 
-
 protected:
 protected:
 	struct ShaderSubgroupSupportHelper
 	struct ShaderSubgroupSupportHelper
 	{
 	{

+ 87 - 86
3rdparty/spirv-cross/spirv_hlsl.cpp

@@ -1234,8 +1234,7 @@ void CompilerHLSL::declare_undefined_values()
 		if (options.force_zero_initialized_variables && type_can_zero_initialize(type))
 		if (options.force_zero_initialized_variables && type_can_zero_initialize(type))
 			initializer = join(" = ", to_zero_initialized_expression(undef.basetype));
 			initializer = join(" = ", to_zero_initialized_expression(undef.basetype));
 
 
-		statement("static ", variable_decl(type, to_name(undef.self), undef.self),
-		          initializer, ";");
+		statement("static ", variable_decl(type, to_name(undef.self), undef.self), initializer, ";");
 		emitted = true;
 		emitted = true;
 	});
 	});
 
 
@@ -1529,14 +1528,14 @@ void CompilerHLSL::emit_resources()
 	if (requires_fp16_packing)
 	if (requires_fp16_packing)
 	{
 	{
 		// HLSL does not pack into a single word sadly :(
 		// HLSL does not pack into a single word sadly :(
-		statement("uint SPIRV_Cross_packHalf2x16(float2 value)");
+		statement("uint spvPackHalf2x16(float2 value)");
 		begin_scope();
 		begin_scope();
 		statement("uint2 Packed = f32tof16(value);");
 		statement("uint2 Packed = f32tof16(value);");
 		statement("return Packed.x | (Packed.y << 16);");
 		statement("return Packed.x | (Packed.y << 16);");
 		end_scope();
 		end_scope();
 		statement("");
 		statement("");
 
 
-		statement("float2 SPIRV_Cross_unpackHalf2x16(uint value)");
+		statement("float2 spvUnpackHalf2x16(uint value)");
 		begin_scope();
 		begin_scope();
 		statement("return f16tof32(uint2(value & 0xffff, value >> 16));");
 		statement("return f16tof32(uint2(value & 0xffff, value >> 16));");
 		end_scope();
 		end_scope();
@@ -1545,13 +1544,13 @@ void CompilerHLSL::emit_resources()
 
 
 	if (requires_uint2_packing)
 	if (requires_uint2_packing)
 	{
 	{
-		statement("uint64_t SPIRV_Cross_packUint2x32(uint2 value)");
+		statement("uint64_t spvPackUint2x32(uint2 value)");
 		begin_scope();
 		begin_scope();
 		statement("return (uint64_t(value.y) << 32) | uint64_t(value.x);");
 		statement("return (uint64_t(value.y) << 32) | uint64_t(value.x);");
 		end_scope();
 		end_scope();
 		statement("");
 		statement("");
 
 
-		statement("uint2 SPIRV_Cross_unpackUint2x32(uint64_t value)");
+		statement("uint2 spvUnpackUint2x32(uint64_t value)");
 		begin_scope();
 		begin_scope();
 		statement("uint2 Unpacked;");
 		statement("uint2 Unpacked;");
 		statement("Unpacked.x = uint(value & 0xffffffff);");
 		statement("Unpacked.x = uint(value & 0xffffffff);");
@@ -1564,14 +1563,14 @@ void CompilerHLSL::emit_resources()
 	if (requires_explicit_fp16_packing)
 	if (requires_explicit_fp16_packing)
 	{
 	{
 		// HLSL does not pack into a single word sadly :(
 		// HLSL does not pack into a single word sadly :(
-		statement("uint SPIRV_Cross_packFloat2x16(min16float2 value)");
+		statement("uint spvPackFloat2x16(min16float2 value)");
 		begin_scope();
 		begin_scope();
 		statement("uint2 Packed = f32tof16(value);");
 		statement("uint2 Packed = f32tof16(value);");
 		statement("return Packed.x | (Packed.y << 16);");
 		statement("return Packed.x | (Packed.y << 16);");
 		end_scope();
 		end_scope();
 		statement("");
 		statement("");
 
 
-		statement("min16float2 SPIRV_Cross_unpackFloat2x16(uint value)");
+		statement("min16float2 spvUnpackFloat2x16(uint value)");
 		begin_scope();
 		begin_scope();
 		statement("return min16float2(f16tof32(uint2(value & 0xffff, value >> 16)));");
 		statement("return min16float2(f16tof32(uint2(value & 0xffff, value >> 16)));");
 		end_scope();
 		end_scope();
@@ -1581,14 +1580,14 @@ void CompilerHLSL::emit_resources()
 	// HLSL does not seem to have builtins for these operation, so roll them by hand ...
 	// HLSL does not seem to have builtins for these operation, so roll them by hand ...
 	if (requires_unorm8_packing)
 	if (requires_unorm8_packing)
 	{
 	{
-		statement("uint SPIRV_Cross_packUnorm4x8(float4 value)");
+		statement("uint spvPackUnorm4x8(float4 value)");
 		begin_scope();
 		begin_scope();
 		statement("uint4 Packed = uint4(round(saturate(value) * 255.0));");
 		statement("uint4 Packed = uint4(round(saturate(value) * 255.0));");
 		statement("return Packed.x | (Packed.y << 8) | (Packed.z << 16) | (Packed.w << 24);");
 		statement("return Packed.x | (Packed.y << 8) | (Packed.z << 16) | (Packed.w << 24);");
 		end_scope();
 		end_scope();
 		statement("");
 		statement("");
 
 
-		statement("float4 SPIRV_Cross_unpackUnorm4x8(uint value)");
+		statement("float4 spvUnpackUnorm4x8(uint value)");
 		begin_scope();
 		begin_scope();
 		statement("uint4 Packed = uint4(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, value >> 24);");
 		statement("uint4 Packed = uint4(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, value >> 24);");
 		statement("return float4(Packed) / 255.0;");
 		statement("return float4(Packed) / 255.0;");
@@ -1598,14 +1597,14 @@ void CompilerHLSL::emit_resources()
 
 
 	if (requires_snorm8_packing)
 	if (requires_snorm8_packing)
 	{
 	{
-		statement("uint SPIRV_Cross_packSnorm4x8(float4 value)");
+		statement("uint spvPackSnorm4x8(float4 value)");
 		begin_scope();
 		begin_scope();
 		statement("int4 Packed = int4(round(clamp(value, -1.0, 1.0) * 127.0)) & 0xff;");
 		statement("int4 Packed = int4(round(clamp(value, -1.0, 1.0) * 127.0)) & 0xff;");
 		statement("return uint(Packed.x | (Packed.y << 8) | (Packed.z << 16) | (Packed.w << 24));");
 		statement("return uint(Packed.x | (Packed.y << 8) | (Packed.z << 16) | (Packed.w << 24));");
 		end_scope();
 		end_scope();
 		statement("");
 		statement("");
 
 
-		statement("float4 SPIRV_Cross_unpackSnorm4x8(uint value)");
+		statement("float4 spvUnpackSnorm4x8(uint value)");
 		begin_scope();
 		begin_scope();
 		statement("int SignedValue = int(value);");
 		statement("int SignedValue = int(value);");
 		statement("int4 Packed = int4(SignedValue << 24, SignedValue << 16, SignedValue << 8, SignedValue) >> 24;");
 		statement("int4 Packed = int4(SignedValue << 24, SignedValue << 16, SignedValue << 8, SignedValue) >> 24;");
@@ -1616,14 +1615,14 @@ void CompilerHLSL::emit_resources()
 
 
 	if (requires_unorm16_packing)
 	if (requires_unorm16_packing)
 	{
 	{
-		statement("uint SPIRV_Cross_packUnorm2x16(float2 value)");
+		statement("uint spvPackUnorm2x16(float2 value)");
 		begin_scope();
 		begin_scope();
 		statement("uint2 Packed = uint2(round(saturate(value) * 65535.0));");
 		statement("uint2 Packed = uint2(round(saturate(value) * 65535.0));");
 		statement("return Packed.x | (Packed.y << 16);");
 		statement("return Packed.x | (Packed.y << 16);");
 		end_scope();
 		end_scope();
 		statement("");
 		statement("");
 
 
-		statement("float2 SPIRV_Cross_unpackUnorm2x16(uint value)");
+		statement("float2 spvUnpackUnorm2x16(uint value)");
 		begin_scope();
 		begin_scope();
 		statement("uint2 Packed = uint2(value & 0xffff, value >> 16);");
 		statement("uint2 Packed = uint2(value & 0xffff, value >> 16);");
 		statement("return float2(Packed) / 65535.0;");
 		statement("return float2(Packed) / 65535.0;");
@@ -1633,14 +1632,14 @@ void CompilerHLSL::emit_resources()
 
 
 	if (requires_snorm16_packing)
 	if (requires_snorm16_packing)
 	{
 	{
-		statement("uint SPIRV_Cross_packSnorm2x16(float2 value)");
+		statement("uint spvPackSnorm2x16(float2 value)");
 		begin_scope();
 		begin_scope();
 		statement("int2 Packed = int2(round(clamp(value, -1.0, 1.0) * 32767.0)) & 0xffff;");
 		statement("int2 Packed = int2(round(clamp(value, -1.0, 1.0) * 32767.0)) & 0xffff;");
 		statement("return uint(Packed.x | (Packed.y << 16));");
 		statement("return uint(Packed.x | (Packed.y << 16));");
 		end_scope();
 		end_scope();
 		statement("");
 		statement("");
 
 
-		statement("float2 SPIRV_Cross_unpackSnorm2x16(uint value)");
+		statement("float2 spvUnpackSnorm2x16(uint value)");
 		begin_scope();
 		begin_scope();
 		statement("int SignedValue = int(value);");
 		statement("int SignedValue = int(value);");
 		statement("int2 Packed = int2(SignedValue << 16, SignedValue) >> 16;");
 		statement("int2 Packed = int2(SignedValue << 16, SignedValue) >> 16;");
@@ -1654,7 +1653,7 @@ void CompilerHLSL::emit_resources()
 		static const char *types[] = { "uint", "uint2", "uint3", "uint4" };
 		static const char *types[] = { "uint", "uint2", "uint3", "uint4" };
 		for (auto &type : types)
 		for (auto &type : types)
 		{
 		{
-			statement(type, " SPIRV_Cross_bitfieldInsert(", type, " Base, ", type, " Insert, uint Offset, uint Count)");
+			statement(type, " spvBitfieldInsert(", type, " Base, ", type, " Insert, uint Offset, uint Count)");
 			begin_scope();
 			begin_scope();
 			statement("uint Mask = Count == 32 ? 0xffffffff : (((1u << Count) - 1) << (Offset & 31));");
 			statement("uint Mask = Count == 32 ? 0xffffffff : (((1u << Count) - 1) << (Offset & 31));");
 			statement("return (Base & ~Mask) | ((Insert << Offset) & Mask);");
 			statement("return (Base & ~Mask) | ((Insert << Offset) & Mask);");
@@ -1668,7 +1667,7 @@ void CompilerHLSL::emit_resources()
 		static const char *unsigned_types[] = { "uint", "uint2", "uint3", "uint4" };
 		static const char *unsigned_types[] = { "uint", "uint2", "uint3", "uint4" };
 		for (auto &type : unsigned_types)
 		for (auto &type : unsigned_types)
 		{
 		{
-			statement(type, " SPIRV_Cross_bitfieldUExtract(", type, " Base, uint Offset, uint Count)");
+			statement(type, " spvBitfieldUExtract(", type, " Base, uint Offset, uint Count)");
 			begin_scope();
 			begin_scope();
 			statement("uint Mask = Count == 32 ? 0xffffffff : ((1 << Count) - 1);");
 			statement("uint Mask = Count == 32 ? 0xffffffff : ((1 << Count) - 1);");
 			statement("return (Base >> Offset) & Mask;");
 			statement("return (Base >> Offset) & Mask;");
@@ -1680,7 +1679,7 @@ void CompilerHLSL::emit_resources()
 		static const char *signed_types[] = { "int", "int2", "int3", "int4" };
 		static const char *signed_types[] = { "int", "int2", "int3", "int4" };
 		for (auto &type : signed_types)
 		for (auto &type : signed_types)
 		{
 		{
-			statement(type, " SPIRV_Cross_bitfieldSExtract(", type, " Base, int Offset, int Count)");
+			statement(type, " spvBitfieldSExtract(", type, " Base, int Offset, int Count)");
 			begin_scope();
 			begin_scope();
 			statement("int Mask = Count == 32 ? -1 : ((1 << Count) - 1);");
 			statement("int Mask = Count == 32 ? -1 : ((1 << Count) - 1);");
 			statement(type, " Masked = (Base >> Offset) & Mask;");
 			statement(type, " Masked = (Base >> Offset) & Mask;");
@@ -1695,7 +1694,7 @@ void CompilerHLSL::emit_resources()
 	{
 	{
 		statement("// Returns the inverse of a matrix, by using the algorithm of calculating the classical");
 		statement("// Returns the inverse of a matrix, by using the algorithm of calculating the classical");
 		statement("// adjoint and dividing by the determinant. The contents of the matrix are changed.");
 		statement("// adjoint and dividing by the determinant. The contents of the matrix are changed.");
-		statement("float2x2 SPIRV_Cross_Inverse(float2x2 m)");
+		statement("float2x2 spvInverse(float2x2 m)");
 		begin_scope();
 		begin_scope();
 		statement("float2x2 adj;	// The adjoint matrix (inverse after dividing by determinant)");
 		statement("float2x2 adj;	// The adjoint matrix (inverse after dividing by determinant)");
 		statement_no_indent("");
 		statement_no_indent("");
@@ -1719,29 +1718,29 @@ void CompilerHLSL::emit_resources()
 	if (requires_inverse_3x3)
 	if (requires_inverse_3x3)
 	{
 	{
 		statement("// Returns the determinant of a 2x2 matrix.");
 		statement("// Returns the determinant of a 2x2 matrix.");
-		statement("float SPIRV_Cross_Det2x2(float a1, float a2, float b1, float b2)");
+		statement("float spvDet2x2(float a1, float a2, float b1, float b2)");
 		begin_scope();
 		begin_scope();
 		statement("return a1 * b2 - b1 * a2;");
 		statement("return a1 * b2 - b1 * a2;");
 		end_scope();
 		end_scope();
 		statement_no_indent("");
 		statement_no_indent("");
 		statement("// Returns the inverse of a matrix, by using the algorithm of calculating the classical");
 		statement("// Returns the inverse of a matrix, by using the algorithm of calculating the classical");
 		statement("// adjoint and dividing by the determinant. The contents of the matrix are changed.");
 		statement("// adjoint and dividing by the determinant. The contents of the matrix are changed.");
-		statement("float3x3 SPIRV_Cross_Inverse(float3x3 m)");
+		statement("float3x3 spvInverse(float3x3 m)");
 		begin_scope();
 		begin_scope();
 		statement("float3x3 adj;	// The adjoint matrix (inverse after dividing by determinant)");
 		statement("float3x3 adj;	// The adjoint matrix (inverse after dividing by determinant)");
 		statement_no_indent("");
 		statement_no_indent("");
 		statement("// Create the transpose of the cofactors, as the classical adjoint of the matrix.");
 		statement("// Create the transpose of the cofactors, as the classical adjoint of the matrix.");
-		statement("adj[0][0] =  SPIRV_Cross_Det2x2(m[1][1], m[1][2], m[2][1], m[2][2]);");
-		statement("adj[0][1] = -SPIRV_Cross_Det2x2(m[0][1], m[0][2], m[2][1], m[2][2]);");
-		statement("adj[0][2] =  SPIRV_Cross_Det2x2(m[0][1], m[0][2], m[1][1], m[1][2]);");
+		statement("adj[0][0] =  spvDet2x2(m[1][1], m[1][2], m[2][1], m[2][2]);");
+		statement("adj[0][1] = -spvDet2x2(m[0][1], m[0][2], m[2][1], m[2][2]);");
+		statement("adj[0][2] =  spvDet2x2(m[0][1], m[0][2], m[1][1], m[1][2]);");
 		statement_no_indent("");
 		statement_no_indent("");
-		statement("adj[1][0] = -SPIRV_Cross_Det2x2(m[1][0], m[1][2], m[2][0], m[2][2]);");
-		statement("adj[1][1] =  SPIRV_Cross_Det2x2(m[0][0], m[0][2], m[2][0], m[2][2]);");
-		statement("adj[1][2] = -SPIRV_Cross_Det2x2(m[0][0], m[0][2], m[1][0], m[1][2]);");
+		statement("adj[1][0] = -spvDet2x2(m[1][0], m[1][2], m[2][0], m[2][2]);");
+		statement("adj[1][1] =  spvDet2x2(m[0][0], m[0][2], m[2][0], m[2][2]);");
+		statement("adj[1][2] = -spvDet2x2(m[0][0], m[0][2], m[1][0], m[1][2]);");
 		statement_no_indent("");
 		statement_no_indent("");
-		statement("adj[2][0] =  SPIRV_Cross_Det2x2(m[1][0], m[1][1], m[2][0], m[2][1]);");
-		statement("adj[2][1] = -SPIRV_Cross_Det2x2(m[0][0], m[0][1], m[2][0], m[2][1]);");
-		statement("adj[2][2] =  SPIRV_Cross_Det2x2(m[0][0], m[0][1], m[1][0], m[1][1]);");
+		statement("adj[2][0] =  spvDet2x2(m[1][0], m[1][1], m[2][0], m[2][1]);");
+		statement("adj[2][1] = -spvDet2x2(m[0][0], m[0][1], m[2][0], m[2][1]);");
+		statement("adj[2][2] =  spvDet2x2(m[0][0], m[0][1], m[1][0], m[1][1]);");
 		statement_no_indent("");
 		statement_no_indent("");
 		statement("// Calculate the determinant as a combination of the cofactors of the first row.");
 		statement("// Calculate the determinant as a combination of the cofactors of the first row.");
 		statement("float det = (adj[0][0] * m[0][0]) + (adj[0][1] * m[1][0]) + (adj[0][2] * m[2][0]);");
 		statement("float det = (adj[0][0] * m[0][0]) + (adj[0][1] * m[1][0]) + (adj[0][2] * m[2][0]);");
@@ -1758,7 +1757,7 @@ void CompilerHLSL::emit_resources()
 		if (!requires_inverse_3x3)
 		if (!requires_inverse_3x3)
 		{
 		{
 			statement("// Returns the determinant of a 2x2 matrix.");
 			statement("// Returns the determinant of a 2x2 matrix.");
-			statement("float SPIRV_Cross_Det2x2(float a1, float a2, float b1, float b2)");
+			statement("float spvDet2x2(float a1, float a2, float b1, float b2)");
 			begin_scope();
 			begin_scope();
 			statement("return a1 * b2 - b1 * a2;");
 			statement("return a1 * b2 - b1 * a2;");
 			end_scope();
 			end_scope();
@@ -1766,71 +1765,71 @@ void CompilerHLSL::emit_resources()
 		}
 		}
 
 
 		statement("// Returns the determinant of a 3x3 matrix.");
 		statement("// Returns the determinant of a 3x3 matrix.");
-		statement("float SPIRV_Cross_Det3x3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, "
+		statement("float spvDet3x3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, "
 		          "float c2, float c3)");
 		          "float c2, float c3)");
 		begin_scope();
 		begin_scope();
-		statement("return a1 * SPIRV_Cross_Det2x2(b2, b3, c2, c3) - b1 * SPIRV_Cross_Det2x2(a2, a3, c2, c3) + c1 * "
-		          "SPIRV_Cross_Det2x2(a2, a3, "
+		statement("return a1 * spvDet2x2(b2, b3, c2, c3) - b1 * spvDet2x2(a2, a3, c2, c3) + c1 * "
+		          "spvDet2x2(a2, a3, "
 		          "b2, b3);");
 		          "b2, b3);");
 		end_scope();
 		end_scope();
 		statement_no_indent("");
 		statement_no_indent("");
 		statement("// Returns the inverse of a matrix, by using the algorithm of calculating the classical");
 		statement("// Returns the inverse of a matrix, by using the algorithm of calculating the classical");
 		statement("// adjoint and dividing by the determinant. The contents of the matrix are changed.");
 		statement("// adjoint and dividing by the determinant. The contents of the matrix are changed.");
-		statement("float4x4 SPIRV_Cross_Inverse(float4x4 m)");
+		statement("float4x4 spvInverse(float4x4 m)");
 		begin_scope();
 		begin_scope();
 		statement("float4x4 adj;	// The adjoint matrix (inverse after dividing by determinant)");
 		statement("float4x4 adj;	// The adjoint matrix (inverse after dividing by determinant)");
 		statement_no_indent("");
 		statement_no_indent("");
 		statement("// Create the transpose of the cofactors, as the classical adjoint of the matrix.");
 		statement("// Create the transpose of the cofactors, as the classical adjoint of the matrix.");
 		statement(
 		statement(
-		    "adj[0][0] =  SPIRV_Cross_Det3x3(m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], "
+		    "adj[0][0] =  spvDet3x3(m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[0][1] = -SPIRV_Cross_Det3x3(m[0][1], m[0][2], m[0][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], "
+		    "adj[0][1] = -spvDet3x3(m[0][1], m[0][2], m[0][3], m[2][1], m[2][2], m[2][3], m[3][1], m[3][2], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[0][2] =  SPIRV_Cross_Det3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[3][1], m[3][2], "
+		    "adj[0][2] =  spvDet3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[3][1], m[3][2], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[0][3] = -SPIRV_Cross_Det3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], "
+		    "adj[0][3] = -spvDet3x3(m[0][1], m[0][2], m[0][3], m[1][1], m[1][2], m[1][3], m[2][1], m[2][2], "
 		    "m[2][3]);");
 		    "m[2][3]);");
 		statement_no_indent("");
 		statement_no_indent("");
 		statement(
 		statement(
-		    "adj[1][0] = -SPIRV_Cross_Det3x3(m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], "
+		    "adj[1][0] = -spvDet3x3(m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[1][1] =  SPIRV_Cross_Det3x3(m[0][0], m[0][2], m[0][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], "
+		    "adj[1][1] =  spvDet3x3(m[0][0], m[0][2], m[0][3], m[2][0], m[2][2], m[2][3], m[3][0], m[3][2], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[1][2] = -SPIRV_Cross_Det3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[3][0], m[3][2], "
+		    "adj[1][2] = -spvDet3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[3][0], m[3][2], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[1][3] =  SPIRV_Cross_Det3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], "
+		    "adj[1][3] =  spvDet3x3(m[0][0], m[0][2], m[0][3], m[1][0], m[1][2], m[1][3], m[2][0], m[2][2], "
 		    "m[2][3]);");
 		    "m[2][3]);");
 		statement_no_indent("");
 		statement_no_indent("");
 		statement(
 		statement(
-		    "adj[2][0] =  SPIRV_Cross_Det3x3(m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], "
+		    "adj[2][0] =  spvDet3x3(m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[2][1] = -SPIRV_Cross_Det3x3(m[0][0], m[0][1], m[0][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], "
+		    "adj[2][1] = -spvDet3x3(m[0][0], m[0][1], m[0][3], m[2][0], m[2][1], m[2][3], m[3][0], m[3][1], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[2][2] =  SPIRV_Cross_Det3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], "
+		    "adj[2][2] =  spvDet3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[3][0], m[3][1], "
 		    "m[3][3]);");
 		    "m[3][3]);");
 		statement(
 		statement(
-		    "adj[2][3] = -SPIRV_Cross_Det3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], "
+		    "adj[2][3] = -spvDet3x3(m[0][0], m[0][1], m[0][3], m[1][0], m[1][1], m[1][3], m[2][0], m[2][1], "
 		    "m[2][3]);");
 		    "m[2][3]);");
 		statement_no_indent("");
 		statement_no_indent("");
 		statement(
 		statement(
-		    "adj[3][0] = -SPIRV_Cross_Det3x3(m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], "
+		    "adj[3][0] = -spvDet3x3(m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], "
 		    "m[3][2]);");
 		    "m[3][2]);");
 		statement(
 		statement(
-		    "adj[3][1] =  SPIRV_Cross_Det3x3(m[0][0], m[0][1], m[0][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], "
+		    "adj[3][1] =  spvDet3x3(m[0][0], m[0][1], m[0][2], m[2][0], m[2][1], m[2][2], m[3][0], m[3][1], "
 		    "m[3][2]);");
 		    "m[3][2]);");
 		statement(
 		statement(
-		    "adj[3][2] = -SPIRV_Cross_Det3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[3][0], m[3][1], "
+		    "adj[3][2] = -spvDet3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[3][0], m[3][1], "
 		    "m[3][2]);");
 		    "m[3][2]);");
 		statement(
 		statement(
-		    "adj[3][3] =  SPIRV_Cross_Det3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], "
+		    "adj[3][3] =  spvDet3x3(m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], m[2][0], m[2][1], "
 		    "m[2][2]);");
 		    "m[2][2]);");
 		statement_no_indent("");
 		statement_no_indent("");
 		statement("// Calculate the determinant as a combination of the cofactors of the first row.");
 		statement("// Calculate the determinant as a combination of the cofactors of the first row.");
@@ -1847,7 +1846,7 @@ void CompilerHLSL::emit_resources()
 	if (requires_scalar_reflect)
 	if (requires_scalar_reflect)
 	{
 	{
 		// FP16/FP64? No templates in HLSL.
 		// FP16/FP64? No templates in HLSL.
-		statement("float SPIRV_Cross_Reflect(float i, float n)");
+		statement("float spvReflect(float i, float n)");
 		begin_scope();
 		begin_scope();
 		statement("return i - 2.0 * dot(n, i) * n;");
 		statement("return i - 2.0 * dot(n, i) * n;");
 		end_scope();
 		end_scope();
@@ -1857,7 +1856,7 @@ void CompilerHLSL::emit_resources()
 	if (requires_scalar_refract)
 	if (requires_scalar_refract)
 	{
 	{
 		// FP16/FP64? No templates in HLSL.
 		// FP16/FP64? No templates in HLSL.
-		statement("float SPIRV_Cross_Refract(float i, float n, float eta)");
+		statement("float spvRefract(float i, float n, float eta)");
 		begin_scope();
 		begin_scope();
 		statement("float NoI = n * i;");
 		statement("float NoI = n * i;");
 		statement("float NoI2 = NoI * NoI;");
 		statement("float NoI2 = NoI * NoI;");
@@ -1877,7 +1876,7 @@ void CompilerHLSL::emit_resources()
 	if (requires_scalar_faceforward)
 	if (requires_scalar_faceforward)
 	{
 	{
 		// FP16/FP64? No templates in HLSL.
 		// FP16/FP64? No templates in HLSL.
-		statement("float SPIRV_Cross_FaceForward(float n, float i, float nref)");
+		statement("float spvFaceForward(float n, float i, float nref)");
 		begin_scope();
 		begin_scope();
 		statement("return i * nref < 0.0 ? n : -n;");
 		statement("return i * nref < 0.0 ? n : -n;");
 		end_scope();
 		end_scope();
@@ -1916,7 +1915,7 @@ void CompilerHLSL::emit_texture_size_variants(uint64_t variant_mask, const char
 			if ((variant_mask & mask) == 0)
 			if ((variant_mask & mask) == 0)
 				continue;
 				continue;
 
 
-			statement(ret_types[index], " SPIRV_Cross_", (uav ? "image" : "texture"), "Size(", (uav ? "RW" : ""),
+			statement(ret_types[index], " spv", (uav ? "Image" : "Texture"), "Size(", (uav ? "RW" : ""),
 			          dims[index], "<", type_qualifier, types[type_index], vecsize_qualifier, "> Tex, ",
 			          dims[index], "<", type_qualifier, types[type_index], vecsize_qualifier, "> Tex, ",
 			          (uav ? "" : "uint Level, "), "out uint Param)");
 			          (uav ? "" : "uint Level, "), "out uint Param)");
 			begin_scope();
 			begin_scope();
@@ -2282,7 +2281,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret
 		out_argument += "out ";
 		out_argument += "out ";
 		out_argument += type_to_glsl(type);
 		out_argument += type_to_glsl(type);
 		out_argument += " ";
 		out_argument += " ";
-		out_argument += "SPIRV_Cross_return_value";
+		out_argument += "spvReturnValue";
 		out_argument += type_to_array_glsl(type);
 		out_argument += type_to_array_glsl(type);
 		arglist.push_back(move(out_argument));
 		arglist.push_back(move(out_argument));
 	}
 	}
@@ -2996,7 +2995,10 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)
 		if (dref)
 		if (dref)
 		{
 		{
 			if (imgtype.image.dim != spv::Dim1D && imgtype.image.dim != spv::Dim2D)
 			if (imgtype.image.dim != spv::Dim1D && imgtype.image.dim != spv::Dim2D)
-				SPIRV_CROSS_THROW("Depth comparison is only supported for 1D and 2D textures in HLSL shader model 2/3.");
+			{
+				SPIRV_CROSS_THROW(
+				    "Depth comparison is only supported for 1D and 2D textures in HLSL shader model 2/3.");
+			}
 
 
 			if (grad_x || grad_y)
 			if (grad_x || grad_y)
 				SPIRV_CROSS_THROW("Depth comparison is not supported for grad sampling in HLSL shader model 2/3.");
 				SPIRV_CROSS_THROW("Depth comparison is not supported for grad sampling in HLSL shader model 2/3.");
@@ -3023,8 +3025,7 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse)
 		}
 		}
 		else if (proj)
 		else if (proj)
 		{
 		{
-			coord_expr = "float4(" + coord_expr + ", " +
-			             to_extract_component_expression(coord, coord_components) + ")";
+			coord_expr = "float4(" + coord_expr + ", " + to_extract_component_expression(coord, coord_components) + ")";
 		}
 		}
 		else if (dref)
 		else if (dref)
 		{
 		{
@@ -3409,7 +3410,7 @@ string CompilerHLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &i
 			requires_explicit_fp16_packing = true;
 			requires_explicit_fp16_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		return "SPIRV_Cross_unpackFloat2x16";
+		return "spvUnpackFloat2x16";
 	}
 	}
 	else if (out_type.basetype == SPIRType::UInt && in_type.basetype == SPIRType::Half && in_type.vecsize == 2)
 	else if (out_type.basetype == SPIRType::UInt && in_type.basetype == SPIRType::Half && in_type.vecsize == 2)
 	{
 	{
@@ -3418,7 +3419,7 @@ string CompilerHLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &i
 			requires_explicit_fp16_packing = true;
 			requires_explicit_fp16_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		return "SPIRV_Cross_packFloat2x16";
+		return "spvPackFloat2x16";
 	}
 	}
 	else
 	else
 		return "";
 		return "";
@@ -3483,7 +3484,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_fp16_packing = true;
 			requires_fp16_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_packHalf2x16");
+		emit_unary_func_op(result_type, id, args[0], "spvPackHalf2x16");
 		break;
 		break;
 
 
 	case GLSLstd450UnpackHalf2x16:
 	case GLSLstd450UnpackHalf2x16:
@@ -3492,7 +3493,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_fp16_packing = true;
 			requires_fp16_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_unpackHalf2x16");
+		emit_unary_func_op(result_type, id, args[0], "spvUnpackHalf2x16");
 		break;
 		break;
 
 
 	case GLSLstd450PackSnorm4x8:
 	case GLSLstd450PackSnorm4x8:
@@ -3501,7 +3502,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_snorm8_packing = true;
 			requires_snorm8_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_packSnorm4x8");
+		emit_unary_func_op(result_type, id, args[0], "spvPackSnorm4x8");
 		break;
 		break;
 
 
 	case GLSLstd450UnpackSnorm4x8:
 	case GLSLstd450UnpackSnorm4x8:
@@ -3510,7 +3511,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_snorm8_packing = true;
 			requires_snorm8_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_unpackSnorm4x8");
+		emit_unary_func_op(result_type, id, args[0], "spvUnpackSnorm4x8");
 		break;
 		break;
 
 
 	case GLSLstd450PackUnorm4x8:
 	case GLSLstd450PackUnorm4x8:
@@ -3519,7 +3520,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_unorm8_packing = true;
 			requires_unorm8_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_packUnorm4x8");
+		emit_unary_func_op(result_type, id, args[0], "spvPackUnorm4x8");
 		break;
 		break;
 
 
 	case GLSLstd450UnpackUnorm4x8:
 	case GLSLstd450UnpackUnorm4x8:
@@ -3528,7 +3529,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_unorm8_packing = true;
 			requires_unorm8_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_unpackUnorm4x8");
+		emit_unary_func_op(result_type, id, args[0], "spvUnpackUnorm4x8");
 		break;
 		break;
 
 
 	case GLSLstd450PackSnorm2x16:
 	case GLSLstd450PackSnorm2x16:
@@ -3537,7 +3538,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_snorm16_packing = true;
 			requires_snorm16_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_packSnorm2x16");
+		emit_unary_func_op(result_type, id, args[0], "spvPackSnorm2x16");
 		break;
 		break;
 
 
 	case GLSLstd450UnpackSnorm2x16:
 	case GLSLstd450UnpackSnorm2x16:
@@ -3546,7 +3547,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_snorm16_packing = true;
 			requires_snorm16_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_unpackSnorm2x16");
+		emit_unary_func_op(result_type, id, args[0], "spvUnpackSnorm2x16");
 		break;
 		break;
 
 
 	case GLSLstd450PackUnorm2x16:
 	case GLSLstd450PackUnorm2x16:
@@ -3555,7 +3556,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_unorm16_packing = true;
 			requires_unorm16_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_packUnorm2x16");
+		emit_unary_func_op(result_type, id, args[0], "spvPackUnorm2x16");
 		break;
 		break;
 
 
 	case GLSLstd450UnpackUnorm2x16:
 	case GLSLstd450UnpackUnorm2x16:
@@ -3564,7 +3565,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 			requires_unorm16_packing = true;
 			requires_unorm16_packing = true;
 			force_recompile();
 			force_recompile();
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_unpackUnorm2x16");
+		emit_unary_func_op(result_type, id, args[0], "spvUnpackUnorm2x16");
 		break;
 		break;
 
 
 	case GLSLstd450PackDouble2x32:
 	case GLSLstd450PackDouble2x32:
@@ -3613,7 +3614,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 				force_recompile();
 				force_recompile();
 			}
 			}
 		}
 		}
-		emit_unary_func_op(result_type, id, args[0], "SPIRV_Cross_Inverse");
+		emit_unary_func_op(result_type, id, args[0], "spvInverse");
 		break;
 		break;
 	}
 	}
 
 
@@ -3636,7 +3637,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 				requires_scalar_reflect = true;
 				requires_scalar_reflect = true;
 				force_recompile();
 				force_recompile();
 			}
 			}
-			emit_binary_func_op(result_type, id, args[0], args[1], "SPIRV_Cross_Reflect");
+			emit_binary_func_op(result_type, id, args[0], args[1], "spvReflect");
 		}
 		}
 		else
 		else
 			CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
 			CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
@@ -3650,7 +3651,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 				requires_scalar_refract = true;
 				requires_scalar_refract = true;
 				force_recompile();
 				force_recompile();
 			}
 			}
-			emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "SPIRV_Cross_Refract");
+			emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "spvRefract");
 		}
 		}
 		else
 		else
 			CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
 			CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
@@ -3664,7 +3665,7 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
 				requires_scalar_faceforward = true;
 				requires_scalar_faceforward = true;
 				force_recompile();
 				force_recompile();
 			}
 			}
-			emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "SPIRV_Cross_FaceForward");
+			emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "spvFaceForward");
 		}
 		}
 		else
 		else
 			CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
 			CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
@@ -4701,9 +4702,9 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
 			}
 			}
 
 
 			if (bitcast_type == CompilerHLSL::TypePackUint2x32)
 			if (bitcast_type == CompilerHLSL::TypePackUint2x32)
-				emit_unary_func_op(ops[0], ops[1], ops[2], "SPIRV_Cross_packUint2x32");
+				emit_unary_func_op(ops[0], ops[1], ops[2], "spvPackUint2x32");
 			else
 			else
-				emit_unary_func_op(ops[0], ops[1], ops[2], "SPIRV_Cross_unpackUint2x32");
+				emit_unary_func_op(ops[0], ops[1], ops[2], "spvUnpackUint2x32");
 		}
 		}
 
 
 		break;
 		break;
@@ -5088,7 +5089,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
 		auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter");
 		auto dummy_samples_levels = join(get_fallback_name(id), "_dummy_parameter");
 		statement("uint ", dummy_samples_levels, ";");
 		statement("uint ", dummy_samples_levels, ";");
 
 
-		auto expr = join("SPIRV_Cross_textureSize(", to_expression(ops[2]), ", ",
+		auto expr = join("spvTextureSize(", to_expression(ops[2]), ", ",
 		                 bitcast_expression(SPIRType::UInt, ops[3]), ", ", dummy_samples_levels, ")");
 		                 bitcast_expression(SPIRType::UInt, ops[3]), ", ", dummy_samples_levels, ")");
 
 
 		auto &restype = get<SPIRType>(ops[0]);
 		auto &restype = get<SPIRType>(ops[0]);
@@ -5114,9 +5115,9 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
 
 
 		string expr;
 		string expr;
 		if (uav)
 		if (uav)
-			expr = join("SPIRV_Cross_imageSize(", to_expression(ops[2]), ", ", dummy_samples_levels, ")");
+			expr = join("spvImageSize(", to_expression(ops[2]), ", ", dummy_samples_levels, ")");
 		else
 		else
-			expr = join("SPIRV_Cross_textureSize(", to_expression(ops[2]), ", 0u, ", dummy_samples_levels, ")");
+			expr = join("spvTextureSize(", to_expression(ops[2]), ", 0u, ", dummy_samples_levels, ")");
 
 
 		auto &restype = get<SPIRType>(ops[0]);
 		auto &restype = get<SPIRType>(ops[0]);
 		expr = bitcast_expression(restype, SPIRType::UInt, expr);
 		expr = bitcast_expression(restype, SPIRType::UInt, expr);
@@ -5146,9 +5147,9 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
 		statement(variable_decl(type, to_name(id)), ";");
 		statement(variable_decl(type, to_name(id)), ";");
 
 
 		if (uav)
 		if (uav)
-			statement("SPIRV_Cross_imageSize(", to_expression(ops[2]), ", ", to_name(id), ");");
+			statement("spvImageSize(", to_expression(ops[2]), ", ", to_name(id), ");");
 		else
 		else
-			statement("SPIRV_Cross_textureSize(", to_expression(ops[2]), ", 0u, ", to_name(id), ");");
+			statement("spvTextureSize(", to_expression(ops[2]), ", 0u, ", to_name(id), ");");
 
 
 		auto &restype = get<SPIRType>(ops[0]);
 		auto &restype = get<SPIRType>(ops[0]);
 		auto expr = bitcast_expression(restype, SPIRType::UInt, to_name(id));
 		auto expr = bitcast_expression(restype, SPIRType::UInt, to_name(id));
@@ -5389,7 +5390,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
 			force_recompile();
 			force_recompile();
 		}
 		}
 
 
-		auto expr = join("SPIRV_Cross_bitfieldInsert(", to_expression(ops[2]), ", ", to_expression(ops[3]), ", ",
+		auto expr = join("spvBitfieldInsert(", to_expression(ops[2]), ", ", to_expression(ops[3]), ", ",
 		                 to_expression(ops[4]), ", ", to_expression(ops[5]), ")");
 		                 to_expression(ops[4]), ", ", to_expression(ops[5]), ")");
 
 
 		bool forward =
 		bool forward =
@@ -5411,9 +5412,9 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction)
 		}
 		}
 
 
 		if (opcode == OpBitFieldSExtract)
 		if (opcode == OpBitFieldSExtract)
-			HLSL_TFOP(SPIRV_Cross_bitfieldSExtract);
+			HLSL_TFOP(spvBitfieldSExtract);
 		else
 		else
-			HLSL_TFOP(SPIRV_Cross_bitfieldUExtract);
+			HLSL_TFOP(spvBitfieldUExtract);
 		break;
 		break;
 	}
 	}
 
 

Разлика између датотеке није приказан због своје велике величине
+ 457 - 150
3rdparty/spirv-cross/spirv_msl.cpp


+ 30 - 0
3rdparty/spirv-cross/spirv_msl.hpp

@@ -364,6 +364,28 @@ public:
 		// and will be addressed using the current ViewIndex.
 		// and will be addressed using the current ViewIndex.
 		bool arrayed_subpass_input = false;
 		bool arrayed_subpass_input = false;
 
 
+		// Whether to use SIMD-group or quadgroup functions to implement group nnon-uniform
+		// operations. Some GPUs on iOS do not support the SIMD-group functions, only the
+		// quadgroup functions.
+		bool ios_use_simdgroup_functions = false;
+
+		// If set, the subgroup size will be assumed to be one, and subgroup-related
+		// builtins and operations will be emitted accordingly. This mode is intended to
+		// be used by MoltenVK on hardware/software configurations which do not provide
+		// sufficient support for subgroups.
+		bool emulate_subgroups = false;
+
+		// If nonzero, a fixed subgroup size to assume. Metal, similarly to VK_EXT_subgroup_size_control,
+		// allows the SIMD-group size (aka thread execution width) to vary depending on
+		// register usage and requirements. In certain circumstances--for example, a pipeline
+		// in MoltenVK without VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT--
+		// this is undesirable. This fixes the value of the SubgroupSize builtin, instead of
+		// mapping it to the Metal builtin [[thread_execution_width]]. If the thread
+		// execution width is reduced, the extra invocations will appear to be inactive.
+		// If zero, the SubgroupSize will be allowed to vary, and the builtin will be mapped
+		// to the Metal [[thread_execution_width]] builtin.
+		uint32_t fixed_subgroup_size = 0;
+
 		enum class IndexType
 		enum class IndexType
 		{
 		{
 			None = 0,
 			None = 0,
@@ -379,6 +401,11 @@ public:
 		// different shaders for these three scenarios.
 		// different shaders for these three scenarios.
 		IndexType vertex_index_type = IndexType::None;
 		IndexType vertex_index_type = IndexType::None;
 
 
+		// If set, a dummy [[sample_id]] input is added to a fragment shader if none is present.
+		// This will force the shader to run at sample rate, assuming Metal does not optimize
+		// the extra threads away.
+		bool force_sample_rate_shading = false;
+
 		bool is_ios() const
 		bool is_ios() const
 		{
 		{
 			return platform == iOS;
 			return platform == iOS;
@@ -776,6 +803,7 @@ protected:
 	std::string to_sampler_expression(uint32_t id);
 	std::string to_sampler_expression(uint32_t id);
 	std::string to_swizzle_expression(uint32_t id);
 	std::string to_swizzle_expression(uint32_t id);
 	std::string to_buffer_size_expression(uint32_t id);
 	std::string to_buffer_size_expression(uint32_t id);
+	bool is_sample_rate() const;
 	bool is_direct_input_builtin(spv::BuiltIn builtin);
 	bool is_direct_input_builtin(spv::BuiltIn builtin);
 	std::string builtin_qualifier(spv::BuiltIn builtin);
 	std::string builtin_qualifier(spv::BuiltIn builtin);
 	std::string builtin_type_decl(spv::BuiltIn builtin, uint32_t id = 0);
 	std::string builtin_type_decl(spv::BuiltIn builtin, uint32_t id = 0);
@@ -853,6 +881,8 @@ protected:
 	uint32_t builtin_subgroup_size_id = 0;
 	uint32_t builtin_subgroup_size_id = 0;
 	uint32_t builtin_dispatch_base_id = 0;
 	uint32_t builtin_dispatch_base_id = 0;
 	uint32_t builtin_stage_input_size_id = 0;
 	uint32_t builtin_stage_input_size_id = 0;
+	uint32_t builtin_local_invocation_index_id = 0;
+	uint32_t builtin_workgroup_size_id = 0;
 	uint32_t swizzle_buffer_id = 0;
 	uint32_t swizzle_buffer_id = 0;
 	uint32_t buffer_size_buffer_id = 0;
 	uint32_t buffer_size_buffer_id = 0;
 	uint32_t view_mask_buffer_id = 0;
 	uint32_t view_mask_buffer_id = 0;

Неке датотеке нису приказане због велике количине промена