summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-11-26 21:36:53 +0100
committerGravatar Fernando Sahmkow2021-11-27 11:22:16 +0100
commitecefc932e64bf4ab8442d3c9808a2e54429e7001 (patch)
tree5c89e97f5893905cfc490ef3a7d67ae066be23ae /src
parentTexture Cache: Further fix regressions. (diff)
downloadyuzu-ecefc932e64bf4ab8442d3c9808a2e54429e7001.tar.gz
yuzu-ecefc932e64bf4ab8442d3c9808a2e54429e7001.tar.xz
yuzu-ecefc932e64bf4ab8442d3c9808a2e54429e7001.zip
Texture Cache: Redesigning the blitting system (again).
Diffstat (limited to 'src')
-rw-r--r--src/video_core/texture_cache/texture_cache.h52
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h3
-rw-r--r--src/video_core/texture_cache/util.cpp32
3 files changed, 64 insertions, 23 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 570da2b04..f24de9a38 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -472,7 +472,7 @@ template <class P>
472void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, 472void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
473 const Tegra::Engines::Fermi2D::Surface& src, 473 const Tegra::Engines::Fermi2D::Surface& src,
474 const Tegra::Engines::Fermi2D::Config& copy) { 474 const Tegra::Engines::Fermi2D::Config& copy) {
475 const BlitImages images = GetBlitImages(dst, src); 475 const BlitImages images = GetBlitImages(dst, src, copy);
476 const ImageId dst_id = images.dst_id; 476 const ImageId dst_id = images.dst_id;
477 const ImageId src_id = images.src_id; 477 const ImageId src_id = images.src_id;
478 478
@@ -762,12 +762,15 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
762 const bool broken_views = 762 const bool broken_views =
763 runtime.HasBrokenTextureViewFormats() || True(options & RelaxedOptions::ForceBrokenViews); 763 runtime.HasBrokenTextureViewFormats() || True(options & RelaxedOptions::ForceBrokenViews);
764 const bool native_bgr = runtime.HasNativeBgr(); 764 const bool native_bgr = runtime.HasNativeBgr();
765 ImageId image_id; 765 const bool flexible_formats = True(options & RelaxedOptions::Format);
766 ImageId image_id{};
767 boost::container::small_vector<ImageId, 1> image_ids;
766 const auto lambda = [&](ImageId existing_image_id, ImageBase& existing_image) { 768 const auto lambda = [&](ImageId existing_image_id, ImageBase& existing_image) {
767 if (True(existing_image.flags & ImageFlagBits::Remapped)) { 769 if (True(existing_image.flags & ImageFlagBits::Remapped)) {
768 return false; 770 return false;
769 } 771 }
770 if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear) { 772 if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear)
773 [[unlikely]] {
771 const bool strict_size = False(options & RelaxedOptions::Size) && 774 const bool strict_size = False(options & RelaxedOptions::Size) &&
772 True(existing_image.flags & ImageFlagBits::Strong); 775 True(existing_image.flags & ImageFlagBits::Strong);
773 const ImageInfo& existing = existing_image.info; 776 const ImageInfo& existing = existing_image.info;
@@ -776,17 +779,27 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
776 IsPitchLinearSameSize(existing, info, strict_size) && 779 IsPitchLinearSameSize(existing, info, strict_size) &&
777 IsViewCompatible(existing.format, info.format, broken_views, native_bgr)) { 780 IsViewCompatible(existing.format, info.format, broken_views, native_bgr)) {
778 image_id = existing_image_id; 781 image_id = existing_image_id;
779 return true; 782 image_ids.push_back(existing_image_id);
783 return !flexible_formats && existing.format == info.format;
780 } 784 }
781 } else if (IsSubresource(info, existing_image, gpu_addr, options, broken_views, 785 } else if (IsSubresource(info, existing_image, gpu_addr, options, broken_views,
782 native_bgr)) { 786 native_bgr)) {
783 image_id = existing_image_id; 787 image_id = existing_image_id;
784 return true; 788 image_ids.push_back(existing_image_id);
789 return !flexible_formats && existing_image.info.format == info.format;
785 } 790 }
786 return false; 791 return false;
787 }; 792 };
788 ForEachImageInRegion(*cpu_addr, CalculateGuestSizeInBytes(info), lambda); 793 ForEachImageInRegion(*cpu_addr, CalculateGuestSizeInBytes(info), lambda);
789 return image_id; 794 if (image_ids.size() <= 1) [[likely]] {
795 return image_id;
796 }
797 auto image_ids_compare = [this](ImageId a, ImageId b) {
798 auto& image_a = slot_images[a];
799 auto& image_b = slot_images[b];
800 return image_a.modification_tick < image_b.modification_tick;
801 };
802 return *std::ranges::max_element(image_ids, image_ids_compare);
790} 803}
791 804
792template <class P> 805template <class P>
@@ -1078,17 +1091,26 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
1078 1091
1079template <class P> 1092template <class P>
1080typename TextureCache<P>::BlitImages TextureCache<P>::GetBlitImages( 1093typename TextureCache<P>::BlitImages TextureCache<P>::GetBlitImages(
1081 const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src) { 1094 const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src,
1095 const Tegra::Engines::Fermi2D::Config& copy) {
1096
1082 static constexpr auto FIND_OPTIONS = RelaxedOptions::Samples; 1097 static constexpr auto FIND_OPTIONS = RelaxedOptions::Samples;
1083 const GPUVAddr dst_addr = dst.Address(); 1098 const GPUVAddr dst_addr = dst.Address();
1084 const GPUVAddr src_addr = src.Address(); 1099 const GPUVAddr src_addr = src.Address();
1085 ImageInfo dst_info(dst); 1100 ImageInfo dst_info(dst);
1086 ImageInfo src_info(src); 1101 ImageInfo src_info(src);
1102 const bool can_be_depth_blit =
1103 dst_info.format == src_info.format && copy.filter == Tegra::Engines::Fermi2D::Filter::Point;
1087 ImageId dst_id; 1104 ImageId dst_id;
1088 ImageId src_id; 1105 ImageId src_id;
1106 RelaxedOptions try_options = FIND_OPTIONS;
1107 if (can_be_depth_blit) {
1108 try_options |= RelaxedOptions::Format;
1109 }
1089 do { 1110 do {
1090 has_deleted_images = false; 1111 has_deleted_images = false;
1091 src_id = FindImage(src_info, src_addr, FIND_OPTIONS); 1112 src_id = FindImage(src_info, src_addr, try_options);
1113 dst_id = FindImage(dst_info, dst_addr, try_options);
1092 const ImageBase* const src_image = src_id ? &slot_images[src_id] : nullptr; 1114 const ImageBase* const src_image = src_id ? &slot_images[src_id] : nullptr;
1093 if (src_image && src_image->info.num_samples > 1) { 1115 if (src_image && src_image->info.num_samples > 1) {
1094 RelaxedOptions find_options{FIND_OPTIONS | RelaxedOptions::ForceBrokenViews}; 1116 RelaxedOptions find_options{FIND_OPTIONS | RelaxedOptions::ForceBrokenViews};
@@ -1097,8 +1119,15 @@ typename TextureCache<P>::BlitImages TextureCache<P>::GetBlitImages(
1097 if (has_deleted_images) { 1119 if (has_deleted_images) {
1098 continue; 1120 continue;
1099 } 1121 }
1122 break;
1123 }
1124 if (can_be_depth_blit) {
1125 const ImageBase* const dst_image = src_id ? &slot_images[src_id] : nullptr;
1126 DeduceBlitImages(dst_info, src_info, dst_image, src_image);
1127 if (GetFormatType(dst_info.format) != GetFormatType(src_info.format)) {
1128 continue;
1129 }
1100 } 1130 }
1101 dst_id = FindImage(dst_info, dst_addr, FIND_OPTIONS);
1102 if (!src_id) { 1131 if (!src_id) {
1103 src_id = InsertImage(src_info, src_addr, RelaxedOptions{}); 1132 src_id = InsertImage(src_info, src_addr, RelaxedOptions{});
1104 } 1133 }
@@ -1106,6 +1135,11 @@ typename TextureCache<P>::BlitImages TextureCache<P>::GetBlitImages(
1106 dst_id = InsertImage(dst_info, dst_addr, RelaxedOptions{}); 1135 dst_id = InsertImage(dst_info, dst_addr, RelaxedOptions{});
1107 } 1136 }
1108 } while (has_deleted_images); 1137 } while (has_deleted_images);
1138 if (GetFormatType(dst_info.format) != SurfaceType::ColorTexture) {
1139 // Make sure the images are depth and/or stencil textures.
1140 src_id = FindOrInsertImage(src_info, src_addr, RelaxedOptions{});
1141 dst_id = FindOrInsertImage(dst_info, dst_addr, RelaxedOptions{});
1142 }
1109 return BlitImages{ 1143 return BlitImages{
1110 .dst_id = dst_id, 1144 .dst_id = dst_id,
1111 .src_id = src_id, 1145 .src_id = src_id,
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 643ad811c..7107887a6 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -252,7 +252,8 @@ private:
252 252
253 /// Return a blit image pair from the given guest blit parameters 253 /// Return a blit image pair from the given guest blit parameters
254 [[nodiscard]] BlitImages GetBlitImages(const Tegra::Engines::Fermi2D::Surface& dst, 254 [[nodiscard]] BlitImages GetBlitImages(const Tegra::Engines::Fermi2D::Surface& dst,
255 const Tegra::Engines::Fermi2D::Surface& src); 255 const Tegra::Engines::Fermi2D::Surface& src,
256 const Tegra::Engines::Fermi2D::Config& copy);
256 257
257 /// Find or create a sampler from a guest descriptor sampler 258 /// Find or create a sampler from a guest descriptor sampler
258 [[nodiscard]] SamplerId FindSampler(const TSCEntry& config); 259 [[nodiscard]] SamplerId FindSampler(const TSCEntry& config);
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index 9b1613008..7bd31b211 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -1151,19 +1151,25 @@ bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, GPUVAddr
1151 1151
1152void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, 1152void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst,
1153 const ImageBase* src) { 1153 const ImageBase* src) {
1154 bool is_resolve = false; 1154 const auto original_dst_format = dst_info.format;
1155 if (src) { 1155 if (src && GetFormatType(src->info.format) != SurfaceType::ColorTexture) {
1156 is_resolve = src->info.num_samples > 1; 1156 src_info.format = src->info.format;
1157 src_info.num_samples = src->info.num_samples; 1157 }
1158 src_info.size.width = src->info.size.width; 1158 if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) {
1159 src_info.size.height = src->info.size.height; 1159 dst_info.format = dst->info.format;
1160 } 1160 }
1161 if (dst) { 1161 if (src && GetFormatType(src->info.format) != SurfaceType::ColorTexture) {
1162 dst_info.num_samples = dst->info.num_samples; 1162 dst_info.format = src->info.format;
1163 dst_info.size.width = dst->info.size.width; 1163 }
1164 dst_info.size.height = dst->info.size.height; 1164 if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) {
1165 } 1165 if (src) {
1166 ASSERT(!is_resolve || dst_info.format == src_info.format); 1166 if (GetFormatType(src->info.format) == SurfaceType::ColorTexture) {
1167 dst_info.format = original_dst_format;
1168 }
1169 } else {
1170 src_info.format = dst->info.format;
1171 }
1172 }
1167} 1173}
1168 1174
1169u32 MapSizeBytes(const ImageBase& image) { 1175u32 MapSizeBytes(const ImageBase& image) {