mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Vulkan BDA debugging force m_BufferAddresses to be sorted
The implementation usage of m_BufferAddresses assumes the container is sorted and requires the use of lower_bound() API Added rdcsortedflatmap subclass of rdcflatmap Only expose upper_bound(), lower_bound() APIs in rdcsortedflatmap The upper/lower bound APIs require a sorted container
This commit is contained in:
@@ -1,3 +1,27 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019-2024 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
@@ -126,35 +150,6 @@ struct rdcflatmap
|
||||
return {(begin() + idx), inserted};
|
||||
}
|
||||
|
||||
iterator upper_bound(const Key &key)
|
||||
{
|
||||
if(!sorted)
|
||||
sort();
|
||||
|
||||
size_t idx = lower_bound_idx(key);
|
||||
|
||||
// almost the same behaviour as lower_bound, except if we actually have the key, return the next
|
||||
// element.
|
||||
if(idx < size() && storage.at(idx).first == key)
|
||||
return begin() + idx + 1;
|
||||
|
||||
return begin() + idx;
|
||||
}
|
||||
|
||||
const_iterator upper_bound(const Key &key) const
|
||||
{
|
||||
size_t idx = lower_bound_idx(key);
|
||||
|
||||
// almost the same behaviour as lower_bound, except if we actually have the key, return the next
|
||||
// element.
|
||||
if(idx < size() && storage.at(idx).first == key)
|
||||
return begin() + idx + 1;
|
||||
|
||||
return begin() + idx;
|
||||
}
|
||||
|
||||
iterator lower_bound(const Key &key) { return begin() + lower_bound_idx(key); }
|
||||
const_iterator lower_bound(const Key &key) const { return begin() + lower_bound_idx(key); }
|
||||
iterator begin() { return storage.begin(); }
|
||||
iterator end() { return storage.end(); }
|
||||
const_iterator begin() const { return storage.begin(); }
|
||||
@@ -167,8 +162,33 @@ struct rdcflatmap
|
||||
storage.swap(other.storage);
|
||||
}
|
||||
void clear() { storage.clear(); }
|
||||
private:
|
||||
protected:
|
||||
rdcarray<rdcpair<Key, Value>> storage;
|
||||
|
||||
size_t lower_bound_idx(const Key &id) const
|
||||
{
|
||||
// start looking at the whole range
|
||||
size_t start = 0, sz = size();
|
||||
// continue iterating until the range is empty
|
||||
while(sz > 0)
|
||||
{
|
||||
const size_t halfsz = sz / 2;
|
||||
const size_t mid = start + halfsz;
|
||||
const Key comp = storage.at(mid).first;
|
||||
if(comp < id)
|
||||
{
|
||||
start = mid + 1;
|
||||
sz -= halfsz + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sz = halfsz;
|
||||
}
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
private:
|
||||
bool sorted = (SortThreshold == 0);
|
||||
|
||||
void sort()
|
||||
@@ -216,29 +236,6 @@ private:
|
||||
return (begin() + idx)->second;
|
||||
}
|
||||
|
||||
size_t lower_bound_idx(const Key &id) const
|
||||
{
|
||||
// start looking at the whole range
|
||||
size_t start = 0, sz = size();
|
||||
// continue iterating until the range is empty
|
||||
while(sz > 0)
|
||||
{
|
||||
const size_t halfsz = sz / 2;
|
||||
const size_t mid = start + halfsz;
|
||||
const Key comp = storage.at(mid).first;
|
||||
if(comp < id)
|
||||
{
|
||||
start = mid + 1;
|
||||
sz -= halfsz + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sz = halfsz;
|
||||
}
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
iterator unsorted_find(const Key &id)
|
||||
{
|
||||
for(auto it = begin(); it != end(); ++it)
|
||||
@@ -277,3 +274,44 @@ private:
|
||||
return storage.back().second;
|
||||
}
|
||||
};
|
||||
|
||||
// a version of rdcflatmap which is guaranteed to be sorted
|
||||
// adds upper_bound and lower_bound APIs
|
||||
template <typename Key, typename Value>
|
||||
struct rdcsortedflatmap : rdcflatmap<Key, Value, 0>
|
||||
{
|
||||
using iterator = rdcpair<Key, Value> *;
|
||||
using const_iterator = const rdcpair<Key, Value> *;
|
||||
|
||||
using rdcflatmap<Key, Value, 0>::begin;
|
||||
using rdcflatmap<Key, Value, 0>::size;
|
||||
using rdcflatmap<Key, Value, 0>::storage;
|
||||
using rdcflatmap<Key, Value, 0>::lower_bound_idx;
|
||||
|
||||
iterator upper_bound(const Key &key)
|
||||
{
|
||||
size_t idx = lower_bound_idx(key);
|
||||
|
||||
// almost the same behaviour as lower_bound, except if we actually have the key, return the next
|
||||
// element.
|
||||
if(idx < size() && storage.at(idx).first == key)
|
||||
return begin() + idx + 1;
|
||||
|
||||
return begin() + idx;
|
||||
}
|
||||
|
||||
const_iterator upper_bound(const Key &key) const
|
||||
{
|
||||
size_t idx = lower_bound_idx(key);
|
||||
|
||||
// almost the same behaviour as lower_bound, except if we actually have the key, return the next
|
||||
// element.
|
||||
if(idx < size() && storage.at(idx).first == key)
|
||||
return begin() + idx + 1;
|
||||
|
||||
return begin() + idx;
|
||||
}
|
||||
|
||||
iterator lower_bound(const Key &key) { return begin() + lower_bound_idx(key); }
|
||||
const_iterator lower_bound(const Key &key) const { return begin() + lower_bound_idx(key); }
|
||||
};
|
||||
|
||||
@@ -162,7 +162,7 @@ template <typename T>
|
||||
struct Intervals
|
||||
{
|
||||
public:
|
||||
using MapType = rdcflatmap<uint64_t, T, 0>;
|
||||
using MapType = rdcsortedflatmap<uint64_t, T>;
|
||||
|
||||
typedef IntervalRef<T, MapType, typename MapType::iterator> interval;
|
||||
typedef IntervalsIter<T, MapType, typename MapType::iterator, interval> iterator;
|
||||
|
||||
@@ -626,7 +626,7 @@ struct VulkanCreationInfo
|
||||
VkMemoryRequirements mrq;
|
||||
};
|
||||
std::unordered_map<ResourceId, Buffer> m_Buffer;
|
||||
rdcflatmap<uint64_t, ResourceId> m_BufferAddresses;
|
||||
rdcsortedflatmap<uint64_t, ResourceId> m_BufferAddresses;
|
||||
|
||||
struct BufferView
|
||||
{
|
||||
|
||||
@@ -2243,10 +2243,23 @@ TEST_CASE("Test flatmap type", "[basictypes][flatmap]")
|
||||
CHECK(test.find(5)->second == "foo");
|
||||
};
|
||||
|
||||
SECTION("empty_map")
|
||||
{
|
||||
rdcflatmap<uint32_t, uint32_t> unsorted;
|
||||
CHECK(unsorted.begin() == unsorted.end());
|
||||
CHECK(unsorted.find(0) == unsorted.end());
|
||||
|
||||
rdcflatmap<uint32_t, uint32_t, 0> sorted;
|
||||
CHECK(sorted.begin() == sorted.end());
|
||||
CHECK(sorted.find(0) == sorted.end());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test sorted flatmap type", "[basictypes][sortedflatmap]")
|
||||
{
|
||||
SECTION("upper_bound")
|
||||
{
|
||||
// set SortThreshold to 0 to force sorted semantics always
|
||||
rdcflatmap<uint32_t, rdcstr, 0> test;
|
||||
rdcsortedflatmap<uint32_t, rdcstr> test;
|
||||
|
||||
test[5] = "foo";
|
||||
test[7] = "bar";
|
||||
@@ -2292,17 +2305,9 @@ TEST_CASE("Test flatmap type", "[basictypes][flatmap]")
|
||||
|
||||
SECTION("empty_map")
|
||||
{
|
||||
rdcflatmap<uint32_t, uint32_t> unsorted;
|
||||
CHECK(unsorted.begin() == unsorted.end());
|
||||
CHECK(unsorted.find(0) == unsorted.end());
|
||||
CHECK(unsorted.lower_bound(1) == 0);
|
||||
CHECK(unsorted.upper_bound(2) == 0);
|
||||
|
||||
rdcflatmap<uint32_t, uint32_t, 0> sorted;
|
||||
CHECK(sorted.begin() == sorted.end());
|
||||
CHECK(sorted.find(0) == sorted.end());
|
||||
CHECK(sorted.lower_bound(1) == 0);
|
||||
CHECK(sorted.upper_bound(2) == 0);
|
||||
rdcsortedflatmap<uint32_t, uint32_t> sortedflatmap;
|
||||
CHECK(sortedflatmap.lower_bound(1) == 0);
|
||||
CHECK(sortedflatmap.upper_bound(2) == 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user