From c6cac2ffaad4ac27f35cea25022d9c59c7ecfbf4 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 30 Apr 2023 17:14:06 +0200 Subject: GPU: Add Reactive flushing --- src/video_core/texture_cache/texture_cache.h | 32 +++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index b5297e76b..fb8ffc002 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -490,6 +490,32 @@ void TextureCache

::DownloadMemory(VAddr cpu_addr, size_t size) { } } +template +std::optional TextureCache

::GetFlushArea(VAddr cpu_addr, + u64 size) { + std::optional area{}; + ForEachImageInRegion(cpu_addr, size, [&](ImageId, ImageBase& image) { + if (False(image.flags & ImageFlagBits::GpuModified)) { + return; + } + if (!area) { + area.emplace(); + area->start_address = cpu_addr; + area->end_address = cpu_addr + size; + area->preemtive = true; + } + area->start_address = std::min(area->start_address, image.cpu_addr); + area->end_address = std::max(area->end_address, image.cpu_addr_end); + for (auto image_view_id : image.image_view_ids) { + auto& image_view = slot_image_views[image_view_id]; + image_view.flags |= ImageViewFlagBits::PreemtiveDownload; + } + area->preemtive &= image.info.forced_flushed; + image.info.forced_flushed = true; + }); + return area; +} + template void TextureCache

::UnmapMemory(VAddr cpu_addr, size_t size) { std::vector deleted_images; @@ -789,11 +815,15 @@ ImageId TextureCache

::DmaImageId(const Tegra::DMA::ImageOperand& operand) { if (!dst_id) { return NULL_IMAGE_ID; } - const auto& image = slot_images[dst_id]; + auto& image = slot_images[dst_id]; if (False(image.flags & ImageFlagBits::GpuModified)) { // No need to waste time on an image that's synced with guest return NULL_IMAGE_ID; } + if (!image.info.forced_flushed) { + image.info.forced_flushed = true; + return NULL_IMAGE_ID; + } const auto base = image.TryFindBase(operand.address); if (!base) { return NULL_IMAGE_ID; -- cgit v1.2.3