mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
renderer: avoid allocating for dirty range probes
This commit is contained in:
@@ -59,6 +59,15 @@ public:
|
|||||||
return result;
|
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 {
|
[[nodiscard]] bool Contains(uint64_t address, uint64_t size) const {
|
||||||
const auto end = End(address, size);
|
const auto end = End(address, size);
|
||||||
auto it = m_ranges.upper_bound(address);
|
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.
|
// query therefore cannot orphan a dirty sibling on an edge page.
|
||||||
m_memory_tracker.UnmarkRegionAsGpuModified(address, size);
|
m_memory_tracker.UnmarkRegionAsGpuModified(address, size);
|
||||||
if (m_memory_tracker.IsRegionGpuModified(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");
|
EXIT("BufferCache: asynchronous garbage collection retained GPU ownership\n");
|
||||||
}
|
}
|
||||||
m_memory_tracker.UntrackMemory(address, size);
|
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())) {
|
!m_memory_tracker.IsRegionGpuModified(begin, buffer.Size())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto dirty = m_gpu_modified_ranges.Intersections(begin, buffer.Size());
|
if (!m_gpu_modified_ranges.Intersects(begin, buffer.Size())) {
|
||||||
if (dirty.empty()) {
|
|
||||||
EXIT("BufferCache: GPU-modified buffer has no dirty ranges\n");
|
EXIT("BufferCache: GPU-modified buffer has no dirty ranges\n");
|
||||||
}
|
}
|
||||||
modified_buffers.emplace_back(begin, buffer.Size());
|
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) {
|
for (const auto& [begin, bytes]: retired_buffers) {
|
||||||
m_memory_tracker.MarkRegionAsCpuModified(begin, bytes);
|
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");
|
EXIT("BufferCache: unmap retained dirty byte ranges\n");
|
||||||
}
|
}
|
||||||
m_memory_tracker.UntrackMemory(vaddr, size);
|
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 cpu_modified = m_memory_tracker.IsRegionCpuModified(vaddr, size);
|
||||||
const bool gpu_modified = m_memory_tracker.IsRegionGpuModified(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 = m_gpu_modified_ranges.Intersects(vaddr, size);
|
||||||
const bool has_dirty_buffer_source = !dirty.empty();
|
|
||||||
m_memory_tracker.ValidateGpuDirtyOwnership(m_gpu_modified_ranges, vaddr, size,
|
m_memory_tracker.ValidateGpuDirtyOwnership(m_gpu_modified_ranges, vaddr, size,
|
||||||
"image source");
|
"image source");
|
||||||
|
|
||||||
@@ -592,8 +590,7 @@ std::pair<Buffer*, uint64_t> BufferCache::ObtainBufferForImage(uint64_t vaddr, u
|
|||||||
}
|
}
|
||||||
m_staging_buffer.Commit();
|
m_staging_buffer.Commit();
|
||||||
|
|
||||||
const auto dirty = m_gpu_modified_ranges.Intersections(vaddr, size);
|
const bool has_dirty_buffer_source = m_gpu_modified_ranges.Intersects(vaddr, size);
|
||||||
const bool has_dirty_buffer_source = !dirty.empty();
|
|
||||||
auto* owner = find_owner();
|
auto* owner = find_owner();
|
||||||
if (has_dirty_buffer_source && owner == nullptr) {
|
if (has_dirty_buffer_source && owner == nullptr) {
|
||||||
EXIT("BufferCache: GPU-dirty image source lost its native owner\n");
|
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) {
|
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) {
|
bool BufferCache::IsRegionCpuModified(uint64_t vaddr, uint64_t size) {
|
||||||
|
|||||||
@@ -191,6 +191,10 @@ void TestRangeSet() {
|
|||||||
ranges.Add(0x1200, 0x40);
|
ranges.Add(0x1200, 0x40);
|
||||||
Check(ranges.Contains(0x1010, 0xe0) && !ranges.Contains(0x1010, 0x200),
|
Check(ranges.Contains(0x1010, 0xe0) && !ranges.Contains(0x1010, 0x200),
|
||||||
"range set containment did not require full coverage");
|
"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);
|
auto intersections = ranges.Intersections(0x1070, 0x1b0);
|
||||||
Check(intersections.size() == 2 && intersections[0].address == 0x1070 &&
|
Check(intersections.size() == 2 && intersections[0].address == 0x1070 &&
|
||||||
intersections[0].size == 0x90 &&
|
intersections[0].size == 0x90 &&
|
||||||
|
|||||||
Reference in New Issue
Block a user