From b62af7c64f4161ed9629a49eaae75d5d29af1356 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 23 Oct 2026 16:43:49 +0100 Subject: [PATCH] Return success from SPIR-V parse, add overload to move SPIR-V words --- renderdoc/driver/shaders/spirv/spirv_debug.h | 4 +- .../shaders/spirv/spirv_debug_setup.cpp | 5 -- .../driver/shaders/spirv/spirv_processor.cpp | 76 ++++++++++++++++--- .../driver/shaders/spirv/spirv_processor.h | 5 +- .../driver/shaders/spirv/spirv_reflect.cpp | 7 +- .../driver/shaders/spirv/spirv_reflect.h | 3 +- 6 files changed, 77 insertions(+), 23 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.h b/renderdoc/driver/shaders/spirv/spirv_debug.h index acc52c3b0..36452744f 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.h +++ b/renderdoc/driver/shaders/spirv/spirv_debug.h @@ -699,7 +699,9 @@ class Debugger : public Processor, public ShaderDebugger public: Debugger(); ~Debugger(); - virtual void Parse(const rdcarray &spirvWords); + + using Processor::Parse; + ShaderDebugTrace *BeginDebug(DebugAPIWrapper *apiWrapper, const ShaderStage stage, const rdcstr &entryPoint, const rdcarray &specInfo, const std::map &instructionLines, diff --git a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp index fce8dfdef..e698af371 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug_setup.cpp @@ -331,11 +331,6 @@ void Debugger::ClampScalars(const ShaderVariable &var, uint8_t &scalar0, uint8_t } } -void Debugger::Parse(const rdcarray &spirvWords) -{ - Processor::Parse(spirvWords); -} - ConstIter Debugger::GetIterForInstruction(uint32_t inst) const { return ConstIter(m_SPIRV, instructionOffsets[inst]); diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.cpp b/renderdoc/driver/shaders/spirv/spirv_processor.cpp index 074d980ed..e6f1c3fa5 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_processor.cpp @@ -374,18 +374,15 @@ Processor::~Processor() { } -void Processor::Parse(const rdcarray &spirvWords) +bool Processor::Parse(const rdcarray &spirvWords) { - m_SPIRV = spirvWords; - - if(m_SPIRV.size() < FirstRealWord || m_SPIRV[0] != MagicNumber) + if(spirvWords.size() < FirstRealWord || spirvWords[0] != MagicNumber) { RDCERR("Empty or invalid SPIR-V module"); - m_SPIRV.clear(); - return; + return false; } - uint32_t packedVersion = m_SPIRV[1]; + uint32_t packedVersion = spirvWords[1]; // Bytes: 0 | major | minor | 0 m_MajorVersion = uint8_t((packedVersion & 0x00ff0000) >> 16); @@ -394,10 +391,69 @@ void Processor::Parse(const rdcarray &spirvWords) if(packedVersion > VersionPacked) { RDCERR("Unsupported SPIR-V version: %08x", packedVersion); - m_SPIRV.clear(); - return; + return false; } + m_SPIRV = spirvWords; + + return Parse(); +} + +bool Processor::Parse(const void *spirvWords, size_t byteSize) +{ + const uint32_t wordCount = byteSize / sizeof(uint32_t); + const uint32_t *words = (const uint32_t *)spirvWords; + + if(wordCount < FirstRealWord || words[0] != MagicNumber) + { + RDCERR("Empty or invalid SPIR-V module"); + return false; + } + + uint32_t packedVersion = words[1]; + + // Bytes: 0 | major | minor | 0 + m_MajorVersion = uint8_t((packedVersion & 0x00ff0000) >> 16); + m_MinorVersion = uint8_t((packedVersion & 0x0000ff00) >> 8); + + if(packedVersion > VersionPacked) + { + RDCERR("Unsupported SPIR-V version: %08x", packedVersion); + return false; + } + + m_SPIRV.assign(words, wordCount); + + return Parse(); +} + +bool Processor::Parse(rdcarray &&spirvWords) +{ + if(spirvWords.size() < FirstRealWord || spirvWords[0] != MagicNumber) + { + RDCERR("Empty or invalid SPIR-V module"); + return false; + } + + uint32_t packedVersion = spirvWords[1]; + + // Bytes: 0 | major | minor | 0 + m_MajorVersion = uint8_t((packedVersion & 0x00ff0000) >> 16); + m_MinorVersion = uint8_t((packedVersion & 0x0000ff00) >> 8); + + if(packedVersion > VersionPacked) + { + RDCERR("Unsupported SPIR-V version: %08x", packedVersion); + return false; + } + + m_SPIRV = std::move(spirvWords); + + return Parse(); +} + +bool Processor::Parse() +{ m_Generator = Generator(m_SPIRV[2] >> 16); m_GeneratorVersion = m_SPIRV[2] & 0xffff; @@ -519,6 +575,8 @@ void Processor::Parse(const rdcarray &spirvWords) if(m_Sections[s - 1].startOffset == 0) m_Sections[s - 1].startOffset = m_Sections[s - 1].endOffset; } + + return true; } void Processor::PreParse(uint32_t maxId) diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.h b/renderdoc/driver/shaders/spirv/spirv_processor.h index 752a31c07..0a0348690 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.h +++ b/renderdoc/driver/shaders/spirv/spirv_processor.h @@ -591,7 +591,10 @@ public: const Decorations &GetDecorations(Id id) const { return decorations[id]; }; const rdcarray &GetSPIRV() const { return m_SPIRV; } protected: - virtual void Parse(const rdcarray &spirvWords); + bool Parse(rdcarray &&spirvWords); + bool Parse(const void *spirvWords, size_t byteSize); + bool Parse(const rdcarray &spirvWords); + bool Parse(); rdcarray m_SPIRV; diff --git a/renderdoc/driver/shaders/spirv/spirv_reflect.cpp b/renderdoc/driver/shaders/spirv/spirv_reflect.cpp index 4db7baba6..3bb78d7da 100644 --- a/renderdoc/driver/shaders/spirv/spirv_reflect.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_reflect.cpp @@ -596,11 +596,6 @@ Reflector::Reflector() { } -void Reflector::Parse(const rdcarray &spirvWords) -{ - Processor::Parse(spirvWords); -} - void Reflector::PreParse(uint32_t maxId) { Processor::PreParse(maxId); @@ -2619,7 +2614,7 @@ TEST_CASE("Validate SPIR-V reflection", "[spirv][reflection]") REQUIRE(!spirv.empty()); rdcspv::Reflector spv; - spv.Parse(spirv); + spv.Parse(std::move(spirv)); SPIRVPatchData patchData; spv.MakeReflection(type == ShaderType::Vulkan ? GraphicsAPI::Vulkan : GraphicsAPI::OpenGL, diff --git a/renderdoc/driver/shaders/spirv/spirv_reflect.h b/renderdoc/driver/shaders/spirv/spirv_reflect.h index 36c03f845..2a710f446 100644 --- a/renderdoc/driver/shaders/spirv/spirv_reflect.h +++ b/renderdoc/driver/shaders/spirv/spirv_reflect.h @@ -111,7 +111,8 @@ class Reflector : public Processor { public: Reflector(); - virtual void Parse(const rdcarray &spirvWords); + + using Processor::Parse; rdcstr Disassemble(const rdcstr &entryPoint, const rdcarray &specInfo, std::map &instructionLines) const;