2
0
Бранимир Караџић 6 жил өмнө
parent
commit
f38bf2b3a2

+ 11 - 11
3rdparty/spirv-cross/CMakeLists.txt

@@ -56,7 +56,7 @@ set(spirv-compiler-options "")
 set(spirv-compiler-defines "")
 set(spirv-cross-link-flags "")
 
-message(STATUS "Finding Git version for SPIRV-Cross.")
+message(STATUS "SPIRV-Cross: Finding Git version for SPIRV-Cross.")
 set(spirv-cross-build-version "unknown")
 find_package(Git)
 if (GIT_FOUND)
@@ -67,9 +67,9 @@ if (GIT_FOUND)
 		ERROR_QUIET
 		OUTPUT_STRIP_TRAILING_WHITESPACE
 		)
-	message(STATUS "Git hash: ${spirv-cross-build-version}")
+	message(STATUS "SPIRV-Cross: Git hash: ${spirv-cross-build-version}")
 else()
-	message(STATUS "Git not found, using unknown build version.")
+	message(STATUS "SPIRV-Cross: Git not found, using unknown build version.")
 endif()
 
 string(TIMESTAMP spirv-cross-timestamp)
@@ -308,7 +308,7 @@ if (SPIRV_CROSS_STATIC)
 endif()
 
 set(spirv-cross-abi-major 0)
-set(spirv-cross-abi-minor 20)
+set(spirv-cross-abi-minor 21)
 set(spirv-cross-abi-patch 0)
 
 if (SPIRV_CROSS_SHARED)
@@ -453,14 +453,14 @@ if (SPIRV_CROSS_CLI)
 
 		if ((${spirv-cross-glslang} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-as} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-val} MATCHES "NOTFOUND") OR (${spirv-cross-spirv-opt} MATCHES "NOTFOUND"))
 			set(SPIRV_CROSS_ENABLE_TESTS OFF)
-			message("Could not find glslang or SPIRV-Tools build under external/. Run ./checkout_glslang_spirv_tools.sh and ./build_glslang_spirv_tools.sh. Testing will be disabled.")
+			message("SPIRV-Cross:  Testing will be disabled for SPIRV-Cross. Could not find glslang or SPIRV-Tools build under external/. To enable testing, run ./checkout_glslang_spirv_tools.sh and ./build_glslang_spirv_tools.sh first.")
 		else()
 			set(SPIRV_CROSS_ENABLE_TESTS ON)
-			message("Found glslang and SPIRV-Tools. Enabling test suite.")
-			message("Found glslangValidator in: ${spirv-cross-glslang}.")
-			message("Found spirv-as in: ${spirv-cross-spirv-as}.")
-			message("Found spirv-val in: ${spirv-cross-spirv-val}.")
-			message("Found spirv-opt in: ${spirv-cross-spirv-opt}.")
+			message("SPIRV-Cross: Found glslang and SPIRV-Tools. Enabling test suite.")
+			message("SPIRV-Cross: Found glslangValidator in: ${spirv-cross-glslang}.")
+			message("SPIRV-Cross: Found spirv-as in: ${spirv-cross-spirv-as}.")
+			message("SPIRV-Cross: Found spirv-val in: ${spirv-cross-spirv-val}.")
+			message("SPIRV-Cross: Found spirv-opt in: ${spirv-cross-spirv-opt}.")
 		endif()
 
 		set(spirv-cross-externals
@@ -577,7 +577,7 @@ if (SPIRV_CROSS_CLI)
 						WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 			endif()
 		elseif(NOT ${PYTHONINTERP_FOUND})
-			message(WARNING "Testing disabled. Could not find python3. If you have python3 installed try running "
+			message(WARNING "SPIRV-Cross: Testing disabled. Could not find python3. If you have python3 installed try running "
 					"cmake with -DPYTHON_EXECUTABLE:FILEPATH=/path/to/python3 to help it find the executable")
 		endif()
 	endif()

+ 27 - 0
3rdparty/spirv-cross/main.cpp

@@ -552,6 +552,7 @@ struct CLIArguments
 	bool hlsl = false;
 	bool hlsl_compat = false;
 	bool hlsl_support_nonzero_base = false;
+	HLSLBindingFlags hlsl_binding_flags = 0;
 	bool vulkan_semantics = false;
 	bool flatten_multidimensional_arrays = false;
 	bool use_420pack_extension = true;
@@ -614,6 +615,7 @@ static void print_help()
 	                "\t[--shader-model]\n"
 	                "\t[--hlsl-enable-compat]\n"
 	                "\t[--hlsl-support-nonzero-basevertex-baseinstance]\n"
+	                "\t[--hlsl-auto-binding (push, cbv, srv, uav, sampler, all)]\n"
 	                "\t[--separate-shader-objects]\n"
 	                "\t[--pls-in format input-name]\n"
 	                "\t[--pls-out format output-name]\n"
@@ -736,6 +738,27 @@ static ExecutionModel stage_to_execution_model(const std::string &stage)
 		SPIRV_CROSS_THROW("Invalid stage.");
 }
 
+static HLSLBindingFlags hlsl_resource_type_to_flag(const std::string &arg)
+{
+	if (arg == "push")
+		return HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT;
+	else if (arg == "cbv")
+		return HLSL_BINDING_AUTO_CBV_BIT;
+	else if (arg == "srv")
+		return HLSL_BINDING_AUTO_SRV_BIT;
+	else if (arg == "uav")
+		return HLSL_BINDING_AUTO_UAV_BIT;
+	else if (arg == "sampler")
+		return HLSL_BINDING_AUTO_SAMPLER_BIT;
+	else if (arg == "all")
+		return HLSL_BINDING_AUTO_ALL;
+	else
+	{
+		fprintf(stderr, "Invalid resource type for --hlsl-auto-binding: %s\n", arg.c_str());
+		return 0;
+	}
+}
+
 static string compile_iteration(const CLIArguments &args, std::vector<uint32_t> spirv_file)
 {
 	Parser spirv_parser(move(spirv_file));
@@ -939,6 +962,7 @@ static string compile_iteration(const CLIArguments &args, std::vector<uint32_t>
 
 		hlsl_opts.support_nonzero_base_vertex_base_instance = args.hlsl_support_nonzero_base;
 		hlsl->set_hlsl_options(hlsl_opts);
+		hlsl->set_resource_binding_flags(args.hlsl_binding_flags);
 	}
 
 	if (build_dummy_sampler)
@@ -1089,6 +1113,9 @@ static int main_inner(int argc, char *argv[])
 	cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; });
 	cbs.add("--hlsl-support-nonzero-basevertex-baseinstance",
 	        [&args](CLIParser &) { args.hlsl_support_nonzero_base = true; });
+	cbs.add("--hlsl-auto-binding", [&args](CLIParser &parser) {
+		args.hlsl_binding_flags |= hlsl_resource_type_to_flag(parser.next_string());
+	});
 	cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
 	cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
 	cbs.add("--no-420pack-extension", [&args](CLIParser &) { args.use_420pack_extension = false; });

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

@@ -769,6 +769,26 @@ spvc_variable_id spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler c
 #endif
 }
 
+spvc_result spvc_compiler_hlsl_set_resource_binding_flags(spvc_compiler compiler,
+                                                          spvc_hlsl_binding_flags flags)
+{
+#if SPIRV_CROSS_C_API_HLSL
+	if (compiler->backend != SPVC_BACKEND_HLSL)
+	{
+		compiler->context->report_error("HLSL function used on a non-HLSL backend.");
+		return SPVC_ERROR_INVALID_ARGUMENT;
+	}
+
+	auto &hlsl = *static_cast<CompilerHLSL *>(compiler->compiler.get());
+	hlsl.set_resource_binding_flags(flags);
+	return SPVC_SUCCESS;
+#else
+	(void)flags;
+	compiler->context->report_error("HLSL function used on a non-HLSL backend.");
+	return SPVC_ERROR_INVALID_ARGUMENT;
+#endif
+}
+
 spvc_bool spvc_compiler_msl_is_rasterization_disabled(spvc_compiler compiler)
 {
 #if SPIRV_CROSS_C_API_MSL

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

@@ -33,7 +33,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 20
+#define SPVC_C_API_VERSION_MINOR 21
 /* Bumped if internal implementation details change. */
 #define SPVC_C_API_VERSION_PATCH 0
 
@@ -466,6 +466,18 @@ typedef struct spvc_msl_sampler_ycbcr_conversion
  */
 SPVC_PUBLIC_API void spvc_msl_sampler_ycbcr_conversion_init(spvc_msl_sampler_ycbcr_conversion *conv);
 
+/* Maps to C++ API. */
+typedef enum spvc_hlsl_binding_flag_bits
+{
+	SPVC_HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT = 1 << 0,
+	SPVC_HLSL_BINDING_AUTO_CBV_BIT = 1 << 1,
+	SPVC_HLSL_BINDING_AUTO_SRV_BIT = 1 << 2,
+	SPVC_HLSL_BINDING_AUTO_UAV_BIT = 1 << 3,
+	SPVC_HLSL_BINDING_AUTO_SAMPLER_BIT = 1 << 4,
+	SPVC_HLSL_BINDING_AUTO_ALL = 0x7fffffff
+} spvc_hlsl_binding_flag_bits;
+typedef unsigned spvc_hlsl_binding_flags;
+
 /* Maps to the various spirv_cross::Compiler*::Option structures. See C++ API for defaults and details. */
 typedef enum spvc_compiler_option
 {
@@ -606,6 +618,9 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_add_vertex_attribute_remap(spvc_c
                                                                           size_t remaps);
 SPVC_PUBLIC_API spvc_variable_id spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler compiler);
 
+SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_set_resource_binding_flags(spvc_compiler compiler,
+                                                                          spvc_hlsl_binding_flags flags);
+
 /*
  * MSL specifics.
  * Maps to C++ API.

+ 35 - 7
3rdparty/spirv-cross/spirv_hlsl.cpp

@@ -1980,7 +1980,7 @@ void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var)
 			auto &memb = ir.meta[type.self].members;
 
 			statement("cbuffer SPIRV_CROSS_RootConstant_", to_name(var.self),
-			          to_resource_register('b', layout.binding, layout.space));
+			          to_resource_register(HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT, 'b', layout.binding, layout.space));
 			begin_scope();
 
 			// Index of the next field in the generated root constant constant buffer
@@ -2943,21 +2943,31 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
 	const auto &type = get<SPIRType>(var.basetype);
 	char space = '\0';
 
+	HLSLBindingFlags resource_flags = 0;
+
 	switch (type.basetype)
 	{
 	case SPIRType::SampledImage:
 		space = 't'; // SRV
+		resource_flags = HLSL_BINDING_AUTO_SRV_BIT;
 		break;
 
 	case SPIRType::Image:
 		if (type.image.sampled == 2 && type.image.dim != DimSubpassData)
+		{
 			space = 'u'; // UAV
+			resource_flags = HLSL_BINDING_AUTO_UAV_BIT;
+		}
 		else
+		{
 			space = 't'; // SRV
+			resource_flags = HLSL_BINDING_AUTO_SRV_BIT;
+		}
 		break;
 
 	case SPIRType::Sampler:
 		space = 's';
+		resource_flags = HLSL_BINDING_AUTO_SAMPLER_BIT;
 		break;
 
 	case SPIRType::Struct:
@@ -2970,18 +2980,26 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
 				Bitset flags = ir.get_buffer_block_flags(var);
 				bool is_readonly = flags.get(DecorationNonWritable);
 				space = is_readonly ? 't' : 'u'; // UAV
+				resource_flags = is_readonly ? HLSL_BINDING_AUTO_SRV_BIT : HLSL_BINDING_AUTO_UAV_BIT;
 			}
 			else if (has_decoration(type.self, DecorationBlock))
+			{
 				space = 'b'; // Constant buffers
+				resource_flags = HLSL_BINDING_AUTO_CBV_BIT;
+			}
 		}
 		else if (storage == StorageClassPushConstant)
+		{
 			space = 'b'; // Constant buffers
+			resource_flags = HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT;
+		}
 		else if (storage == StorageClassStorageBuffer)
 		{
 			// UAV or SRV depending on readonly flag.
 			Bitset flags = ir.get_buffer_block_flags(var);
 			bool is_readonly = flags.get(DecorationNonWritable);
 			space = is_readonly ? 't' : 'u';
+			resource_flags = is_readonly ? HLSL_BINDING_AUTO_SRV_BIT : HLSL_BINDING_AUTO_UAV_BIT;
 		}
 
 		break;
@@ -2993,7 +3011,7 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var)
 	if (!space)
 		return "";
 
-	return to_resource_register(space, get_decoration(var.self, DecorationBinding),
+	return to_resource_register(resource_flags, space, get_decoration(var.self, DecorationBinding),
 	                            get_decoration(var.self, DecorationDescriptorSet));
 }
 
@@ -3003,16 +3021,21 @@ string CompilerHLSL::to_resource_binding_sampler(const SPIRVariable &var)
 	if (!has_decoration(var.self, DecorationBinding))
 		return "";
 
-	return to_resource_register('s', get_decoration(var.self, DecorationBinding),
+	return to_resource_register(HLSL_BINDING_AUTO_SAMPLER_BIT, 's', get_decoration(var.self, DecorationBinding),
 	                            get_decoration(var.self, DecorationDescriptorSet));
 }
 
-string CompilerHLSL::to_resource_register(char space, uint32_t binding, uint32_t space_set)
+string CompilerHLSL::to_resource_register(uint32_t flags, char space, uint32_t binding, uint32_t space_set)
 {
-	if (hlsl_options.shader_model >= 51)
-		return join(" : register(", space, binding, ", space", space_set, ")");
+	if ((flags & resource_binding_flags) == 0)
+	{
+		if (hlsl_options.shader_model >= 51)
+			return join(" : register(", space, binding, ", space", space_set, ")");
+		else
+			return join(" : register(", space, binding, ")");
+	}
 	else
-		return join(" : register(", space, binding, ")");
+		return "";
 }
 
 void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var)
@@ -4893,6 +4916,11 @@ VariableID CompilerHLSL::remap_num_workgroups_builtin()
 	return variable_id;
 }
 
+void CompilerHLSL::set_resource_binding_flags(HLSLBindingFlags flags)
+{
+	resource_binding_flags = flags;
+}
+
 void CompilerHLSL::validate_shader_model()
 {
 	// Check for nonuniform qualifier.

+ 31 - 1
3rdparty/spirv-cross/spirv_hlsl.hpp

@@ -41,6 +41,32 @@ struct RootConstants
 	uint32_t space;
 };
 
+// For finer control, decorations may be removed from specific resources instead with unset_decoration().
+enum HLSLBindingFlagBits
+{
+	// Push constant (root constant) resources will be declared as CBVs (b-space) without a register() declaration.
+	// A register will be automatically assigned by the D3D compiler, but must therefore be reflected in D3D-land.
+	// Push constants do not normally have a DecorationBinding set, but if they do, this can be used to ignore it.
+	HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT = 1 << 0,
+
+	// cbuffer resources will be declared as CBVs (b-space) without a register() declaration.
+	// A register will be automatically assigned, but must be reflected in D3D-land.
+	HLSL_BINDING_AUTO_CBV_BIT = 1 << 1,
+
+	// All SRVs (t-space) will be declared without a register() declaration.
+	HLSL_BINDING_AUTO_SRV_BIT = 1 << 2,
+
+	// All UAVs (u-space) will be declared without a register() declaration.
+	HLSL_BINDING_AUTO_UAV_BIT = 1 << 3,
+
+	// All samplers (s-space) will be declared without a register() declaration.
+	HLSL_BINDING_AUTO_SAMPLER_BIT = 1 << 4,
+
+	// No resources will be declared with register().
+	HLSL_BINDING_AUTO_ALL = 0x7fffffff
+};
+using HLSLBindingFlags = uint32_t;
+
 class CompilerHLSL : public CompilerGLSL
 {
 public:
@@ -116,6 +142,9 @@ public:
 	// so the calling application should declare explicit bindings on this ID before calling compile().
 	VariableID remap_num_workgroups_builtin();
 
+	// Controls how resource bindings are declared in the output HLSL.
+	void set_resource_binding_flags(HLSLBindingFlags flags);
+
 private:
 	std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override;
 	std::string image_type_hlsl(const SPIRType &type, uint32_t id);
@@ -149,7 +178,7 @@ private:
 	std::string to_sampler_expression(uint32_t id);
 	std::string to_resource_binding(const SPIRVariable &var);
 	std::string to_resource_binding_sampler(const SPIRVariable &var);
-	std::string to_resource_register(char space, uint32_t binding, uint32_t set);
+	std::string to_resource_register(HLSLBindingFlags flags, char space, uint32_t binding, uint32_t set);
 	void emit_sampled_image_op(uint32_t result_type, uint32_t result_id, uint32_t image_id, uint32_t samp_id) override;
 	void emit_access_chain(const Instruction &instruction);
 	void emit_load(const Instruction &instruction);
@@ -221,6 +250,7 @@ private:
 	std::string to_semantic(uint32_t location, spv::ExecutionModel em, spv::StorageClass sc);
 
 	uint32_t num_workgroups_builtin = 0;
+	HLSLBindingFlags resource_binding_flags = 0;
 
 	// Custom root constant layout, which should be emitted
 	// when translating push constant ranges.