diff --git a/renderdoc/driver/shaders/spirv/spirv_editor.cpp b/renderdoc/driver/shaders/spirv/spirv_editor.cpp index cbbb24f2e..845d59e53 100644 --- a/renderdoc/driver/shaders/spirv/spirv_editor.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_editor.cpp @@ -678,6 +678,15 @@ void Editor::RegisterOp(Iter it) if(decorate.decoration == Decoration::BufferBlock) m_BufferBlockTypes.push_back(decorate.target); } + else if(opdata.op == Op::Constant) + { + if(dataTypes[opdata.resultType].IsU32()) + { + uint32_t val = it.word(3); + if(m_U32Consts[val] == rdcspv::Id()) + m_U32Consts[val] = opdata.result; + } + } } void Editor::UnregisterOp(Iter it) @@ -740,6 +749,15 @@ void Editor::UnregisterOp(Iter it) if(decorate.decoration == Decoration::BufferBlock) m_BufferBlockTypes.removeOne(decorate.target); } + else if(opdata.op == Op::Constant) + { + if(dataTypes[opdata.resultType].IsU32()) + { + uint32_t val = it.word(3); + if(m_U32Consts[val] == opdata.result) + m_U32Consts[val] = rdcspv::Id(); + } + } } void Editor::RegisterBuiltinMembers(rdcspv::Id baseId, const rdcarray chainSoFar, diff --git a/renderdoc/driver/shaders/spirv/spirv_editor.h b/renderdoc/driver/shaders/spirv/spirv_editor.h index 6c70cdec5..415d32dbd 100644 --- a/renderdoc/driver/shaders/spirv/spirv_editor.h +++ b/renderdoc/driver/shaders/spirv/spirv_editor.h @@ -26,6 +26,7 @@ #include #include +#include #include "api/replay/rdcarray.h" #include "spirv_common.h" #include "spirv_processor.h" @@ -297,6 +298,9 @@ private: std::map builtinInputs; + // optimise for repeated U32 constants, only register once + std::unordered_map m_U32Consts; + BufferStorageMode m_StorageMode = BufferStorageMode::Unknown; std::map bindings; @@ -335,6 +339,18 @@ inline Id Editor::AddConstantImmediate(bool b) return AddConstant(Operation(b ? Op::ConstantTrue : Op::ConstantFalse, words)); } +template <> +inline Id Editor::AddConstantImmediate(uint32_t b) +{ + Id typeId = DeclareType(scalar()); + + if(m_U32Consts[b] != rdcspv::Id()) + return m_U32Consts[b]; + + rdcspv::Id constantId = MakeId(); + return AddConstant(Operation(Op::Constant, {typeId.value(), constantId.value(), b})); +} + template <> inline Id Editor::AddSpecConstantImmediate(bool b, uint32_t specId) { diff --git a/renderdoc/driver/shaders/spirv/spirv_processor.h b/renderdoc/driver/shaders/spirv/spirv_processor.h index afdeaa3c9..830c4a5fa 100644 --- a/renderdoc/driver/shaders/spirv/spirv_processor.h +++ b/renderdoc/driver/shaders/spirv/spirv_processor.h @@ -372,6 +372,11 @@ struct DataType const Vector &vector() const { return basicType.vector; } const Matrix &matrix() const { return basicType; } Id InnerType() const { return pointerType.baseId; } + bool IsU32() const + { + return type == Type::ScalarType && basicType.vector.scalar.width == 32 && + basicType.vector.scalar.type == Op::TypeInt && !basicType.vector.scalar.signedness; + } bool IsOpaqueType() const { switch(type)