summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/texture_cache')
-rw-r--r--src/video_core/texture_cache/image_info.h1
-rw-r--r--src/video_core/texture_cache/image_view_base.cpp3
-rw-r--r--src/video_core/texture_cache/texture_cache.h32
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h2
4 files changed, 35 insertions, 3 deletions
diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h
index 4b7dfa315..cfb85a3dc 100644
--- a/src/video_core/texture_cache/image_info.h
+++ b/src/video_core/texture_cache/image_info.h
@@ -39,6 +39,7 @@ struct ImageInfo {
39 u32 tile_width_spacing = 0; 39 u32 tile_width_spacing = 0;
40 bool rescaleable = false; 40 bool rescaleable = false;
41 bool downscaleable = false; 41 bool downscaleable = false;
42 bool forced_flushed = false;
42}; 43};
43 44
44} // namespace VideoCommon 45} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp
index bcad40353..8f28342d5 100644
--- a/src/video_core/texture_cache/image_view_base.cpp
+++ b/src/video_core/texture_cache/image_view_base.cpp
@@ -26,8 +26,7 @@ ImageViewBase::ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_i
26 ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format, false, true), 26 ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format, false, true),
27 "Image view format {} is incompatible with image format {}", info.format, 27 "Image view format {} is incompatible with image format {}", info.format,
28 image_info.format); 28 image_info.format);
29 const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue(); 29 if (image_info.forced_flushed) {
30 if (image_info.type == ImageType::Linear && is_async) {
31 flags |= ImageViewFlagBits::PreemtiveDownload; 30 flags |= ImageViewFlagBits::PreemtiveDownload;
32 } 31 }
33 if (image_info.type == ImageType::e3D && info.type != ImageViewType::e3D) { 32 if (image_info.type == ImageType::e3D && info.type != ImageViewType::e3D) {
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
@@ -491,6 +491,32 @@ void TextureCache<P>::DownloadMemory(VAddr cpu_addr, size_t size) {
491} 491}
492 492
493template <class P> 493template <class P>
494std::optional<VideoCore::RasterizerDownloadArea> TextureCache<P>::GetFlushArea(VAddr cpu_addr,
495 u64 size) {
496 std::optional<VideoCore::RasterizerDownloadArea> area{};
497 ForEachImageInRegion(cpu_addr, size, [&](ImageId, ImageBase& image) {
498 if (False(image.flags & ImageFlagBits::GpuModified)) {
499 return;
500 }
501 if (!area) {
502 area.emplace();
503 area->start_address = cpu_addr;
504 area->end_address = cpu_addr + size;
505 area->preemtive = true;
506 }
507 area->start_address = std::min(area->start_address, image.cpu_addr);
508 area->end_address = std::max(area->end_address, image.cpu_addr_end);
509 for (auto image_view_id : image.image_view_ids) {
510 auto& image_view = slot_image_views[image_view_id];
511 image_view.flags |= ImageViewFlagBits::PreemtiveDownload;
512 }
513 area->preemtive &= image.info.forced_flushed;
514 image.info.forced_flushed = true;
515 });
516 return area;
517}
518
519template <class P>
494void TextureCache<P>::UnmapMemory(VAddr cpu_addr, size_t size) { 520void TextureCache<P>::UnmapMemory(VAddr cpu_addr, size_t size) {
495 std::vector<ImageId> deleted_images; 521 std::vector<ImageId> deleted_images;
496 ForEachImageInRegion(cpu_addr, size, [&](ImageId id, Image&) { deleted_images.push_back(id); }); 522 ForEachImageInRegion(cpu_addr, size, [&](ImageId id, Image&) { deleted_images.push_back(id); });
@@ -789,11 +815,15 @@ ImageId TextureCache<P>::DmaImageId(const Tegra::DMA::ImageOperand& operand) {
789 if (!dst_id) { 815 if (!dst_id) {
790 return NULL_IMAGE_ID; 816 return NULL_IMAGE_ID;
791 } 817 }
792 const auto& image = slot_images[dst_id]; 818 auto& image = slot_images[dst_id];
793 if (False(image.flags & ImageFlagBits::GpuModified)) { 819 if (False(image.flags & ImageFlagBits::GpuModified)) {
794 // No need to waste time on an image that's synced with guest 820 // No need to waste time on an image that's synced with guest
795 return NULL_IMAGE_ID; 821 return NULL_IMAGE_ID;
796 } 822 }
823 if (!image.info.forced_flushed) {
824 image.info.forced_flushed = true;
825 return NULL_IMAGE_ID;
826 }
797 const auto base = image.TryFindBase(operand.address); 827 const auto base = image.TryFindBase(operand.address);
798 if (!base) { 828 if (!base) {
799 return NULL_IMAGE_ID; 829 return NULL_IMAGE_ID;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 758b7e212..01f5ac588 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -179,6 +179,8 @@ public:
179 /// Download contents of host images to guest memory in a region 179 /// Download contents of host images to guest memory in a region
180 void DownloadMemory(VAddr cpu_addr, size_t size); 180 void DownloadMemory(VAddr cpu_addr, size_t size);
181 181
182 std::optional<VideoCore::RasterizerDownloadArea> GetFlushArea(VAddr cpu_addr, u64 size);
183
182 /// Remove images in a region 184 /// Remove images in a region
183 void UnmapMemory(VAddr cpu_addr, size_t size); 185 void UnmapMemory(VAddr cpu_addr, size_t size);
184 186