mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 05:21:25 +12:00
rsx/util: Split address_range into a sized address_range template
This commit is contained in:
parent
4f7c82ba8a
commit
2ea7ff6b14
6 changed files with 108 additions and 86 deletions
|
@ -8,65 +8,73 @@
|
||||||
|
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
|
template <typename T>
|
||||||
class address_range_vector;
|
class address_range_vector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helpers
|
* Helpers
|
||||||
*/
|
*/
|
||||||
static inline u32 page_start(u32 addr)
|
template <typename T>
|
||||||
|
T page_start(T addr)
|
||||||
{
|
{
|
||||||
return addr & ~(get_page_size() - 1);
|
return addr & ~static_cast<T>(get_page_size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 next_page(u32 addr)
|
template <typename T>
|
||||||
|
static inline T next_page(T addr)
|
||||||
{
|
{
|
||||||
return page_start(addr) + get_page_size();
|
return page_start(addr) + static_cast<T>(get_page_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 page_end(u32 addr)
|
template <typename T>
|
||||||
|
static inline T page_end(T addr)
|
||||||
{
|
{
|
||||||
return next_page(addr) - 1;
|
return next_page(addr) - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u32 is_page_aligned(u32 val)
|
template <typename T>
|
||||||
|
static inline T is_page_aligned(T val)
|
||||||
{
|
{
|
||||||
return (val & (get_page_size() - 1)) == 0;
|
return (val & static_cast<T>(get_page_size() - 1)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address Range utility class
|
* Address Range utility class
|
||||||
*/
|
*/
|
||||||
class address_range32
|
template <typename T>
|
||||||
|
class address_range
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
u32 start = umax; // First address in range
|
T start = umax; // First address in range
|
||||||
u32 end = 0; // Last address
|
T end = 0; // Last address
|
||||||
|
|
||||||
|
using signed_type_t = std::make_signed<T>::type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Helper constexprs
|
// Helper constexprs
|
||||||
static constexpr inline bool range_overlaps(u32 start1, u32 end1, u32 start2, u32 end2)
|
static constexpr inline bool range_overlaps(T start1, T end1, T start2, T end2)
|
||||||
{
|
{
|
||||||
return (start1 <= end2 && start2 <= end1);
|
return (start1 <= end2 && start2 <= end1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr inline bool address_overlaps(u32 address, u32 start, u32 end)
|
static constexpr inline bool address_overlaps(T address, T start, T end)
|
||||||
{
|
{
|
||||||
return (start <= address && address <= end);
|
return (start <= address && address <= end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr inline bool range_inside_range(u32 start1, u32 end1, u32 start2, u32 end2)
|
static constexpr inline bool range_inside_range(T start1, T end1, T start2, T end2)
|
||||||
{
|
{
|
||||||
return (start1 >= start2 && end1 <= end2);
|
return (start1 >= start2 && end1 <= end2);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr address_range32(u32 _start, u32 _end) : start(_start), end(_end) {}
|
constexpr address_range(T _start, T _end) : start(_start), end(_end) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructors
|
// Constructors
|
||||||
constexpr address_range32() = default;
|
constexpr address_range() = default;
|
||||||
|
|
||||||
static constexpr address_range32 start_length(u32 _start, u32 _length)
|
static constexpr address_range start_length(T _start, T _length)
|
||||||
{
|
{
|
||||||
if (!_length)
|
if (!_length)
|
||||||
{
|
{
|
||||||
|
@ -76,57 +84,57 @@ namespace utils
|
||||||
return {_start, _start + (_length - 1)};
|
return {_start, _start + (_length - 1)};
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr address_range32 start_end(u32 _start, u32 _end)
|
static constexpr address_range start_end(T _start, T _end)
|
||||||
{
|
{
|
||||||
return {_start, _end};
|
return {_start, _end};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Length
|
// Length
|
||||||
u32 length() const
|
T length() const
|
||||||
{
|
{
|
||||||
AUDIT(valid());
|
AUDIT(valid());
|
||||||
return end - start + 1;
|
return end - start + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_length(const u32 new_length)
|
void set_length(const T new_length)
|
||||||
{
|
{
|
||||||
end = start + new_length - 1;
|
end = start + new_length - 1;
|
||||||
ensure(valid());
|
ensure(valid());
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 next_address() const
|
T next_address() const
|
||||||
{
|
{
|
||||||
return end + 1;
|
return end + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 prev_address() const
|
T prev_address() const
|
||||||
{
|
{
|
||||||
return start - 1;
|
return start - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overlapping checks
|
// Overlapping checks
|
||||||
bool overlaps(const address_range32 &other) const
|
bool overlaps(const address_range<T>& other) const
|
||||||
{
|
{
|
||||||
AUDIT(valid() && other.valid());
|
AUDIT(valid() && other.valid());
|
||||||
return range_overlaps(start, end, other.start, other.end);
|
return range_overlaps(start, end, other.start, other.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool overlaps(const u32 addr) const
|
bool overlaps(const T addr) const
|
||||||
{
|
{
|
||||||
AUDIT(valid());
|
AUDIT(valid());
|
||||||
return address_overlaps(addr, start, end);
|
return address_overlaps(addr, start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inside(const address_range32 &other) const
|
bool inside(const address_range<T>& other) const
|
||||||
{
|
{
|
||||||
AUDIT(valid() && other.valid());
|
AUDIT(valid() && other.valid());
|
||||||
return range_inside_range(start, end, other.start, other.end);
|
return range_inside_range(start, end, other.start, other.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool inside(const address_range_vector &vec) const;
|
inline bool inside(const address_range_vector<T>& vec) const;
|
||||||
inline bool overlaps(const address_range_vector &vec) const;
|
inline bool overlaps(const address_range_vector<T>& vec) const;
|
||||||
|
|
||||||
bool touches(const address_range32 &other) const
|
bool touches(const address_range<T>& other) const
|
||||||
{
|
{
|
||||||
AUDIT(valid() && other.valid());
|
AUDIT(valid() && other.valid());
|
||||||
// returns true if there is overlap, or if sections are side-by-side
|
// returns true if there is overlap, or if sections are side-by-side
|
||||||
|
@ -134,7 +142,7 @@ namespace utils
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
s32 signed_distance(const address_range32 &other) const
|
signed_type_t signed_distance(const address_range<T>& other) const
|
||||||
{
|
{
|
||||||
if (touches(other))
|
if (touches(other))
|
||||||
{
|
{
|
||||||
|
@ -144,15 +152,15 @@ namespace utils
|
||||||
// other after this
|
// other after this
|
||||||
if (other.start > end)
|
if (other.start > end)
|
||||||
{
|
{
|
||||||
return static_cast<s32>(other.start - end - 1);
|
return static_cast<signed_type_t>(other.start - end - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this after other
|
// this after other
|
||||||
AUDIT(start > other.end);
|
AUDIT(start > other.end);
|
||||||
return -static_cast<s32>(start - other.end - 1);
|
return -static_cast<signed_type_t>(start - other.end - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 distance(const address_range32 &other) const
|
T distance(const address_range<T>& other) const
|
||||||
{
|
{
|
||||||
if (touches(other))
|
if (touches(other))
|
||||||
{
|
{
|
||||||
|
@ -170,7 +178,7 @@ namespace utils
|
||||||
return (start - other.end - 1);
|
return (start - other.end - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
address_range32 get_min_max(const address_range32 &other) const
|
address_range<T> get_min_max(const address_range<T>& other) const
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
std::min(valid() ? start : umax, other.valid() ? other.start : umax),
|
std::min(valid() ? start : umax, other.valid() ? other.start : umax),
|
||||||
|
@ -178,7 +186,7 @@ namespace utils
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_min_max(const address_range32 &other)
|
void set_min_max(const address_range<T>& other)
|
||||||
{
|
{
|
||||||
*this = get_min_max(other);
|
*this = get_min_max(other);
|
||||||
}
|
}
|
||||||
|
@ -188,7 +196,7 @@ namespace utils
|
||||||
return (valid() && is_page_aligned(start) && is_page_aligned(length()));
|
return (valid() && is_page_aligned(start) && is_page_aligned(length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
address_range32 to_page_range() const
|
address_range<T> to_page_range() const
|
||||||
{
|
{
|
||||||
AUDIT(valid());
|
AUDIT(valid());
|
||||||
return { page_start(start), page_end(end) };
|
return { page_start(start), page_end(end) };
|
||||||
|
@ -202,7 +210,7 @@ namespace utils
|
||||||
AUDIT(is_page_range());
|
AUDIT(is_page_range());
|
||||||
}
|
}
|
||||||
|
|
||||||
address_range32 get_intersect(const address_range32 &clamp) const
|
address_range<T> get_intersect(const address_range<T>& clamp) const
|
||||||
{
|
{
|
||||||
if (!valid() || !clamp.valid())
|
if (!valid() || !clamp.valid())
|
||||||
{
|
{
|
||||||
|
@ -212,7 +220,7 @@ namespace utils
|
||||||
return { std::max(start, clamp.start), std::min(end, clamp.end) };
|
return { std::max(start, clamp.start), std::min(end, clamp.end) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void intersect(const address_range32 &clamp)
|
void intersect(const address_range<T>& clamp)
|
||||||
{
|
{
|
||||||
if (!clamp.valid())
|
if (!clamp.valid())
|
||||||
{
|
{
|
||||||
|
@ -238,7 +246,7 @@ namespace utils
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comparison Operators
|
// Comparison Operators
|
||||||
bool operator ==(const address_range32& other) const
|
bool operator ==(const address_range<T>& other) const
|
||||||
{
|
{
|
||||||
return (start == other.start && end == other.end);
|
return (start == other.start && end == other.end);
|
||||||
}
|
}
|
||||||
|
@ -252,21 +260,27 @@ namespace utils
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline address_range32 page_for(u32 addr)
|
using address_range16 = address_range<u16>;
|
||||||
|
using address_range32 = address_range<u32>;
|
||||||
|
using address_range64 = address_range<u64>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static inline address_range<T> page_for(T addr)
|
||||||
{
|
{
|
||||||
return address_range32::start_end(page_start(addr), page_end(addr));
|
return address_range<T>::start_end(page_start(addr), page_end(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address Range Vector utility class
|
* Address Range Vector utility class
|
||||||
*
|
*
|
||||||
* Collection of address_range32 objects. Allows for merging and removing ranges from the set.
|
* Collection of address_range<T> objects. Allows for merging and removing ranges from the set.
|
||||||
*/
|
*/
|
||||||
|
template <typename T>
|
||||||
class address_range_vector
|
class address_range_vector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using vector_type = std::vector<address_range32>;
|
using vector_type = std::vector<address_range<T>>;
|
||||||
using iterator = vector_type::iterator;
|
using iterator = vector_type::iterator;
|
||||||
using const_iterator = vector_type::const_iterator;
|
using const_iterator = vector_type::const_iterator;
|
||||||
using size_type = vector_type::size_type;
|
using size_type = vector_type::size_type;
|
||||||
|
@ -280,8 +294,8 @@ namespace utils
|
||||||
inline void clear() { data.clear(); }
|
inline void clear() { data.clear(); }
|
||||||
inline size_type size() const { return data.size(); }
|
inline size_type size() const { return data.size(); }
|
||||||
inline bool empty() const { return data.empty(); }
|
inline bool empty() const { return data.empty(); }
|
||||||
inline address_range32& operator[](size_type n) { return data[n]; }
|
inline address_range<T>& operator[](size_type n) { return data[n]; }
|
||||||
inline const address_range32& operator[](size_type n) const { return data[n]; }
|
inline const address_range<T>& operator[](size_type n) const { return data[n]; }
|
||||||
inline iterator begin() { return data.begin(); }
|
inline iterator begin() { return data.begin(); }
|
||||||
inline const_iterator begin() const { return data.begin(); }
|
inline const_iterator begin() const { return data.begin(); }
|
||||||
inline iterator end() { return data.end(); }
|
inline iterator end() { return data.end(); }
|
||||||
|
@ -289,7 +303,7 @@ namespace utils
|
||||||
|
|
||||||
// Search for ranges that touch new_range. If found, merge instead of adding new_range.
|
// Search for ranges that touch new_range. If found, merge instead of adding new_range.
|
||||||
// When adding a new range, re-use invalid ranges whenever possible
|
// When adding a new range, re-use invalid ranges whenever possible
|
||||||
void merge(const address_range32 &new_range)
|
void merge(const address_range<T>& new_range)
|
||||||
{
|
{
|
||||||
// Note the case where we have
|
// Note the case where we have
|
||||||
// AAAA BBBB
|
// AAAA BBBB
|
||||||
|
@ -301,8 +315,8 @@ namespace utils
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
address_range32 *found = nullptr;
|
address_range<T> *found = nullptr;
|
||||||
address_range32 *invalid = nullptr;
|
address_range<T> *invalid = nullptr;
|
||||||
|
|
||||||
for (auto &existing : data)
|
for (auto &existing : data)
|
||||||
{
|
{
|
||||||
|
@ -347,22 +361,22 @@ namespace utils
|
||||||
AUDIT(check_consistency());
|
AUDIT(check_consistency());
|
||||||
}
|
}
|
||||||
|
|
||||||
void merge(const address_range_vector &other)
|
void merge(const address_range_vector<T>& other)
|
||||||
{
|
{
|
||||||
for (const address_range32 &new_range : other)
|
for (const address_range<T>& new_range : other)
|
||||||
{
|
{
|
||||||
merge(new_range);
|
merge(new_range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exclude a given range from data
|
// Exclude a given range from data
|
||||||
void exclude(const address_range32 &exclusion)
|
void exclude(const address_range<T>& exclusion)
|
||||||
{
|
{
|
||||||
// Note the case where we have
|
// Note the case where we have
|
||||||
// AAAAAAA
|
// AAAAAAA
|
||||||
// EEE
|
// EEE
|
||||||
// where data={A} and exclusion=E.
|
// where data={A} and exclusion=E.
|
||||||
// In this case, we need to reduce A to the head (before E starts), and then create a new address_range32 B for the tail (after E ends), i.e.
|
// In this case, we need to reduce A to the head (before E starts), and then create a new address_range<T> B for the tail (after E ends), i.e.
|
||||||
// AA BB
|
// AA BB
|
||||||
// EEE
|
// EEE
|
||||||
|
|
||||||
|
@ -371,13 +385,13 @@ namespace utils
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
address_range32 *invalid = nullptr; // try to re-use an invalid range instead of calling push_back
|
address_range<T> *invalid = nullptr; // try to re-use an invalid range instead of calling push_back
|
||||||
|
|
||||||
// We use index access because we might have to push_back within the loop, which could invalidate the iterators
|
// We use index access because we might have to push_back within the loop, which could invalidate the iterators
|
||||||
size_type _size = data.size();
|
size_type _size = data.size();
|
||||||
for (size_type n = 0; n < _size; ++n)
|
for (size_type n = 0; n < _size; ++n)
|
||||||
{
|
{
|
||||||
address_range32 &existing = data[n];
|
address_range<T>& existing = data[n];
|
||||||
|
|
||||||
if (!existing.valid())
|
if (!existing.valid())
|
||||||
{
|
{
|
||||||
|
@ -430,7 +444,7 @@ namespace utils
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// IMPORTANT: adding to data invalidates "existing". This must be done last!
|
// IMPORTANT: adding to data invalidates "existing". This must be done last!
|
||||||
data.push_back(address_range32::start_end(exclusion.next_address(), tail_end));
|
data.push_back(address_range<T>::start_end(exclusion.next_address(), tail_end));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -438,9 +452,9 @@ namespace utils
|
||||||
AUDIT(!overlaps(exclusion));
|
AUDIT(!overlaps(exclusion));
|
||||||
}
|
}
|
||||||
|
|
||||||
void exclude(const address_range_vector &other)
|
void exclude(const address_range_vector<T>& other)
|
||||||
{
|
{
|
||||||
for (const address_range32 &exclusion : other)
|
for (const address_range<T>& exclusion : other)
|
||||||
{
|
{
|
||||||
exclude(exclusion);
|
exclude(exclusion);
|
||||||
}
|
}
|
||||||
|
@ -478,25 +492,25 @@ namespace utils
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for overlap with a given range
|
// Test for overlap with a given range
|
||||||
bool overlaps(const address_range32 &range) const
|
bool overlaps(const address_range<T>& range) const
|
||||||
{
|
{
|
||||||
return std::any_of(data.cbegin(), data.cend(), [&range](const address_range32& cur)
|
return std::any_of(data.cbegin(), data.cend(), [&range](const address_range<T>& cur)
|
||||||
{
|
{
|
||||||
return cur.valid() && cur.overlaps(range);
|
return cur.valid() && cur.overlaps(range);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test for overlap with a given address_range32 vector
|
// Test for overlap with a given address_range<T> vector
|
||||||
bool overlaps(const address_range_vector &other) const
|
bool overlaps(const address_range_vector<T>& other) const
|
||||||
{
|
{
|
||||||
for (const address_range32 &rng1 : data)
|
for (const address_range<T>& rng1 : data)
|
||||||
{
|
{
|
||||||
if (!rng1.valid())
|
if (!rng1.valid())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const address_range32 &rng2 : other.data)
|
for (const address_range<T>& rng2 : other.data)
|
||||||
{
|
{
|
||||||
if (!rng2.valid())
|
if (!rng2.valid())
|
||||||
{
|
{
|
||||||
|
@ -513,18 +527,18 @@ namespace utils
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if a given range is fully contained inside this vector
|
// Test if a given range is fully contained inside this vector
|
||||||
bool contains(const address_range32 &range) const
|
bool contains(const address_range<T>& range) const
|
||||||
{
|
{
|
||||||
return std::any_of(this->begin(), this->end(), [&range](const address_range32& cur)
|
return std::any_of(this->begin(), this->end(), [&range](const address_range<T>& cur)
|
||||||
{
|
{
|
||||||
return cur.valid() && cur.inside(range);
|
return cur.valid() && cur.inside(range);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test if all ranges in this vector are full contained inside a specific range
|
// Test if all ranges in this vector are full contained inside a specific range
|
||||||
bool inside(const address_range32 &range) const
|
bool inside(const address_range<T>& range) const
|
||||||
{
|
{
|
||||||
return std::all_of(this->begin(), this->end(), [&range](const address_range32& cur)
|
return std::all_of(this->begin(), this->end(), [&range](const address_range<T>& cur)
|
||||||
{
|
{
|
||||||
return !cur.valid() || cur.inside(range);
|
return !cur.valid() || cur.inside(range);
|
||||||
});
|
});
|
||||||
|
@ -547,16 +561,22 @@ namespace utils
|
||||||
|
|
||||||
|
|
||||||
// These declarations must be done after address_range_vector has been defined
|
// These declarations must be done after address_range_vector has been defined
|
||||||
bool address_range32::inside(const address_range_vector &vec) const
|
template <typename T>
|
||||||
|
bool address_range<T>::inside(const address_range_vector<T>& vec) const
|
||||||
{
|
{
|
||||||
return vec.contains(*this);
|
return vec.contains(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool address_range32::overlaps(const address_range_vector &vec) const
|
template <typename T>
|
||||||
|
bool address_range<T>::overlaps(const address_range_vector<T>& vec) const
|
||||||
{
|
{
|
||||||
return vec.overlaps(*this);
|
return vec.overlaps(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using address_range_vector16 = address_range_vector<u16>;
|
||||||
|
using address_range_vector32 = address_range_vector<u32>;
|
||||||
|
using address_range_vector64 = address_range_vector<u64>;
|
||||||
|
|
||||||
} // namespace utils
|
} // namespace utils
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,9 @@ void ppubreak(ppu_thread& ppu);
|
||||||
namespace utils
|
namespace utils
|
||||||
{
|
{
|
||||||
class shm;
|
class shm;
|
||||||
class address_range32;
|
|
||||||
|
template <typename T> class address_range;
|
||||||
|
using address_range32 = address_range<u32>;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace vm
|
namespace vm
|
||||||
|
|
|
@ -685,7 +685,7 @@ namespace rsx
|
||||||
|
|
||||||
|
|
||||||
// Merges the protected ranges of the sections in "sections" into "result"
|
// Merges the protected ranges of the sections in "sections" into "result"
|
||||||
void merge_protected_ranges(address_range_vector &result, const std::vector<section_storage_type*> §ions)
|
void merge_protected_ranges(address_range_vector32 &result, const std::vector<section_storage_type*> §ions)
|
||||||
{
|
{
|
||||||
result.reserve(result.size() + sections.size());
|
result.reserve(result.size() + sections.size());
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ namespace rsx
|
||||||
// Otherwise the page protections will end up incorrect and things will break!
|
// Otherwise the page protections will end up incorrect and things will break!
|
||||||
void unprotect_set(thrashed_set& data)
|
void unprotect_set(thrashed_set& data)
|
||||||
{
|
{
|
||||||
auto protect_ranges = [](address_range_vector& _set, utils::protection _prot)
|
auto protect_ranges = [](address_range_vector32& _set, utils::protection _prot)
|
||||||
{
|
{
|
||||||
//u32 count = 0;
|
//u32 count = 0;
|
||||||
for (auto &range : _set)
|
for (auto &range : _set)
|
||||||
|
@ -734,8 +734,8 @@ namespace rsx
|
||||||
AUDIT(data.is_flushed());
|
AUDIT(data.is_flushed());
|
||||||
|
|
||||||
// Merge ranges to unprotect
|
// Merge ranges to unprotect
|
||||||
address_range_vector ranges_to_unprotect;
|
address_range_vector32 ranges_to_unprotect;
|
||||||
address_range_vector ranges_to_protect_ro;
|
address_range_vector32 ranges_to_protect_ro;
|
||||||
ranges_to_unprotect.reserve(data.sections_to_unprotect.size() + data.sections_to_flush.size() + data.sections_to_exclude.size());
|
ranges_to_unprotect.reserve(data.sections_to_unprotect.size() + data.sections_to_flush.size() + data.sections_to_exclude.size());
|
||||||
|
|
||||||
merge_protected_ranges(ranges_to_unprotect, data.sections_to_unprotect);
|
merge_protected_ranges(ranges_to_unprotect, data.sections_to_unprotect);
|
||||||
|
|
|
@ -928,7 +928,7 @@ namespace rsx
|
||||||
return get_bounds(bounds).overlaps(other);
|
return get_bounds(bounds).overlaps(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool overlaps(const address_range_vector& other, section_bounds bounds) const
|
inline bool overlaps(const address_range_vector32& other, section_bounds bounds) const
|
||||||
{
|
{
|
||||||
return get_bounds(bounds).overlaps(other);
|
return get_bounds(bounds).overlaps(other);
|
||||||
}
|
}
|
||||||
|
@ -943,7 +943,7 @@ namespace rsx
|
||||||
return get_bounds(bounds).inside(other);
|
return get_bounds(bounds).inside(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool inside(const address_range_vector& other, section_bounds bounds) const
|
inline bool inside(const address_range_vector32& other, section_bounds bounds) const
|
||||||
{
|
{
|
||||||
return get_bounds(bounds).inside(other);
|
return get_bounds(bounds).inside(other);
|
||||||
}
|
}
|
||||||
|
@ -1088,7 +1088,7 @@ namespace rsx
|
||||||
rsx::texture_upload_context context = rsx::texture_upload_context::shader_read;
|
rsx::texture_upload_context context = rsx::texture_upload_context::shader_read;
|
||||||
rsx::texture_dimension_extended image_type = rsx::texture_dimension_extended::texture_dimension_2d;
|
rsx::texture_dimension_extended image_type = rsx::texture_dimension_extended::texture_dimension_2d;
|
||||||
|
|
||||||
address_range_vector flush_exclusions; // Address ranges that will be skipped during flush
|
address_range_vector32 flush_exclusions; // Address ranges that will be skipped during flush
|
||||||
|
|
||||||
predictor_type *m_predictor = nullptr;
|
predictor_type *m_predictor = nullptr;
|
||||||
usz m_predictor_key_hash = 0;
|
usz m_predictor_key_hash = 0;
|
||||||
|
@ -1553,7 +1553,7 @@ namespace rsx
|
||||||
|
|
||||||
// Otherwise, we need to filter the memcpy with our flush exclusions
|
// Otherwise, we need to filter the memcpy with our flush exclusions
|
||||||
// Should be relatively rare
|
// Should be relatively rare
|
||||||
address_range_vector vec;
|
address_range_vector32 vec;
|
||||||
vec.merge(copy_range);
|
vec.merge(copy_range);
|
||||||
vec.exclude(flush_exclusions);
|
vec.exclude(flush_exclusions);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
// Import address_range32 utilities
|
// Import address_range32 utilities
|
||||||
using utils::address_range32;
|
using utils::address_range32;
|
||||||
using utils::address_range_vector;
|
using utils::address_range_vector32;
|
||||||
using utils::page_for;
|
using utils::page_for;
|
||||||
using utils::page_start;
|
using utils::page_start;
|
||||||
using utils::page_end;
|
using utils::page_end;
|
||||||
|
|
|
@ -302,10 +302,10 @@ namespace utils
|
||||||
EXPECT_NE(str.find("1fff"), std::string::npos);
|
EXPECT_NE(str.find("1fff"), std::string::npos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests for address_range_vector
|
// Tests for address_range_vector32
|
||||||
TEST(AddressRangeVector, BasicOperations)
|
TEST(AddressRangeVector, BasicOperations)
|
||||||
{
|
{
|
||||||
address_range_vector vec;
|
address_range_vector32 vec;
|
||||||
EXPECT_TRUE(vec.empty());
|
EXPECT_TRUE(vec.empty());
|
||||||
EXPECT_EQ(vec.size(), 0);
|
EXPECT_EQ(vec.size(), 0);
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ namespace utils
|
||||||
|
|
||||||
TEST(AddressRangeVector, MergeOperations)
|
TEST(AddressRangeVector, MergeOperations)
|
||||||
{
|
{
|
||||||
address_range_vector vec;
|
address_range_vector32 vec;
|
||||||
|
|
||||||
// Add non-touching ranges
|
// Add non-touching ranges
|
||||||
vec.merge(address_range32::start_length(0x1000, 0x1000)); // 0x1000-0x1FFF
|
vec.merge(address_range32::start_length(0x1000, 0x1000)); // 0x1000-0x1FFF
|
||||||
|
@ -347,7 +347,7 @@ namespace utils
|
||||||
|
|
||||||
TEST(AddressRangeVector, ExcludeOperations)
|
TEST(AddressRangeVector, ExcludeOperations)
|
||||||
{
|
{
|
||||||
address_range_vector vec;
|
address_range_vector32 vec;
|
||||||
vec.merge(address_range32::start_length(0x1000, 0x4000)); // 0x1000-0x4FFF
|
vec.merge(address_range32::start_length(0x1000, 0x4000)); // 0x1000-0x4FFF
|
||||||
|
|
||||||
// Exclude from the middle
|
// Exclude from the middle
|
||||||
|
@ -378,7 +378,7 @@ namespace utils
|
||||||
// Test excluding with another vector
|
// Test excluding with another vector
|
||||||
vec.merge(address_range32::start_length(0x1000, 0x4000)); // 0x1000-0x4FFF
|
vec.merge(address_range32::start_length(0x1000, 0x4000)); // 0x1000-0x4FFF
|
||||||
|
|
||||||
address_range_vector vec2;
|
address_range_vector32 vec2;
|
||||||
vec2.merge(address_range32::start_length(0x2000, 0x1000)); // 0x2000-0x2FFF
|
vec2.merge(address_range32::start_length(0x2000, 0x1000)); // 0x2000-0x2FFF
|
||||||
vec2.merge(address_range32::start_length(0x4000, 0x1000)); // 0x4000-0x4FFF
|
vec2.merge(address_range32::start_length(0x4000, 0x1000)); // 0x4000-0x4FFF
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ namespace utils
|
||||||
|
|
||||||
TEST(AddressRangeVector, ConsistencyCheck)
|
TEST(AddressRangeVector, ConsistencyCheck)
|
||||||
{
|
{
|
||||||
address_range_vector vec;
|
address_range_vector32 vec;
|
||||||
vec.merge(address_range32::start_length(0x1000, 0x1000)); // 0x1000-0x1FFF
|
vec.merge(address_range32::start_length(0x1000, 0x1000)); // 0x1000-0x1FFF
|
||||||
vec.merge(address_range32::start_length(0x3000, 0x1000)); // 0x3000-0x3FFF
|
vec.merge(address_range32::start_length(0x3000, 0x1000)); // 0x3000-0x3FFF
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ namespace utils
|
||||||
|
|
||||||
TEST(AddressRangeVector, OverlapsAndContains)
|
TEST(AddressRangeVector, OverlapsAndContains)
|
||||||
{
|
{
|
||||||
address_range_vector vec;
|
address_range_vector32 vec;
|
||||||
vec.merge(address_range32::start_length(0x1000, 0x1000)); // 0x1000-0x1FFF
|
vec.merge(address_range32::start_length(0x1000, 0x1000)); // 0x1000-0x1FFF
|
||||||
vec.merge(address_range32::start_length(0x3000, 0x1000)); // 0x3000-0x3FFF
|
vec.merge(address_range32::start_length(0x3000, 0x1000)); // 0x3000-0x3FFF
|
||||||
|
|
||||||
|
@ -420,11 +420,11 @@ namespace utils
|
||||||
EXPECT_FALSE(vec.contains(address_range32::start_length(0x1500, 0x1000))); // 0x1500-0x24FF
|
EXPECT_FALSE(vec.contains(address_range32::start_length(0x1500, 0x1000))); // 0x1500-0x24FF
|
||||||
|
|
||||||
// Test overlaps with another vector
|
// Test overlaps with another vector
|
||||||
address_range_vector vec2;
|
address_range_vector32 vec2;
|
||||||
vec2.merge(address_range32::start_length(0x1500, 0x1000)); // 0x1500-0x24FF
|
vec2.merge(address_range32::start_length(0x1500, 0x1000)); // 0x1500-0x24FF
|
||||||
EXPECT_TRUE(vec.overlaps(vec2));
|
EXPECT_TRUE(vec.overlaps(vec2));
|
||||||
|
|
||||||
address_range_vector vec3;
|
address_range_vector32 vec3;
|
||||||
vec3.merge(address_range32::start_length(0x2000, 0x1000)); // 0x2000-0x2FFF
|
vec3.merge(address_range32::start_length(0x2000, 0x1000)); // 0x2000-0x2FFF
|
||||||
EXPECT_FALSE(vec.overlaps(vec3));
|
EXPECT_FALSE(vec.overlaps(vec3));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue