瀏覽代碼

Disable smolv and change the shader hash when SPIR-V debug info is enabled.

Dario 2 周之前
父節點
當前提交
e137c882c0

+ 15 - 19
drivers/vulkan/rendering_device_driver_vulkan.cpp

@@ -34,9 +34,7 @@
 #include "core/io/marshalls.h"
 #include "vulkan_hooks.h"
 
-#if RENDERING_SHADER_CONTAINER_VULKAN_SMOLV
 #include "thirdparty/misc/smolv.h"
-#endif
 
 #if defined(ANDROID_ENABLED)
 #include "platform/android/java_godot_wrapper.h"
@@ -1586,6 +1584,8 @@ Error RenderingDeviceDriverVulkan::initialize(uint32_t p_device_index, uint32_t
 	}
 #endif
 
+	shader_container_format.set_debug_info_enabled(Engine::get_singleton()->is_generate_spirv_debug_info_enabled());
+
 	return OK;
 }
 
@@ -3664,7 +3664,6 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_container(const Re
 	VkShaderModule vk_module;
 	for (int i = 0; i < shader_refl.stages_vector.size(); i++) {
 		const RenderingShaderContainer::Shader &shader = p_shader_container->shaders[i];
-#if RENDERING_SHADER_CONTAINER_VULKAN_COMPRESSION
 		bool requires_decompression = (shader.code_decompressed_size > 0);
 		if (requires_decompression) {
 			decompressed_code.resize(shader.code_decompressed_size);
@@ -3674,27 +3673,24 @@ RDD::ShaderID RenderingDeviceDriverVulkan::shader_create_from_container(const Re
 				break;
 			}
 		}
-#else
-		bool requires_decompression = false;
-#endif
 
 		const uint8_t *smolv_input = requires_decompression ? decompressed_code.ptr() : shader.code_compressed_bytes.ptr();
 		uint32_t smolv_input_size = requires_decompression ? decompressed_code.size() : shader.code_compressed_bytes.size();
-#if RENDERING_SHADER_CONTAINER_VULKAN_SMOLV
-		decoded_spirv.resize(smolv::GetDecodedBufferSize(smolv_input, smolv_input_size));
-		if (decoded_spirv.is_empty()) {
-			error_text = vformat("Malformed smolv input on shader stage %s.", String(SHADER_STAGE_NAMES[shader_refl.stages_vector[i]]));
-			break;
-		}
+		if (shader.code_compression_flags & RenderingShaderContainerVulkan::COMPRESSION_FLAG_SMOLV) {
+			decoded_spirv.resize(smolv::GetDecodedBufferSize(smolv_input, smolv_input_size));
+			if (decoded_spirv.is_empty()) {
+				error_text = vformat("Malformed smolv input on shader stage %s.", String(SHADER_STAGE_NAMES[shader_refl.stages_vector[i]]));
+				break;
+			}
 
-		if (!smolv::Decode(smolv_input, smolv_input_size, decoded_spirv.ptrw(), decoded_spirv.size())) {
-			error_text = vformat("Malformed smolv input on shader stage %s.", String(SHADER_STAGE_NAMES[shader_refl.stages_vector[i]]));
-			break;
+			if (!smolv::Decode(smolv_input, smolv_input_size, decoded_spirv.ptrw(), decoded_spirv.size())) {
+				error_text = vformat("Malformed smolv input on shader stage %s.", String(SHADER_STAGE_NAMES[shader_refl.stages_vector[i]]));
+				break;
+			}
+		} else {
+			decoded_spirv.resize(smolv_input_size);
+			memcpy(decoded_spirv.ptrw(), smolv_input, decoded_spirv.size());
 		}
-#else
-		decoded_spirv.resize(smolv_input_size);
-		memcpy(decoded_spirv.ptrw(), smolv_input, decoded_spirv.size());
-#endif
 
 		VkShaderModuleCreateInfo shader_module_create_info = {};
 		shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;

+ 38 - 30
drivers/vulkan/rendering_shader_container_vulkan.cpp

@@ -30,9 +30,7 @@
 
 #include "rendering_shader_container_vulkan.h"
 
-#if RENDERING_SHADER_CONTAINER_VULKAN_SMOLV
 #include "thirdparty/misc/smolv.h"
-#endif
 
 // RenderingShaderContainerVulkan
 
@@ -50,44 +48,50 @@ bool RenderingShaderContainerVulkan::_set_code_from_spirv(const Vector<Rendering
 	PackedByteArray code_bytes;
 	shaders.resize(p_spirv.size());
 	for (int64_t i = 0; i < p_spirv.size(); i++) {
-#if RENDERING_SHADER_CONTAINER_VULKAN_SMOLV
-		// Encode into smolv.
-		smolv::ByteArray smolv_bytes;
-		bool smolv_encoded = smolv::Encode(p_spirv[i].spirv.ptr(), p_spirv[i].spirv.size(), smolv_bytes, smolv::kEncodeFlagStripDebugInfo);
-		ERR_FAIL_COND_V_MSG(!smolv_encoded, false, "Failed to compress SPIR-V into smolv.");
-
-		code_bytes.resize(smolv_bytes.size());
-		memcpy(code_bytes.ptrw(), smolv_bytes.data(), code_bytes.size());
-#else
-		code_bytes.resize(p_spirv[i].spirv.size());
-		memcpy(code_bytes.ptrw(), p_spirv[i].spirv.ptr(), code_bytes.size());
-#endif
-
 		RenderingShaderContainer::Shader &shader = shaders.ptrw()[i];
-#if RENDERING_SHADER_CONTAINER_VULKAN_COMPRESSION
-		uint32_t compressed_size = 0;
-		shader.code_decompressed_size = code_bytes.size();
-		shader.code_compressed_bytes.resize(code_bytes.size());
-
-		bool compressed = compress_code(code_bytes.ptr(), code_bytes.size(), shader.code_compressed_bytes.ptrw(), &compressed_size, &shader.code_compression_flags);
-		ERR_FAIL_COND_V_MSG(!compressed, false, vformat("Failed to compress native code to native for SPIR-V #%d.", i));
-
-		shader.code_compressed_bytes.resize(compressed_size);
-#else
-		shader.code_decompressed_size = 0;
-		shader.code_compression_flags = 0;
-		shader.code_compressed_bytes = code_bytes;
-#endif
+
+		if (debug_info_enabled) {
+			// Store SPIR-V as is when debug info is required.
+			shader.code_compressed_bytes = p_spirv[i].spirv;
+			shader.code_compression_flags = 0;
+			shader.code_decompressed_size = 0;
+		} else {
+			// Encode into smolv.
+			smolv::ByteArray smolv_bytes;
+			bool smolv_encoded = smolv::Encode(p_spirv[i].spirv.ptr(), p_spirv[i].spirv.size(), smolv_bytes, smolv::kEncodeFlagStripDebugInfo);
+			ERR_FAIL_COND_V_MSG(!smolv_encoded, false, "Failed to compress SPIR-V into smolv.");
+
+			code_bytes.resize(smolv_bytes.size());
+			memcpy(code_bytes.ptrw(), smolv_bytes.data(), code_bytes.size());
+
+			// Compress.
+			uint32_t compressed_size = 0;
+			shader.code_decompressed_size = code_bytes.size();
+			shader.code_compressed_bytes.resize(code_bytes.size());
+
+			bool compressed = compress_code(code_bytes.ptr(), code_bytes.size(), shader.code_compressed_bytes.ptrw(), &compressed_size, &shader.code_compression_flags);
+			ERR_FAIL_COND_V_MSG(!compressed, false, vformat("Failed to compress native code to native for SPIR-V #%d.", i));
+
+			shader.code_compressed_bytes.resize(compressed_size);
+
+			// Indicate it uses smolv for compression.
+			shader.code_compression_flags |= COMPRESSION_FLAG_SMOLV;
+		}
+
 		shader.shader_stage = p_spirv[i].shader_stage;
 	}
 
 	return true;
 }
 
+RenderingShaderContainerVulkan::RenderingShaderContainerVulkan(bool p_debug_info_enabled) {
+	debug_info_enabled = p_debug_info_enabled;
+}
+
 // RenderingShaderContainerFormatVulkan
 
 Ref<RenderingShaderContainer> RenderingShaderContainerFormatVulkan::create_container() const {
-	return memnew(RenderingShaderContainerVulkan);
+	return memnew(RenderingShaderContainerVulkan(debug_info_enabled));
 }
 
 RenderingDeviceCommons::ShaderLanguageVersion RenderingShaderContainerFormatVulkan::get_shader_language_version() const {
@@ -98,6 +102,10 @@ RenderingDeviceCommons::ShaderSpirvVersion RenderingShaderContainerFormatVulkan:
 	return SHADER_SPIRV_VERSION_1_3;
 }
 
+void RenderingShaderContainerFormatVulkan::set_debug_info_enabled(bool p_debug_info_enabled) {
+	debug_info_enabled = p_debug_info_enabled;
+}
+
 RenderingShaderContainerFormatVulkan::RenderingShaderContainerFormatVulkan() {}
 
 RenderingShaderContainerFormatVulkan::~RenderingShaderContainerFormatVulkan() {}

+ 13 - 3
drivers/vulkan/rendering_shader_container_vulkan.h

@@ -32,26 +32,36 @@
 
 #include "servers/rendering/rendering_shader_container.h"
 
-#define RENDERING_SHADER_CONTAINER_VULKAN_COMPRESSION 1
-#define RENDERING_SHADER_CONTAINER_VULKAN_SMOLV 1
-
 class RenderingShaderContainerVulkan : public RenderingShaderContainer {
 	GDSOFTCLASS(RenderingShaderContainerVulkan, RenderingShaderContainer);
 
 public:
 	static const uint32_t FORMAT_VERSION;
 
+	enum CompressionFlagsVulkan {
+		COMPRESSION_FLAG_SMOLV = 0x10000,
+	};
+
+	bool debug_info_enabled = false;
+
 protected:
 	virtual uint32_t _format() const override;
 	virtual uint32_t _format_version() const override;
 	virtual bool _set_code_from_spirv(const Vector<RenderingDeviceCommons::ShaderStageSPIRVData> &p_spirv) override;
+
+public:
+	RenderingShaderContainerVulkan(bool p_debug_info_enabled);
 };
 
 class RenderingShaderContainerFormatVulkan : public RenderingShaderContainerFormat {
+private:
+	bool debug_info_enabled = false;
+
 public:
 	virtual Ref<RenderingShaderContainer> create_container() const override;
 	virtual ShaderLanguageVersion get_shader_language_version() const override;
 	virtual ShaderSpirvVersion get_shader_spirv_version() const override;
+	void set_debug_info_enabled(bool p_debug_info_enabled);
 	RenderingShaderContainerFormatVulkan();
 	virtual ~RenderingShaderContainerFormatVulkan();
 };

+ 5 - 0
editor/export/shader_baker_export_plugin.cpp

@@ -103,6 +103,11 @@ bool ShaderBakerExportPlugin::_begin_customize_resources(const Ref<EditorExportP
 		return false;
 	}
 
+	if (Engine::get_singleton()->is_generate_spirv_debug_info_enabled()) {
+		WARN_PRINT("Shader baker can't generate a compatible shader when run with --generate-spirv-debug-info. Restart the editor without this argument if you want to bake shaders.");
+		return false;
+	}
+
 	shader_cache_platform_name = p_platform->get_os_name();
 	shader_cache_renderer_name = RendererSceneRenderRD::get_singleton()->get_name();
 	tasks_processed = 0;

+ 2 - 0
servers/rendering/renderer_rd/shader_rd.cpp

@@ -158,6 +158,8 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
 	tohash.append(p_fragment_code ? p_fragment_code : "");
 	tohash.append("[Compute]");
 	tohash.append(p_compute_code ? p_compute_code : "");
+	tohash.append("[DebugInfo]");
+	tohash.append(Engine::get_singleton()->is_generate_spirv_debug_info_enabled() ? "1" : "0");
 
 	base_sha256 = tohash.as_string().sha256_text();
 }