Renderer: Move reflect_spirv to RenderingShaderContainer

This change introduces a new protected type, `ReflectedShaderStage` to
`RenderingShaderContainer` that derived types use to access SPIR-V and
the reflected module, `SpvReflectShaderModule` allowing implementations
to use the reflection information to compile their platform-specific
module.

* Fixes memory leak in `reflect_spirv` that would not deallocate the
  `SpvReflectShaderModule` if an error occurred.
* Removes unnecessary allocation when creating `SpvReflectShaderModule`
  by passing `NO_COPY` flag to `spvReflectCreateShaderModule2`
  constructor function.
* Replaces `VectorView` with `Span` for consistency
* Fixes unnecessary allocations in D3D12 shader container in
  `_convert_spirv_to_nir` and `_convert_spirv_to_dxil` which implicitly
  converted the old `VectorView` to a `Vector`
This commit is contained in:
Stuart Carnie 2025-09-29 07:04:23 +10:00
parent 9283328fe7
commit 65e8b0951b
12 changed files with 425 additions and 391 deletions

View file

@ -33,6 +33,8 @@
#include "core/object/ref_counted.h"
#include "servers/rendering/rendering_device_commons.h"
struct SpvReflectShaderModule;
class RenderingShaderContainer : public RefCounted {
GDSOFTCLASS(RenderingShaderContainer, RefCounted);
@ -118,10 +120,29 @@ protected:
virtual uint32_t _to_bytes_footer_extra_data(uint8_t *p_bytes) const;
// This method will be called when set_from_shader_reflection() is finished. Used to update internal structures to match the reflection if necessary.
virtual void _set_from_shader_reflection_post(const String &p_shader_name, const RenderingDeviceCommons::ShaderReflection &p_reflection);
virtual void _set_from_shader_reflection_post(const RenderingDeviceCommons::ShaderReflection &p_reflection);
class ReflectedShaderStage {
friend class RenderingShaderContainer;
Vector<uint8_t> _spirv_data;
SpvReflectShaderModule *_module = nullptr;
public:
RenderingDeviceCommons::ShaderStage shader_stage = RenderingDeviceCommons::SHADER_STAGE_MAX;
const SpvReflectShaderModule &module() const;
const Span<uint32_t> spirv() const;
const Vector<uint8_t> spirv_data() const { return _spirv_data; }
ReflectedShaderStage();
~ReflectedShaderStage();
};
// This method will be called when set_code_from_spirv() is called.
virtual bool _set_code_from_spirv(const Vector<RenderingDeviceCommons::ShaderStageSPIRVData> &p_spirv) = 0;
virtual bool _set_code_from_spirv(Span<ReflectedShaderStage> p_spirv) = 0;
void set_from_shader_reflection(const RenderingDeviceCommons::ShaderReflection &p_reflection);
Error reflect_spirv(const String &p_shader_name, Span<RenderingDeviceCommons::ShaderStageSPIRVData> p_spirv, LocalVector<ReflectedShaderStage> &r_refl);
public:
enum CompressionFlags {
@ -138,8 +159,7 @@ public:
CharString shader_name;
Vector<Shader> shaders;
void set_from_shader_reflection(const String &p_shader_name, const RenderingDeviceCommons::ShaderReflection &p_reflection);
bool set_code_from_spirv(const Vector<RenderingDeviceCommons::ShaderStageSPIRVData> &p_spirv);
bool set_code_from_spirv(const String &p_shader_name, Span<RenderingDeviceCommons::ShaderStageSPIRVData> p_spirv);
RenderingDeviceCommons::ShaderReflection get_shader_reflection() const;
bool from_bytes(const PackedByteArray &p_bytes);
PackedByteArray to_bytes() const;