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.
This commit is contained in:
baldurk
2020-08-19 14:24:51 +01:00
parent 8a350f28c8
commit babbdadc36
2 changed files with 18 additions and 14 deletions
+7 -5
View File
@@ -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<ImageSubresourceStateForRange> &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<ImageSubresourceStateForRange
return;
}
Split(arr.front().range);
if(m_values.size() != arr.size())
if(size() != arr.size())
{
RDCERR("Incorrect number of values for ImageSubresourceMap");
return;
+11 -9
View File
@@ -1397,6 +1397,10 @@ class ImageSubresourceMap
// `m_values` and the `*Split` flags in `m_flags`.
rdcarray<ImageSubresourceState> 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<ImageSubresourceStateForRange> &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 <typename Map, typename Pair>
@@ -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 <typename Barrier>