From fc452b7586ec93a52354130244fc46e13b3e4eb3 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 10 Apr 2020 12:56:10 +0100 Subject: [PATCH] Add helpers to create an empty SPIR-V module in an editor --- .../driver/shaders/spirv/spirv_editor.cpp | 30 ++++++++++++++++--- renderdoc/driver/shaders/spirv/spirv_editor.h | 1 + .../driver/shaders/spirv/spirv_processor.cpp | 4 +++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_editor.cpp b/renderdoc/driver/shaders/spirv/spirv_editor.cpp index ddb88a5f4..d932842a7 100644 --- a/renderdoc/driver/shaders/spirv/spirv_editor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_editor.cpp @@ -117,15 +117,37 @@ void Editor::Prepare() } } +void Editor::CreateEmpty(uint32_t major, uint32_t minor) +{ + if(!m_ExternalSPIRV.empty()) + { + RDCERR("Creating empty SPIR-V module with some SPIR-V words already in place!"); + m_ExternalSPIRV.clear(); + } + + // create an empty SPIR-V header with an upper ID bound of 1 + + m_ExternalSPIRV = { + MagicNumber, (major << 16) | (minor << 8), + 0, // TODO maybe register a generator ID? + 1, // bound + 0, // instruction schema + }; + + // we need at least one opcode to parse properly, and we'll always need shader. + Operation shader = Operation(OpCapability(Capability::Shader)); + m_ExternalSPIRV.append(&shader[0], shader.size()); + + Prepare(); +} + Editor::~Editor() { for(size_t i = FirstRealWord; i < m_SPIRV.size();) { - while(m_SPIRV[i] == OpNopWord) - { + // don't need to update anything as we're destructing! + while(i < m_SPIRV.size() && m_SPIRV[i] == OpNopWord) m_SPIRV.erase(i); - addWords(i, -1); - } uint32_t len = m_SPIRV[i] >> WordCountShift; diff --git a/renderdoc/driver/shaders/spirv/spirv_editor.h b/renderdoc/driver/shaders/spirv/spirv_editor.h index 2aec15d0b..fa1dc4988 100644 --- a/renderdoc/driver/shaders/spirv/spirv_editor.h +++ b/renderdoc/driver/shaders/spirv/spirv_editor.h @@ -122,6 +122,7 @@ public: ~Editor(); void Prepare(); + void CreateEmpty(uint32_t major, uint32_t minor); Id MakeId(); diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.cpp b/renderdoc/driver/shaders/spirv/spirv_processor.cpp index 428b44c10..b9f16e001 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_processor.cpp @@ -422,6 +422,10 @@ void Processor::Parse(const rdcarray &spirvWords) // ensure we got everything right. First section should start at the beginning RDCASSERTEQUAL(m_Sections[Section::First].startOffset, FirstRealWord); + // if the last section is empty, set its start ofset. This will cascade below + if(m_Sections[Section::Count - 1].startOffset == 0) + m_Sections[Section::Count - 1].startOffset = m_Sections[Section::Count - 1].endOffset; + // we now set the endOffset of each section to the start of the next. Any empty sections // temporarily have startOffset set to endOffset, we'll pad them with a nop below. for(int s = Section::Count - 1; s > 0; s--)