diff --git a/renderdoc/driver/shaders/spirv/spirv_editor.cpp b/renderdoc/driver/shaders/spirv/spirv_editor.cpp index 2456a540a..17dfa4fd2 100644 --- a/renderdoc/driver/shaders/spirv/spirv_editor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_editor.cpp @@ -191,6 +191,16 @@ std::vector SPIRVEditor::GetWords() for(const LogicalSection §ion : {typeVarSection, decorationSection, debugSection}) ret.insert(ret.begin() + section.iter.offset, section.additions.begin(), section.additions.end()); + // remove any Nops + + for(size_t i = 5; i < ret.size();) + { + while(ret[i] == SPV_NOP) + ret.erase(ret.begin() + i); + + i += ret[i] >> spv::WordCountShift; + } + return ret; } diff --git a/renderdoc/driver/shaders/spirv/spirv_editor.h b/renderdoc/driver/shaders/spirv/spirv_editor.h index f1ce57c14..4c602f6f9 100644 --- a/renderdoc/driver/shaders/spirv/spirv_editor.h +++ b/renderdoc/driver/shaders/spirv/spirv_editor.h @@ -33,6 +33,9 @@ class SPIRVOperation; class SPIRVEditor; +// length of 1 word in the top 16-bits, OpNop = 0 in the lower 16-bits +#define SPV_NOP (0x00010000) + class SPIRVIterator { public: @@ -40,10 +43,20 @@ public: SPIRVIterator() = default; SPIRVIterator(std::vector &w, size_t o) : words(&w), offset(o) {} // increment to the next op - SPIRVIterator &operator++(int) { return operator++(); } - SPIRVIterator &operator++() + SPIRVIterator operator++(int) { - offset += cur() >> spv::WordCountShift; + SPIRVIterator ret = *this; + operator++(); + return ret; + } + SPIRVIterator operator++() + { + do + { + offset += cur() >> spv::WordCountShift; + // silently skip nops + } while(*this && opcode() == spv::OpNop); + return *this; } // utility functions @@ -93,15 +106,27 @@ public: uint32_t &operator[](size_t idx) { return iter.word(idx); } const uint32_t &operator[](size_t idx) const { return iter.word(idx); } size_t size() const { return iter.size(); } - void push_back(uint32_t word) + void nopRemove() { - spv::Op op = iter.opcode(); - size_t count = iter.size(); - iter.words->insert(iter.it() + count, word); + for(size_t i = 0, sz = size(); i < sz; i++) + iter.word(i) = SPV_NOP; + } + void nopRemove(size_t idx, size_t count = 0) + { + size_t oldSize = size(); - // since the length is in the high-order bits, we have to extract/increment/insert instead of - // just incrementing. Boo! - *iter = MakeHeader(op, count + 1); + if(count == 0) + count = oldSize - idx; + + // reduce the size of this op + *iter = MakeHeader(iter.opcode(), oldSize - count); + + // move any words on the end into the middle, then nop them + for(size_t i = 0; i < count; i++) + { + iter.word(idx + i) = iter.word(idx + count + i); + iter.word(oldSize - i - 1) = SPV_NOP; + } } private: