From babbdadc36f9dd937c7d4593d134c851f690e623 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 17 Aug 2020 12:43:36 +0100 Subject: [PATCH] Cache a single value inline in ImageSubresourceMap * Having a single subresource (range) is a common case, so avoid allocating storage in an array for that, only switch to the array when we have more than one range to store. --- renderdoc/driver/vulkan/vk_image_states.cpp | 12 +++++++----- renderdoc/driver/vulkan/vk_resources.h | 20 +++++++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/renderdoc/driver/vulkan/vk_image_states.cpp b/renderdoc/driver/vulkan/vk_image_states.cpp index 93397a1ad..2dbfb8a24 100644 --- a/renderdoc/driver/vulkan/vk_image_states.cpp +++ b/renderdoc/driver/vulkan/vk_image_states.cpp @@ -169,13 +169,15 @@ void ImageSubresourceMap::Split(bool splitAspects, bool splitLevels, bool splitL uint32_t newSplitSliceCount = splitDepth ? GetImageInfo().extent.depth : oldSplitSliceCount; uint32_t oldSize = (uint32_t)m_values.size(); - RDCASSERT(oldSize > 0); uint32_t newSize = newSplitAspectCount * newSplitLevelCount * newSplitLayerCount * newSplitSliceCount; - RDCASSERT(newSize > oldSize); + RDCASSERT(newSize > RDCMAX(oldSize, 1U)); m_values.resize(newSize); + // if m_values was empty before, copy the first value from our inline storage + if(oldSize == 0) + m_values[0] = m_value; uint32_t newAspectIndex = newSplitAspectCount - 1; uint32_t oldAspectIndex = AreAspectsSplit() ? newAspectIndex : 0; @@ -322,7 +324,7 @@ void ImageSubresourceMap::Unsplit(bool unsplitAspects, bool unsplitLevels, bool void ImageSubresourceMap::Unsplit() { - if(m_values.size() == 1) + if(m_values.size() <= 1) return; uint32_t aspectCount = AreAspectsSplit() ? m_aspectCount : 1; @@ -449,7 +451,7 @@ size_t ImageSubresourceMap::SubresourceIndex(uint32_t aspectIndex, uint32_t leve void ImageSubresourceMap::ToArray(rdcarray &arr) { - arr.reserve(arr.size() + m_values.size()); + arr.reserve(arr.size() + size()); for(auto src = begin(); src != end(); ++src) { arr.push_back(*src); @@ -464,7 +466,7 @@ void ImageSubresourceMap::FromArray(const rdcarray m_values; + // commonly there will only be one value, in that case we inline it here. This is only valid if + // m_values is empty. + ImageSubresourceState m_value; + // The bit count of `m_aspectMask` uint16_t m_aspectCount = 0; @@ -1443,8 +1447,8 @@ public: for(auto it = ImageAspectFlagIter::begin(GetImageInfo().Aspects()); it != ImageAspectFlagIter::end(); ++it) ++m_aspectCount; - m_values.push_back( - ImageSubresourceState(VK_QUEUE_FAMILY_IGNORED, UNKNOWN_PREV_IMG_LAYOUT, refType)); + + m_value = ImageSubresourceState(VK_QUEUE_FAMILY_IGNORED, UNKNOWN_PREV_IMG_LAYOUT, refType); } void ToArray(rdcarray &arr); @@ -1456,11 +1460,15 @@ public: inline ImageSubresourceState &SubresourceIndexValue(uint32_t aspectIndex, uint32_t level, uint32_t layer, uint32_t slice) { + if(m_values.empty()) + return m_value; return m_values[SubresourceIndex(aspectIndex, level, layer, slice)]; } inline const ImageSubresourceState &SubresourceIndexValue(uint32_t aspectIndex, uint32_t level, uint32_t layer, uint32_t slice) const { + if(m_values.empty()) + return m_value; return m_values[SubresourceIndex(aspectIndex, level, layer, slice)]; } inline ImageSubresourceState &SubresourceAspectValue(VkImageAspectFlagBits aspect, uint32_t level, @@ -1493,12 +1501,6 @@ public: range.baseDepthSlice != 0u || range.sliceCount < GetImageInfo().extent.depth); } void Unsplit(); - inline void Clear() - { - m_values.clear(); - m_values.resize(1); - m_flags = 0; - } FrameRefType Merge(const ImageSubresourceMap &other, FrameRefCompFunc compose); template @@ -1588,7 +1590,7 @@ public: inline SubresourceRangeConstIter begin() const { return RangeBegin(GetImageInfo().FullRange()); } inline SubresourceRangeIter end() { return SubresourceRangeIter(); } inline SubresourceRangeConstIter end() const { return SubresourceRangeConstIter(); } - inline size_t size() const { return m_values.size(); } + inline size_t size() const { return RDCMAX(m_values.size(), (size_t)1); } }; template