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 From 0f4f18265f4f45ae1314b0fef10c4bdf9b870b8b Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 1 May 2023 17:34:03 +0200 Subject: Texture cache: sync the first flush. --- src/video_core/texture_cache/texture_cache.h | 32 +++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (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 fb8ffc002..762e8a52f 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -709,18 +709,43 @@ void TextureCache

::CommitAsyncFlushes() { download_info.async_buffer_id = last_async_buffer_id; } } + if (any_none_dma) { + bool all_pre_sync = true; auto download_map = runtime.DownloadStagingBuffer(total_size_bytes, true); for (const PendingDownload& download_info : download_ids) { if (download_info.is_swizzle) { Image& image = slot_images[download_info.object_id]; + all_pre_sync &= image.info.dma_downloaded; + image.info.dma_downloaded = true; const auto copies = FullDownloadCopies(image.info); image.DownloadMemory(download_map, copies); download_map.offset += Common::AlignUp(image.unswizzled_size_bytes, 64); } } - uncommitted_async_buffers.emplace_back(download_map); + if (!all_pre_sync) { + runtime.Finish(); + auto it = download_ids.begin(); + while (it != download_ids.end()) { + const PendingDownload& download_info = *it; + if (download_info.is_swizzle) { + const ImageBase& image = slot_images[download_info.object_id]; + const auto copies = FullDownloadCopies(image.info); + download_map.offset -= Common::AlignUp(image.unswizzled_size_bytes, 64); + std::span download_span = + download_map.mapped_span.subspan(download_map.offset); + SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span, + swizzle_data_buffer); + it = download_ids.erase(it); + } else { + it++; + } + } + } else { + uncommitted_async_buffers.emplace_back(download_map); + } } + async_buffers.emplace_back(std::move(uncommitted_async_buffers)); uncommitted_async_buffers.clear(); } @@ -820,8 +845,9 @@ ImageId TextureCache

::DmaImageId(const Tegra::DMA::ImageOperand& operand) { // 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; + if (!image.info.dma_downloaded) { + // Force a full sync. + image.info.dma_downloaded = true; return NULL_IMAGE_ID; } const auto base = image.TryFindBase(operand.address); -- cgit v1.2.3 From 016c6feb49255792e4093be381e20509eb94e6d1 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 4 May 2023 17:44:49 +0200 Subject: Texture cache: reverse inmediate flush changes --- src/video_core/texture_cache/texture_cache.h | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (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 762e8a52f..29ac01eb4 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -711,39 +711,16 @@ void TextureCache

::CommitAsyncFlushes() { } if (any_none_dma) { - bool all_pre_sync = true; auto download_map = runtime.DownloadStagingBuffer(total_size_bytes, true); for (const PendingDownload& download_info : download_ids) { if (download_info.is_swizzle) { Image& image = slot_images[download_info.object_id]; - all_pre_sync &= image.info.dma_downloaded; - image.info.dma_downloaded = true; const auto copies = FullDownloadCopies(image.info); image.DownloadMemory(download_map, copies); download_map.offset += Common::AlignUp(image.unswizzled_size_bytes, 64); } } - if (!all_pre_sync) { - runtime.Finish(); - auto it = download_ids.begin(); - while (it != download_ids.end()) { - const PendingDownload& download_info = *it; - if (download_info.is_swizzle) { - const ImageBase& image = slot_images[download_info.object_id]; - const auto copies = FullDownloadCopies(image.info); - download_map.offset -= Common::AlignUp(image.unswizzled_size_bytes, 64); - std::span download_span = - download_map.mapped_span.subspan(download_map.offset); - SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span, - swizzle_data_buffer); - it = download_ids.erase(it); - } else { - it++; - } - } - } else { - uncommitted_async_buffers.emplace_back(download_map); - } + uncommitted_async_buffers.emplace_back(download_map); } async_buffers.emplace_back(std::move(uncommitted_async_buffers)); -- cgit v1.2.3 From 2df19ef0fd5a91ca87e2c2cf201166a40c9d44dc Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 7 May 2023 23:25:34 +0200 Subject: Buffer Cache: disable reactive flushing in it. --- src/video_core/texture_cache/texture_cache.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (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 29ac01eb4..d49f3a7a0 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1323,7 +1323,6 @@ ImageId TextureCache

::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA all_siblings.push_back(overlap_id); } else { bad_overlap_ids.push_back(overlap_id); - overlap.flags |= ImageFlagBits::BadOverlap; } }; ForEachImageInRegion(cpu_addr, size_bytes, region_check); @@ -1434,7 +1433,12 @@ ImageId TextureCache

::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA ImageBase& aliased = slot_images[aliased_id]; aliased.overlapping_images.push_back(new_image_id); new_image.overlapping_images.push_back(aliased_id); - new_image.flags |= ImageFlagBits::BadOverlap; + if (aliased.info.resources.levels == 1 && aliased.overlapping_images.size() > 1) { + aliased.flags |= ImageFlagBits::BadOverlap; + } + if (new_image.info.resources.levels == 1 && new_image.overlapping_images.size() > 1) { + new_image.flags |= ImageFlagBits::BadOverlap; + } } RegisterImage(new_image_id); return new_image_id; -- cgit v1.2.3 From 8014dd82594dbb40e13749203e67b21e8447733c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 7 May 2023 23:34:52 +0200 Subject: Texture cache: Only force flush the dma downloads --- src/video_core/texture_cache/texture_cache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (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 d49f3a7a0..e1198dcf8 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -811,7 +811,7 @@ void TextureCache

::PopAsyncFlushes() { } template -ImageId TextureCache

::DmaImageId(const Tegra::DMA::ImageOperand& operand) { +ImageId TextureCache

::DmaImageId(const Tegra::DMA::ImageOperand& operand, bool is_upload) { const ImageInfo dst_info(operand); const ImageId dst_id = FindDMAImage(dst_info, operand.address); if (!dst_id) { @@ -822,7 +822,7 @@ ImageId TextureCache

::DmaImageId(const Tegra::DMA::ImageOperand& operand) { // No need to waste time on an image that's synced with guest return NULL_IMAGE_ID; } - if (!image.info.dma_downloaded) { + if (!is_upload && !image.info.dma_downloaded) { // Force a full sync. image.info.dma_downloaded = true; return NULL_IMAGE_ID; -- cgit v1.2.3