From 50b34a2bb7a6a2c638c5ce5f212c08eda5effa46 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 16 Jan 2018 16:54:32 +0000 Subject: [PATCH] Merge SPIRVVoid into SPIRVScalar, add image types, reduce copy-paste * We use templates to reduce copy-paste between the different types since it's the same operation of "look up a map, if not found then declare and add to map", just with a different typed map. --- .../driver/shaders/spirv/spirv_editor.cpp | 181 ++++++++---------- renderdoc/driver/shaders/spirv/spirv_editor.h | 130 ++++++++++--- renderdoc/driver/vulkan/vk_postvs.cpp | 2 +- 3 files changed, 190 insertions(+), 123 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_editor.cpp b/renderdoc/driver/shaders/spirv/spirv_editor.cpp index ebc3320b3..13e0d0588 100644 --- a/renderdoc/driver/shaders/spirv/spirv_editor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_editor.cpp @@ -37,7 +37,7 @@ SPIRVScalar::SPIRVScalar(SPIRVIterator it) { type = it.opcode(); - if(type != spv::OpTypeBool) + if(type == spv::OpTypeInt || type == spv::OpTypeFloat) width = it.word(2); else width = 0; @@ -48,6 +48,44 @@ SPIRVScalar::SPIRVScalar(SPIRVIterator it) signedness = false; } +SPIRVOperation SPIRVVector::decl(SPIRVEditor &editor) const +{ + return SPIRVOperation(spv::OpTypeVector, {0U, editor.DeclareType(scalar), count}); +} + +SPIRVOperation SPIRVMatrix::decl(SPIRVEditor &editor) const +{ + return SPIRVOperation(spv::OpTypeMatrix, {0U, editor.DeclareType(vector), count}); +} + +SPIRVOperation SPIRVPointer::decl(SPIRVEditor &editor) const +{ + return SPIRVOperation(spv::OpTypePointer, {0U, (uint32_t)storage, baseId}); +} + +SPIRVOperation SPIRVImage::decl(SPIRVEditor &editor) const +{ + return SPIRVOperation(spv::OpTypeImage, {0U, editor.DeclareType(retType), (uint32_t)dim, depth, + arrayed, ms, sampled, (uint32_t)format}); +} + +SPIRVOperation SPIRVSampledImage::decl(SPIRVEditor &editor) const +{ + return SPIRVOperation(spv::OpTypeSampledImage, {0U, baseId}); +} + +SPIRVOperation SPIRVFunction::decl(SPIRVEditor &editor) const +{ + std::vector words; + + words.push_back(0U); + words.push_back(returnId); + for(SPIRVId id : argumentIds) + words.push_back(id); + + return SPIRVOperation(spv::OpTypeFunction, words); +} + SPIRVEditor::SPIRVEditor(std::vector &spirvWords) : spirv(spirvWords) { if(spirv.size() < 5 || spirv[0] != spv::MagicNumber) @@ -140,7 +178,8 @@ SPIRVEditor::SPIRVEditor(std::vector &spirvWords) : spirv(spirvWords) } // identify declared scalar/vector/matrix types - if(opcode == spv::OpTypeBool || opcode == spv::OpTypeInt || opcode == spv::OpTypeFloat) + if(opcode == spv::OpTypeVoid || opcode == spv::OpTypeBool || opcode == spv::OpTypeInt || + opcode == spv::OpTypeFloat) { uint32_t id = it.word(1); idOffsets[id] = it.offset; @@ -204,12 +243,6 @@ SPIRVEditor::SPIRVEditor(std::vector &spirvWords) : spirv(spirvWords) functionTypes[SPIRVFunction(it.word(2), args)] = id; } - - if(opcode == spv::OpTypeVoid) - { - voidType = it.word(1); - idOffsets[voidType] = it.offset; - } } } @@ -348,96 +381,6 @@ SPIRVIterator SPIRVEditor::EndTypes() return SPIRVIterator(spirv, typeVarSection.endOffset); } -SPIRVId SPIRVEditor::DeclareType(const SPIRVVoid &) -{ - if(voidType) - return voidType; - - voidType = MakeId(); - AddType(SPIRVOperation(spv::OpTypeVoid, {voidType})); - - return voidType; -} - -SPIRVId SPIRVEditor::DeclareType(const SPIRVScalar &scalar) -{ - auto it = scalarTypes.lower_bound(scalar); - if(it != scalarTypes.end() && it->first == scalar) - return it->second; - - SPIRVOperation decl = scalar.decl(); - SPIRVId id = decl[1] = MakeId(); - AddType(decl); - - scalarTypes.insert(it, std::make_pair(scalar, id)); - - return id; -} - -SPIRVId SPIRVEditor::DeclareType(const SPIRVVector &vector) -{ - auto it = vectorTypes.lower_bound(vector); - if(it != vectorTypes.end() && it->first == vector) - return it->second; - - SPIRVId id = MakeId(); - AddType(SPIRVOperation(spv::OpTypeVector, {id, DeclareType(vector.scalar), vector.count})); - - vectorTypes.insert(it, std::make_pair(vector, id)); - - return id; -} - -SPIRVId SPIRVEditor::DeclareType(const SPIRVMatrix &matrix) -{ - auto it = matrixTypes.lower_bound(matrix); - if(it != matrixTypes.end() && it->first == matrix) - return it->second; - - SPIRVId id = MakeId(); - AddType(SPIRVOperation(spv::OpTypeVector, {id, DeclareType(matrix.vector), matrix.count})); - - matrixTypes.insert(it, std::make_pair(matrix, id)); - - return id; -} - -SPIRVId SPIRVEditor::DeclareType(const SPIRVPointer &pointer) -{ - auto it = pointerTypes.lower_bound(pointer); - if(it != pointerTypes.end() && it->first == pointer) - return it->second; - - SPIRVId id = MakeId(); - AddType(SPIRVOperation(spv::OpTypePointer, {id, (uint32_t)pointer.storage, pointer.baseId})); - - pointerTypes.insert(it, std::make_pair(pointer, id)); - - return id; -} - -SPIRVId SPIRVEditor::DeclareType(const SPIRVFunction &func) -{ - auto it = functionTypes.lower_bound(func); - if(it != functionTypes.end() && it->first == func) - return it->second; - - SPIRVId id = MakeId(); - - std::vector words; - - words.push_back(id); - words.push_back(func.returnId); - for(SPIRVId id : func.argumentIds) - words.push_back(id); - - AddType(SPIRVOperation(spv::OpTypeFunction, words)); - - functionTypes.insert(it, std::make_pair(func, id)); - - return id; -} - SPIRVId SPIRVEditor::DeclareStructType(std::vector members) { SPIRVId typeId = MakeId(); @@ -487,3 +430,45 @@ void SPIRVEditor::addWords(size_t offs, int32_t num) if(o >= offs) o += num; } + +template <> +std::map &SPIRVEditor::GetTable() +{ + return scalarTypes; +} + +template <> +std::map &SPIRVEditor::GetTable() +{ + return vectorTypes; +} + +template <> +std::map &SPIRVEditor::GetTable() +{ + return matrixTypes; +} + +template <> +std::map &SPIRVEditor::GetTable() +{ + return pointerTypes; +} + +template <> +std::map &SPIRVEditor::GetTable() +{ + return imageTypes; +} + +template <> +std::map &SPIRVEditor::GetTable() +{ + return sampledImageTypes; +} + +template <> +std::map &SPIRVEditor::GetTable() +{ + return functionTypes; +} diff --git a/renderdoc/driver/shaders/spirv/spirv_editor.h b/renderdoc/driver/shaders/spirv/spirv_editor.h index 2d7db3b5f..bde23e867 100644 --- a/renderdoc/driver/shaders/spirv/spirv_editor.h +++ b/renderdoc/driver/shaders/spirv/spirv_editor.h @@ -172,10 +172,6 @@ struct SPIRVEntry std::string name; }; -struct SPIRVVoid -{ -}; - struct SPIRVScalar { constexpr SPIRVScalar(spv::Op t, uint32_t w, bool s) : type(t), width(w), signedness(s) {} @@ -200,16 +196,18 @@ struct SPIRVScalar return type == o.type && width == o.width && signedness == o.signedness; } - inline SPIRVOperation decl() const + SPIRVOperation decl(SPIRVEditor &editor) const { - if(type == spv::Op::OpTypeBool) + if(type == spv::OpTypeVoid) return SPIRVOperation(type, {0}); - else if(type == spv::Op::OpTypeFloat) + else if(type == spv::OpTypeBool) + return SPIRVOperation(type, {0}); + else if(type == spv::OpTypeFloat) return SPIRVOperation(type, {0, width}); - else if(type == spv::Op::OpTypeInt) + else if(type == spv::OpTypeInt) return SPIRVOperation(type, {0, width, signedness ? 1U : 0U}); else - return SPIRVOperation(spv::Op::OpNop, {0}); + return SPIRVOperation(spv::OpNop, {0}); } }; @@ -224,13 +222,14 @@ inline constexpr SPIRVScalar scalar(); return SPIRVScalar(op, width, sign); \ } -SCALAR_TYPE(bool, spv::Op::OpTypeBool, 0, false); -SCALAR_TYPE(uint16_t, spv::Op::OpTypeInt, 16, false); -SCALAR_TYPE(uint32_t, spv::Op::OpTypeInt, 32, false); -SCALAR_TYPE(int16_t, spv::Op::OpTypeInt, 16, true); -SCALAR_TYPE(int32_t, spv::Op::OpTypeInt, 32, true); -SCALAR_TYPE(float, spv::Op::OpTypeFloat, 32, false); -SCALAR_TYPE(double, spv::Op::OpTypeFloat, 64, false); +SCALAR_TYPE(void, spv::OpTypeVoid, 0, false); +SCALAR_TYPE(bool, spv::OpTypeBool, 0, false); +SCALAR_TYPE(uint16_t, spv::OpTypeInt, 16, false); +SCALAR_TYPE(uint32_t, spv::OpTypeInt, 32, false); +SCALAR_TYPE(int16_t, spv::OpTypeInt, 16, true); +SCALAR_TYPE(int32_t, spv::OpTypeInt, 32, true); +SCALAR_TYPE(float, spv::OpTypeFloat, 32, false); +SCALAR_TYPE(double, spv::OpTypeFloat, 64, false); struct SPIRVVector { @@ -247,6 +246,7 @@ struct SPIRVVector bool operator!=(const SPIRVVector &o) const { return !operator==(o); } bool operator==(const SPIRVVector &o) const { return scalar == o.scalar && count == o.count; } + SPIRVOperation decl(SPIRVEditor &editor) const; }; struct SPIRVMatrix @@ -264,6 +264,7 @@ struct SPIRVMatrix bool operator!=(const SPIRVMatrix &o) const { return !operator==(o); } bool operator==(const SPIRVMatrix &o) const { return vector == o.vector && count == o.count; } + SPIRVOperation decl(SPIRVEditor &editor) const; }; struct SPIRVPointer @@ -284,6 +285,59 @@ struct SPIRVPointer { return baseId == o.baseId && storage == o.storage; } + SPIRVOperation decl(SPIRVEditor &editor) const; +}; + +struct SPIRVImage +{ + SPIRVImage(SPIRVScalar ret, spv::Dim d, uint32_t dp, uint32_t ar, uint32_t m, uint32_t samp, + spv::ImageFormat f) + : retType(ret), dim(d), depth(dp), arrayed(ar), ms(m), sampled(samp), format(f) + { + } + + SPIRVScalar retType; + spv::Dim dim; + uint32_t depth; + uint32_t arrayed; + uint32_t ms; + uint32_t sampled; + spv::ImageFormat format; + + bool operator<(const SPIRVImage &o) const + { + if(retType != o.retType) + return retType < o.retType; + if(dim != o.dim) + return dim < o.dim; + if(depth != o.depth) + return depth < o.depth; + if(arrayed != o.arrayed) + return arrayed < o.arrayed; + if(ms != o.ms) + return ms < o.ms; + if(sampled != o.sampled) + return sampled < o.sampled; + return format < o.format; + } + bool operator!=(const SPIRVImage &o) const { return !operator==(o); } + bool operator==(const SPIRVImage &o) const + { + return retType == o.retType && dim == o.dim && depth == o.depth && arrayed == o.arrayed && + ms == o.ms && sampled == o.sampled && format == o.format; + } + SPIRVOperation decl(SPIRVEditor &editor) const; +}; + +struct SPIRVSampledImage +{ + SPIRVSampledImage(SPIRVId b) : baseId(b) {} + SPIRVId baseId; + + bool operator<(const SPIRVSampledImage &o) const { return baseId < o.baseId; } + bool operator!=(const SPIRVSampledImage &o) const { return !operator==(o); } + bool operator==(const SPIRVSampledImage &o) const { return baseId == o.baseId; } + SPIRVOperation decl(SPIRVEditor &editor) const; }; struct SPIRVFunction @@ -304,6 +358,7 @@ struct SPIRVFunction { return returnId == o.returnId && argumentIds == o.argumentIds; } + SPIRVOperation decl(SPIRVEditor &editor) const; }; class SPIRVEditor @@ -337,12 +392,35 @@ public: // fetches the id of this type. If it exists already the old ID will be returned, otherwise it // will be declared and the new ID returned - SPIRVId DeclareType(const SPIRVVoid &); - SPIRVId DeclareType(const SPIRVScalar &scalar); - SPIRVId DeclareType(const SPIRVVector &vector); - SPIRVId DeclareType(const SPIRVMatrix &matrix); - SPIRVId DeclareType(const SPIRVPointer &pointer); - SPIRVId DeclareType(const SPIRVFunction &func); + template + SPIRVId DeclareType(const SPIRVType &t) + { + std::map &table = GetTable(); + + auto it = table.lower_bound(t); + if(it != table.end() && it->first == t) + return it->second; + + SPIRVOperation decl = t.decl(*this); + SPIRVId id = decl[1] = MakeId(); + AddType(decl); + + table.insert(it, std::make_pair(t, id)); + + return id; + } + + template + SPIRVId GetType(const SPIRVType &t) + { + std::map &table = GetTable(); + + auto it = table.find(t); + if(it != table.end()) + return it->second; + + return SPIRVId(); + } SPIRVId DeclareStructType(std::vector members); @@ -397,8 +475,12 @@ private: std::map vectorTypes; std::map matrixTypes; std::map pointerTypes; + std::map imageTypes; + std::map sampledImageTypes; std::map functionTypes; - SPIRVId voidType; + + template + std::map &GetTable(); std::vector &spirv; -}; +}; \ No newline at end of file diff --git a/renderdoc/driver/vulkan/vk_postvs.cpp b/renderdoc/driver/vulkan/vk_postvs.cpp index f00aeff70..25f436ab5 100644 --- a/renderdoc/driver/vulkan/vk_postvs.cpp +++ b/renderdoc/driver/vulkan/vk_postvs.cpp @@ -242,7 +242,7 @@ static void AddOutputDumping(const ShaderReflection &refl, const SPIRVPatchData { std::vector ops; - SPIRVId voidType = editor.DeclareType(SPIRVVoid()); + SPIRVId voidType = editor.DeclareType(scalar()); SPIRVId funcType = editor.DeclareType(SPIRVFunction(voidType, {})); ops.push_back(SPIRVOperation(spv::OpFunction,