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

@ -292,7 +292,7 @@ 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;
virtual bool _set_code_from_spirv(Span<ReflectedShaderStage> p_spirv) override;
};
class RenderingShaderContainerFormatMetal : public RenderingShaderContainerFormat {

View File

@ -253,7 +253,7 @@ Error RenderingShaderContainerMetal::compile_metal_source(const char *p_source,
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
bool RenderingShaderContainerMetal::_set_code_from_spirv(const Vector<RenderingDeviceCommons::ShaderStageSPIRVData> &p_spirv) {
bool RenderingShaderContainerMetal::_set_code_from_spirv(Span<ReflectedShaderStage> p_spirv) {
using namespace spirv_cross;
using spirv_cross::CompilerMSL;
using spirv_cross::Resource;
@ -354,12 +354,11 @@ bool RenderingShaderContainerMetal::_set_code_from_spirv(const Vector<RenderingD
for (uint32_t i = 0; i < p_spirv.size(); i++) {
StageData &stage_data = mtl_shaders.write[i];
RD::ShaderStageSPIRVData const &v = p_spirv[i];
const ReflectedShaderStage &v = p_spirv[i];
RD::ShaderStage stage = v.shader_stage;
char const *stage_name = RD::SHADER_STAGE_NAMES[stage];
uint32_t const *const ir = reinterpret_cast<uint32_t const *const>(v.spirv.ptr());
size_t word_count = v.spirv.size() / sizeof(uint32_t);
Parser parser(ir, word_count);
Span<uint32_t> spirv = v.spirv();
Parser parser(spirv.ptr(), spirv.size());
try {
parser.parse();
} catch (CompilerError &e) {