summaryrefslogtreecommitdiff
path: root/src/video_core/texture_cache
diff options
context:
space:
mode:
authorGravatar liamwhite2023-05-07 19:05:56 -0400
committerGravatar GitHub2023-05-07 19:05:56 -0400
commit2688fb1aa2d80fc4edac87ff93365f3570cd3af8 (patch)
treeb874061d30aa6a03fd3c92116df92ed6d3b91a19 /src/video_core/texture_cache
parentMerge pull request #10097 from german77/nfp_full (diff)
parentTexture cache: Only force flush the dma downloads (diff)
downloadyuzu-2688fb1aa2d80fc4edac87ff93365f3570cd3af8.tar.gz
yuzu-2688fb1aa2d80fc4edac87ff93365f3570cd3af8.tar.xz
yuzu-2688fb1aa2d80fc4edac87ff93365f3570cd3af8.zip
Merge pull request #10155 from FernandoS27/reactive-flushing-new
Y.F.C. bring back Reactive Flushing
Diffstat (limited to 'src/video_core/texture_cache')
-rw-r--r--src/video_core/texture_cache/image_info.cpp12
-rw-r--r--src/video_core/texture_cache/image_info.h2
-rw-r--r--src/video_core/texture_cache/image_view_base.cpp4
-rw-r--r--src/video_core/texture_cache/texture_cache.h45
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h4
5 files changed, 59 insertions, 8 deletions
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 11f3f78a1..e8ddde691 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -4,6 +4,7 @@
4#include <fmt/format.h> 4#include <fmt/format.h>
5 5
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/settings.h"
7#include "video_core/surface.h" 8#include "video_core/surface.h"
8#include "video_core/texture_cache/format_lookup_table.h" 9#include "video_core/texture_cache/format_lookup_table.h"
9#include "video_core/texture_cache/image_info.h" 10#include "video_core/texture_cache/image_info.h"
@@ -22,6 +23,8 @@ using VideoCore::Surface::PixelFormat;
22using VideoCore::Surface::SurfaceType; 23using VideoCore::Surface::SurfaceType;
23 24
24ImageInfo::ImageInfo(const TICEntry& config) noexcept { 25ImageInfo::ImageInfo(const TICEntry& config) noexcept {
26 forced_flushed = config.IsPitchLinear() && !Settings::values.use_reactive_flushing.GetValue();
27 dma_downloaded = forced_flushed;
25 format = PixelFormatFromTextureInfo(config.format, config.r_type, config.g_type, config.b_type, 28 format = PixelFormatFromTextureInfo(config.format, config.r_type, config.g_type, config.b_type,
26 config.a_type, config.srgb_conversion); 29 config.a_type, config.srgb_conversion);
27 num_samples = NumSamples(config.msaa_mode); 30 num_samples = NumSamples(config.msaa_mode);
@@ -117,6 +120,9 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
117 120
118ImageInfo::ImageInfo(const Maxwell3D::Regs::RenderTargetConfig& ct, 121ImageInfo::ImageInfo(const Maxwell3D::Regs::RenderTargetConfig& ct,
119 Tegra::Texture::MsaaMode msaa_mode) noexcept { 122 Tegra::Texture::MsaaMode msaa_mode) noexcept {
123 forced_flushed =
124 ct.tile_mode.is_pitch_linear && !Settings::values.use_reactive_flushing.GetValue();
125 dma_downloaded = forced_flushed;
120 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(ct.format); 126 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(ct.format);
121 rescaleable = false; 127 rescaleable = false;
122 if (ct.tile_mode.is_pitch_linear) { 128 if (ct.tile_mode.is_pitch_linear) {
@@ -155,6 +161,9 @@ ImageInfo::ImageInfo(const Maxwell3D::Regs::RenderTargetConfig& ct,
155 161
156ImageInfo::ImageInfo(const Maxwell3D::Regs::Zeta& zt, const Maxwell3D::Regs::ZetaSize& zt_size, 162ImageInfo::ImageInfo(const Maxwell3D::Regs::Zeta& zt, const Maxwell3D::Regs::ZetaSize& zt_size,
157 Tegra::Texture::MsaaMode msaa_mode) noexcept { 163 Tegra::Texture::MsaaMode msaa_mode) noexcept {
164 forced_flushed =
165 zt.tile_mode.is_pitch_linear && !Settings::values.use_reactive_flushing.GetValue();
166 dma_downloaded = forced_flushed;
158 format = VideoCore::Surface::PixelFormatFromDepthFormat(zt.format); 167 format = VideoCore::Surface::PixelFormatFromDepthFormat(zt.format);
159 size.width = zt_size.width; 168 size.width = zt_size.width;
160 size.height = zt_size.height; 169 size.height = zt_size.height;
@@ -195,6 +204,9 @@ ImageInfo::ImageInfo(const Maxwell3D::Regs::Zeta& zt, const Maxwell3D::Regs::Zet
195 204
196ImageInfo::ImageInfo(const Fermi2D::Surface& config) noexcept { 205ImageInfo::ImageInfo(const Fermi2D::Surface& config) noexcept {
197 UNIMPLEMENTED_IF_MSG(config.layer != 0, "Surface layer is not zero"); 206 UNIMPLEMENTED_IF_MSG(config.layer != 0, "Surface layer is not zero");
207 forced_flushed = config.linear == Fermi2D::MemoryLayout::Pitch &&
208 !Settings::values.use_reactive_flushing.GetValue();
209 dma_downloaded = forced_flushed;
198 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(config.format); 210 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(config.format);
199 rescaleable = false; 211 rescaleable = false;
200 if (config.linear == Fermi2D::MemoryLayout::Pitch) { 212 if (config.linear == Fermi2D::MemoryLayout::Pitch) {
diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h
index 4b7dfa315..8a4cb0cbd 100644
--- a/src/video_core/texture_cache/image_info.h
+++ b/src/video_core/texture_cache/image_info.h
@@ -39,6 +39,8 @@ 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;
43 bool dma_downloaded = false;
42}; 44};
43 45
44} // namespace VideoCommon 46} // 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..d134b6738 100644
--- a/src/video_core/texture_cache/image_view_base.cpp
+++ b/src/video_core/texture_cache/image_view_base.cpp
@@ -4,7 +4,6 @@
4#include <algorithm> 4#include <algorithm>
5 5
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/settings.h"
8#include "video_core/compatible_formats.h" 7#include "video_core/compatible_formats.h"
9#include "video_core/surface.h" 8#include "video_core/surface.h"
10#include "video_core/texture_cache/formatter.h" 9#include "video_core/texture_cache/formatter.h"
@@ -26,8 +25,7 @@ ImageViewBase::ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_i
26 ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format, false, true), 25 ASSERT_MSG(VideoCore::Surface::IsViewCompatible(image_info.format, info.format, false, true),
27 "Image view format {} is incompatible with image format {}", info.format, 26 "Image view format {} is incompatible with image format {}", info.format,
28 image_info.format); 27 image_info.format);
29 const bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue(); 28 if (image_info.forced_flushed) {
30 if (image_info.type == ImageType::Linear && is_async) {
31 flags |= ImageViewFlagBits::PreemtiveDownload; 29 flags |= ImageViewFlagBits::PreemtiveDownload;
32 } 30 }
33 if (image_info.type == ImageType::e3D && info.type != ImageViewType::e3D) { 31 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..e1198dcf8 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); });
@@ -683,6 +709,7 @@ void TextureCache<P>::CommitAsyncFlushes() {
683 download_info.async_buffer_id = last_async_buffer_id; 709 download_info.async_buffer_id = last_async_buffer_id;
684 } 710 }
685 } 711 }
712
686 if (any_none_dma) { 713 if (any_none_dma) {
687 auto download_map = runtime.DownloadStagingBuffer(total_size_bytes, true); 714 auto download_map = runtime.DownloadStagingBuffer(total_size_bytes, true);
688 for (const PendingDownload& download_info : download_ids) { 715 for (const PendingDownload& download_info : download_ids) {
@@ -695,6 +722,7 @@ void TextureCache<P>::CommitAsyncFlushes() {
695 } 722 }
696 uncommitted_async_buffers.emplace_back(download_map); 723 uncommitted_async_buffers.emplace_back(download_map);
697 } 724 }
725
698 async_buffers.emplace_back(std::move(uncommitted_async_buffers)); 726 async_buffers.emplace_back(std::move(uncommitted_async_buffers));
699 uncommitted_async_buffers.clear(); 727 uncommitted_async_buffers.clear();
700 } 728 }
@@ -783,17 +811,22 @@ void TextureCache<P>::PopAsyncFlushes() {
783} 811}
784 812
785template <class P> 813template <class P>
786ImageId TextureCache<P>::DmaImageId(const Tegra::DMA::ImageOperand& operand) { 814ImageId TextureCache<P>::DmaImageId(const Tegra::DMA::ImageOperand& operand, bool is_upload) {
787 const ImageInfo dst_info(operand); 815 const ImageInfo dst_info(operand);
788 const ImageId dst_id = FindDMAImage(dst_info, operand.address); 816 const ImageId dst_id = FindDMAImage(dst_info, operand.address);
789 if (!dst_id) { 817 if (!dst_id) {
790 return NULL_IMAGE_ID; 818 return NULL_IMAGE_ID;
791 } 819 }
792 const auto& image = slot_images[dst_id]; 820 auto& image = slot_images[dst_id];
793 if (False(image.flags & ImageFlagBits::GpuModified)) { 821 if (False(image.flags & ImageFlagBits::GpuModified)) {
794 // No need to waste time on an image that's synced with guest 822 // No need to waste time on an image that's synced with guest
795 return NULL_IMAGE_ID; 823 return NULL_IMAGE_ID;
796 } 824 }
825 if (!is_upload && !image.info.dma_downloaded) {
826 // Force a full sync.
827 image.info.dma_downloaded = true;
828 return NULL_IMAGE_ID;
829 }
797 const auto base = image.TryFindBase(operand.address); 830 const auto base = image.TryFindBase(operand.address);
798 if (!base) { 831 if (!base) {
799 return NULL_IMAGE_ID; 832 return NULL_IMAGE_ID;
@@ -1290,7 +1323,6 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
1290 all_siblings.push_back(overlap_id); 1323 all_siblings.push_back(overlap_id);
1291 } else { 1324 } else {
1292 bad_overlap_ids.push_back(overlap_id); 1325 bad_overlap_ids.push_back(overlap_id);
1293 overlap.flags |= ImageFlagBits::BadOverlap;
1294 } 1326 }
1295 }; 1327 };
1296 ForEachImageInRegion(cpu_addr, size_bytes, region_check); 1328 ForEachImageInRegion(cpu_addr, size_bytes, region_check);
@@ -1401,7 +1433,12 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
1401 ImageBase& aliased = slot_images[aliased_id]; 1433 ImageBase& aliased = slot_images[aliased_id];
1402 aliased.overlapping_images.push_back(new_image_id); 1434 aliased.overlapping_images.push_back(new_image_id);
1403 new_image.overlapping_images.push_back(aliased_id); 1435 new_image.overlapping_images.push_back(aliased_id);
1404 new_image.flags |= ImageFlagBits::BadOverlap; 1436 if (aliased.info.resources.levels == 1 && aliased.overlapping_images.size() > 1) {
1437 aliased.flags |= ImageFlagBits::BadOverlap;
1438 }
1439 if (new_image.info.resources.levels == 1 && new_image.overlapping_images.size() > 1) {
1440 new_image.flags |= ImageFlagBits::BadOverlap;
1441 }
1405 } 1442 }
1406 RegisterImage(new_image_id); 1443 RegisterImage(new_image_id);
1407 return new_image_id; 1444 return new_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..0720494e5 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
@@ -205,7 +207,7 @@ public:
205 /// Pop asynchronous downloads 207 /// Pop asynchronous downloads
206 void PopAsyncFlushes(); 208 void PopAsyncFlushes();
207 209
208 [[nodiscard]] ImageId DmaImageId(const Tegra::DMA::ImageOperand& operand); 210 [[nodiscard]] ImageId DmaImageId(const Tegra::DMA::ImageOperand& operand, bool is_upload);
209 211
210 [[nodiscard]] std::pair<Image*, BufferImageCopy> DmaBufferImageCopy( 212 [[nodiscard]] std::pair<Image*, BufferImageCopy> DmaBufferImageCopy(
211 const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& buffer_operand, 213 const Tegra::DMA::ImageCopy& copy_info, const Tegra::DMA::BufferOperand& buffer_operand,