mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
renderer: avoid allocating for dirty range probes
This commit is contained in:
@@ -59,6 +59,15 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Intersects(uint64_t address, uint64_t size) const {
|
||||
const auto end = End(address, size);
|
||||
auto it = m_ranges.lower_bound(address);
|
||||
if (it != m_ranges.begin() && std::prev(it)->second > address) {
|
||||
return true;
|
||||
}
|
||||
return it != m_ranges.end() && it->first < end;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Contains(uint64_t address, uint64_t size) const {
|
||||
const auto end = End(address, size);
|
||||
auto it = m_ranges.upper_bound(address);
|
||||
|
||||
+6
-9
@@ -167,7 +167,7 @@ void BufferCache::QueueGarbageDownload(std::span<const DownloadCopy> copies, Buf
|
||||
// query therefore cannot orphan a dirty sibling on an edge page.
|
||||
m_memory_tracker.UnmarkRegionAsGpuModified(address, size);
|
||||
if (m_memory_tracker.IsRegionGpuModified(address, size) ||
|
||||
!m_gpu_modified_ranges.Intersections(address, size).empty()) {
|
||||
m_gpu_modified_ranges.Intersects(address, size)) {
|
||||
EXIT("BufferCache: asynchronous garbage collection retained GPU ownership\n");
|
||||
}
|
||||
m_memory_tracker.UntrackMemory(address, size);
|
||||
@@ -314,8 +314,7 @@ void BufferCache::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
||||
!m_memory_tracker.IsRegionGpuModified(begin, buffer.Size())) {
|
||||
continue;
|
||||
}
|
||||
const auto dirty = m_gpu_modified_ranges.Intersections(begin, buffer.Size());
|
||||
if (dirty.empty()) {
|
||||
if (!m_gpu_modified_ranges.Intersects(begin, buffer.Size())) {
|
||||
EXIT("BufferCache: GPU-modified buffer has no dirty ranges\n");
|
||||
}
|
||||
modified_buffers.emplace_back(begin, buffer.Size());
|
||||
@@ -350,7 +349,7 @@ void BufferCache::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
||||
for (const auto& [begin, bytes]: retired_buffers) {
|
||||
m_memory_tracker.MarkRegionAsCpuModified(begin, bytes);
|
||||
}
|
||||
if (!m_gpu_modified_ranges.Intersections(vaddr, size).empty()) {
|
||||
if (m_gpu_modified_ranges.Intersects(vaddr, size)) {
|
||||
EXIT("BufferCache: unmap retained dirty byte ranges\n");
|
||||
}
|
||||
m_memory_tracker.UntrackMemory(vaddr, size);
|
||||
@@ -557,8 +556,7 @@ std::pair<Buffer*, uint64_t> BufferCache::ObtainBufferForImage(uint64_t vaddr, u
|
||||
{
|
||||
const bool cpu_modified = m_memory_tracker.IsRegionCpuModified(vaddr, size);
|
||||
const bool gpu_modified = m_memory_tracker.IsRegionGpuModified(vaddr, size);
|
||||
const auto dirty = m_gpu_modified_ranges.Intersections(vaddr, size);
|
||||
const bool has_dirty_buffer_source = !dirty.empty();
|
||||
const bool has_dirty_buffer_source = m_gpu_modified_ranges.Intersects(vaddr, size);
|
||||
m_memory_tracker.ValidateGpuDirtyOwnership(m_gpu_modified_ranges, vaddr, size,
|
||||
"image source");
|
||||
|
||||
@@ -592,8 +590,7 @@ std::pair<Buffer*, uint64_t> BufferCache::ObtainBufferForImage(uint64_t vaddr, u
|
||||
}
|
||||
m_staging_buffer.Commit();
|
||||
|
||||
const auto dirty = m_gpu_modified_ranges.Intersections(vaddr, size);
|
||||
const bool has_dirty_buffer_source = !dirty.empty();
|
||||
const bool has_dirty_buffer_source = m_gpu_modified_ranges.Intersects(vaddr, size);
|
||||
auto* owner = find_owner();
|
||||
if (has_dirty_buffer_source && owner == nullptr) {
|
||||
EXIT("BufferCache: GPU-dirty image source lost its native owner\n");
|
||||
@@ -756,7 +753,7 @@ bool BufferCache::IsRegionGpuModified(uint64_t vaddr, uint64_t size) {
|
||||
}
|
||||
|
||||
bool BufferCache::HasGpuDirtyBytes(uint64_t vaddr, uint64_t size) {
|
||||
return !m_gpu_modified_ranges.Intersections(vaddr, size).empty();
|
||||
return m_gpu_modified_ranges.Intersects(vaddr, size);
|
||||
}
|
||||
|
||||
bool BufferCache::IsRegionCpuModified(uint64_t vaddr, uint64_t size) {
|
||||
|
||||
@@ -191,6 +191,10 @@ void TestRangeSet() {
|
||||
ranges.Add(0x1200, 0x40);
|
||||
Check(ranges.Contains(0x1010, 0xe0) && !ranges.Contains(0x1010, 0x200),
|
||||
"range set containment did not require full coverage");
|
||||
Check(ranges.Intersects(0x0fff, 2) && ranges.Intersects(0x11ff, 2) &&
|
||||
!ranges.Intersects(0x1100, 0x100) &&
|
||||
!ranges.Intersects(0x1240, 1),
|
||||
"range set intersection did not preserve half-open boundaries");
|
||||
auto intersections = ranges.Intersections(0x1070, 0x1b0);
|
||||
Check(intersections.size() == 2 && intersections[0].address == 0x1070 &&
|
||||
intersections[0].size == 0x90 &&
|
||||
|
||||
Reference in New Issue
Block a user