Merge pull request #110025 from DarioSamo/fix-shader-debug-info-take-two

Fix --generate-spirv-debug-info regression (alternate take)
This commit is contained in:
Clay John 2025-09-01 19:37:27 -07:00 committed by GitHub
commit 0f0bb7d225
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 71 additions and 50 deletions

View file

@ -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;

View file

@ -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));
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.code_compressed_bytes.resize(compressed_size);
#else
shader.code_decompressed_size = 0;
shader.code_compression_flags = 0;
shader.code_compressed_bytes = code_bytes;
#endif
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() {}

View file

@ -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();
};

View file

@ -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;

View file

@ -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();
}