renderer: remove legacy code left from refactoring

This commit is contained in:
nmzik
2026-07-31 23:13:48 +02:00
parent d68a477276
commit f830d6b2e4
15 changed files with 669 additions and 2414 deletions
+2 -110
View File
@@ -123,24 +123,6 @@ struct BufferCache::RetiredBuffer {
std::shared_ptr<Buffer> owner;
};
struct BufferCache::FaultReadback {
PageFaultAccess access = PageFaultAccess::Unknown;
uint64_t vaddr = 0;
uint64_t size = 0;
std::vector<DownloadRange> ranges;
bool installed = false;
[[nodiscard]] bool Active() const noexcept { return !ranges.empty(); }
void Reset() {
access = PageFaultAccess::Unknown;
vaddr = 0;
size = 0;
installed = false;
ranges.clear();
}
};
struct BufferCache::PendingBackingPublication {
uint64_t address = 0;
uint64_t size = 0;
@@ -253,7 +235,7 @@ BufferCache::BufferCache(GraphicContext& graphics, CommandScheduler& scheduler,
ResourceMutex& resource_mutex)
: m_graphics(graphics), m_scheduler(scheduler),
m_gds_buffer(graphics, scheduler, MemoryUsage::Stream, 0, AllFlags, GdsBufferSize),
m_fault_readback(std::make_unique<FaultReadback>()), m_memory_tracker(page_manager),
m_memory_tracker(page_manager),
m_staging_buffer(graphics, scheduler, MemoryUsage::Upload, 512 * MiB),
m_stream_buffer(graphics, scheduler, MemoryUsage::Stream, 64 * MiB),
m_download_buffer(graphics, scheduler, MemoryUsage::Download, 32 * MiB),
@@ -277,9 +259,6 @@ BufferCache::BufferCache(GraphicContext& graphics, CommandScheduler& scheduler,
}
BufferCache::~BufferCache() {
if (m_fault_readback->Active()) {
EXIT("BufferCache: destroyed with an active fault readback\n");
}
if (!m_gpu_modified_ranges.Empty()) {
EXIT("BufferCache: destroyed with pending GPU-modified ranges\n");
}
@@ -447,93 +426,6 @@ void BufferCache::ReadMemory(uint64_t vaddr, uint64_t size) {
}
}
bool BufferCache::InvalidateMemory(PageFaultAccess access, uint64_t vaddr, uint64_t size,
PageFaultPhase phase) noexcept {
const auto page = vaddr & ~(TRACKER_PAGE_SIZE - 1);
if (size == 0 || size > page + TRACKER_PAGE_SIZE - vaddr) {
EXIT("BufferCache: invalid page-fault range\n");
}
if (phase == PageFaultPhase::Complete) {
FaultSafeCacheLock lock(this, m_mutex);
auto& fault = *m_fault_readback;
if (!fault.Active()) {
return m_memory_tracker.CompleteCpuFault(vaddr, size, access, false);
}
if (fault.access != access || fault.vaddr != vaddr || fault.size != size ||
fault.installed) {
EXIT("BufferCache: mismatched fault readback completion\n");
}
PublishDownloads(fault.ranges);
if (!m_memory_tracker.CompleteCpuFault(vaddr, size, access, true)) {
EXIT("BufferCache: failed to complete downloaded CPU fault\n");
}
fault.installed = true;
return true;
}
if (phase == PageFaultPhase::Release) {
FaultSafeCacheLock lock(this, m_mutex);
auto& fault = *m_fault_readback;
if (fault.Active()) {
if (fault.access != access || fault.vaddr != vaddr || fault.size != size ||
!fault.installed) {
EXIT("BufferCache: mismatched fault readback release\n");
}
for (const auto& range: fault.ranges) {
m_gpu_modified_ranges.Subtract(range.address, range.size);
}
fault.Reset();
}
return true;
}
if (phase != PageFaultPhase::Invalidate) {
EXIT("BufferCache: unsupported page-fault phase\n");
}
const auto action = m_memory_tracker.BeginCpuFault(vaddr, size, access);
if (action != CpuFaultAction::Download) {
return action == CpuFaultAction::Continue;
}
auto& fault = *m_fault_readback;
std::vector<DownloadCopy> copies;
{
FaultSafeCacheLock lock(this, m_mutex);
if (fault.Active()) {
EXIT("BufferCache: nested fault readback\n");
}
fault.access = access;
fault.vaddr = vaddr;
fault.size = size;
m_gpu_modified_ranges.ForEachIntersection(
page, TRACKER_PAGE_SIZE, [&](RangeSet::Range range) {
auto owner = m_buffers.upper_bound(range.address);
if (owner == m_buffers.begin()) {
EXIT("BufferCache: fault readback has no buffer owner\n");
}
--owner;
auto& cached = *owner->second;
if (!cached.buffer->IsInBounds(range.address, range.size)) {
EXIT("BufferCache: fault readback is outside its buffer owner\n");
}
copies.push_back({cached.buffer, cached.buffer->Offset(range.address),
range.address, range.size});
});
if (copies.empty()) {
EXIT("BufferCache: GPU-dirty fault page has no dirty byte ranges\n");
}
}
fault.ranges = RecordDownloads(copies);
if (!fault.Active()) {
EXIT("BufferCache: GPU-dirty fault page has no dirty byte ranges\n");
}
m_scheduler.FinishCurrent();
return true;
}
void BufferCache::UnmapMemory(uint64_t vaddr, uint64_t size) {
if (vaddr == 0 || size == 0 || size > UINT64_MAX - vaddr) {
EXIT("BufferCache: invalid unmap range\n");
@@ -1201,7 +1093,7 @@ void BufferCache::RunGarbageCollector() {
if (m_graphics.CanReportMemoryUsage()) {
m_total_used_memory = m_graphics.GetDeviceMemoryUsage();
}
if (m_total_used_memory < m_trigger_gc_memory || m_fault_readback->Active()) {
if (m_total_used_memory < m_trigger_gc_memory) {
return;
}
+3 -7
View File
@@ -47,11 +47,9 @@ public:
~BufferCache();
KYTY_CLASS_NO_COPY(BufferCache);
[[nodiscard]] bool InvalidateMemory(PageFaultAccess access, uint64_t vaddr, uint64_t size,
PageFaultPhase phase) noexcept;
void InvalidateMemory(uint64_t vaddr, uint64_t size);
void ReadMemory(uint64_t vaddr, uint64_t size);
void UnmapMemory(uint64_t vaddr, uint64_t size);
void InvalidateMemory(uint64_t vaddr, uint64_t size);
void ReadMemory(uint64_t vaddr, uint64_t size);
void UnmapMemory(uint64_t vaddr, uint64_t size);
[[nodiscard]] BufferBinding ObtainBuffer(CommandBuffer& command, uint64_t vaddr, uint64_t size,
bool is_written = false, bool is_read = true,
bool is_formatted = false);
@@ -90,7 +88,6 @@ private:
struct DownloadCopy;
struct DownloadRange;
struct RetiredBuffer;
struct FaultReadback;
struct PendingBackingPublication;
static constexpr uint64_t DOWNLOAD_ALIGNMENT = 64;
[[nodiscard]] static uint64_t AlignDown(uint64_t value) noexcept;
@@ -120,7 +117,6 @@ private:
Common::Mutex m_mutex;
std::shared_ptr<Buffer> m_null_buffer;
std::map<uint64_t, std::unique_ptr<CachedBuffer>> m_buffers;
std::unique_ptr<FaultReadback> m_fault_readback;
RangeSet m_gpu_modified_ranges;
RangeSet m_image_invalidated_ranges;
std::mutex m_publication_mutex;
+1 -23
View File
@@ -7,33 +7,11 @@
namespace Libs::Graphics {
GpuResourceManager::GpuResourceManager(GraphicContext& graphics, CommandScheduler& scheduler)
: m_page_manager(FaultThunk, this),
m_buffer_cache(graphics, scheduler, m_page_manager, m_texture_cache, m_resource_mutex),
: m_buffer_cache(graphics, scheduler, m_page_manager, m_texture_cache, m_resource_mutex),
m_texture_cache(graphics, scheduler, m_page_manager, m_buffer_cache, m_resource_mutex) {}
GpuResourceManager::~GpuResourceManager() = default;
bool GpuResourceManager::FaultThunk(void* context, PageFaultAccess access, uint64_t vaddr,
uint64_t size, PageFaultPhase phase) noexcept {
return static_cast<GpuResourceManager*>(context)->InvalidateMemory(access, vaddr, size, phase);
}
bool GpuResourceManager::InvalidateMemory(PageFaultAccess access, uint64_t vaddr, uint64_t size,
PageFaultPhase phase) noexcept {
// Let the authoritative image materialize first. A clean overlapping buffer marks a write
// fault CPU-dirty when it begins ownership transfer; doing that before image preflight would
// make the image appear to race a real CPU write. Completion and release retain buffer-first
// ordering so its pending fault is gone before TextureCache publishes the downloaded backing.
if (phase == PageFaultPhase::Invalidate) {
const bool image_handled = m_texture_cache.InvalidateMemory(access, vaddr, size, phase);
const bool buffer_handled = m_buffer_cache.InvalidateMemory(access, vaddr, size, phase);
return buffer_handled || image_handled;
}
const bool buffer_handled = m_buffer_cache.InvalidateMemory(access, vaddr, size, phase);
const bool image_handled = m_texture_cache.InvalidateMemory(access, vaddr, size, phase);
return buffer_handled || image_handled;
}
bool GpuResourceManager::HandleFault(PageFaultAccess access, uint64_t fault_vaddr) noexcept {
constexpr uint64_t fault_size = 8;
if (!IsMapped(fault_vaddr, fault_size)) {
@@ -34,11 +34,6 @@ public:
void RunGarbageCollector();
private:
static bool FaultThunk(void* context, PageFaultAccess access, uint64_t vaddr, uint64_t size,
PageFaultPhase phase) noexcept;
[[nodiscard]] bool InvalidateMemory(PageFaultAccess access, uint64_t vaddr, uint64_t size,
PageFaultPhase phase) noexcept;
PageManager m_page_manager;
ResourceMutex m_resource_mutex;
BufferCache m_buffer_cache;
-31
View File
@@ -1826,37 +1826,6 @@ bool TextureCache::TouchMeta(uint64_t address, uint32_t slice, bool is_clear) {
return true;
}
bool TextureCache::InvalidateMemory(PageFaultAccess access, uint64_t address, uint64_t size,
PageFaultPhase phase) noexcept {
if ((access != PageFaultAccess::Read && access != PageFaultAccess::Write) ||
!GuestRange {address, size}.Valid()) {
return false;
}
if (access == PageFaultAccess::Read) {
return false;
}
if (phase == PageFaultPhase::Invalidate) {
CacheLock lock(*this, m_lock);
const bool tracked =
std::ranges::any_of(FindImagesInRegion(address, size, true), [&](ImageId id) {
const auto owner = ResolveOwner(id);
return owner != nullptr && !owner->depth_id && owner->IsTracked();
});
if (tracked) {
InvalidateCpuAliases(address, size);
}
return tracked;
}
if (phase != PageFaultPhase::Complete && phase != PageFaultPhase::Release) {
return false;
}
CacheLock lock(*this, m_lock);
return std::ranges::any_of(FindImagesInRegion(address, size, true), [&](ImageId id) {
const auto owner = ResolveOwner(id);
return owner != nullptr && !owner->depth_id;
});
}
void TextureCache::UnmapMemory(uint64_t address, uint64_t size) {
if (!GuestRange {address, size}.Valid()) {
EXIT("TextureCache: invalid unmap range\n");
+3 -5
View File
@@ -76,11 +76,9 @@ public:
[[nodiscard]] bool ClearMeta(uint64_t address);
[[nodiscard]] bool TouchMeta(uint64_t address, uint32_t slice, bool is_clear);
[[nodiscard]] bool InvalidateMemory(PageFaultAccess access, uint64_t address, uint64_t size,
PageFaultPhase phase) noexcept;
void UnmapMemory(uint64_t address, uint64_t size);
void ProcessDownloadImages();
void RunGarbageCollector();
void UnmapMemory(uint64_t address, uint64_t size);
void ProcessDownloadImages();
void RunGarbageCollector();
private:
enum class TransferDirection { Upload, Download };