summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp8
-rw-r--r--src/video_core/texture_cache/texture_cache.h162
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h6
4 files changed, 96 insertions, 84 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 9b2a09007..2d9f770cd 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -918,7 +918,7 @@ bool Image::ScaleUp() {
918 return false; 918 return false;
919 } 919 }
920 flags |= ImageFlagBits::Rescaled; 920 flags |= ImageFlagBits::Rescaled;
921 Scale(); 921 //Scale();
922 return true; 922 return true;
923} 923}
924 924
@@ -927,7 +927,7 @@ bool Image::ScaleDown() {
927 return false; 927 return false;
928 } 928 }
929 flags &= ~ImageFlagBits::Rescaled; 929 flags &= ~ImageFlagBits::Rescaled;
930 Scale(); 930 //Scale();
931 return true; 931 return true;
932} 932}
933 933
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 668554d1e..5fd190825 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1078,6 +1078,10 @@ bool Image::ScaleUp(bool save_as_backup) {
1078 MemoryCommit new_commit( 1078 MemoryCommit new_commit(
1079 runtime->memory_allocator.Commit(rescaled_image, MemoryUsage::DeviceLocal)); 1079 runtime->memory_allocator.Commit(rescaled_image, MemoryUsage::DeviceLocal));
1080 1080
1081 if (aspect_mask == 0) {
1082 aspect_mask = ImageAspectMask(info.format);
1083 }
1084
1081 const auto scale_up = [&](u32 value) { 1085 const auto scale_up = [&](u32 value) {
1082 return (value * resolution.up_scale) >> resolution.down_shift; 1086 return (value * resolution.up_scale) >> resolution.down_shift;
1083 }; 1087 };
@@ -1170,6 +1174,10 @@ bool Image::ScaleDown(bool save_as_backup) {
1170 return (value * resolution.up_scale) >> resolution.down_shift; 1174 return (value * resolution.up_scale) >> resolution.down_shift;
1171 }; 1175 };
1172 1176
1177 if (aspect_mask == 0) {
1178 aspect_mask = ImageAspectMask(info.format);
1179 }
1180
1173 const bool is_2d = info.type == ImageType::e2D; 1181 const bool is_2d = info.type == ImageType::e2D;
1174 boost::container::small_vector<VkImageBlit, 4> vkRegions(info.resources.levels); 1182 boost::container::small_vector<VkImageBlit, 4> vkRegions(info.resources.levels);
1175 for (s32 level = 0; level < info.resources.levels; level++) { 1183 for (s32 level = 0; level < info.resources.levels; level++) {
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 95a9e8fe9..b7d1ae92d 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -204,75 +204,68 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
204 PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id)); 204 PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
205 return; 205 return;
206 } 206 }
207 flags[Dirty::RenderTargets] = false;
208
209 // Render target control is used on all render targets, so force look ups when this one is up
210 const bool force = flags[Dirty::RenderTargetControl];
211 flags[Dirty::RenderTargetControl] = false;
212
213 bool can_rescale = true;
214 std::array<ImageId, NUM_RT> tmp_color_images{};
215 ImageId tmp_depth_image{};
216 const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
217 if (view_id) {
218 const auto& view = slot_image_views[view_id];
219 const auto image_id = view.image_id;
220 id_save = image_id;
221 auto& image = slot_images[image_id];
222 can_rescale &= ImageCanRescale(image);
223 } else {
224 id_save = CORRUPT_ID;
225 }
226 };
227 for (size_t index = 0; index < NUM_RT; ++index) {
228 ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
229 if (flags[Dirty::ColorBuffer0 + index] || force) {
230 flags[Dirty::ColorBuffer0 + index] = false;
231 BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear));
232 }
233 check_rescale(color_buffer_id, tmp_color_images[index]);
234 }
235 if (flags[Dirty::ZetaBuffer] || force) {
236 flags[Dirty::ZetaBuffer] = false;
237 BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
238 }
239 check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
240 207
241 if (can_rescale) { 208 do {
242 const auto scale_up = [this](ImageId image_id) { 209 flags[Dirty::RenderTargets] = false;
243 if (image_id != CORRUPT_ID) { 210
244 Image& image = slot_images[image_id]; 211 has_deleted_images = false;
245 return ScaleUp(image); 212 // Render target control is used on all render targets, so force look ups when this one is
213 // up
214 const bool force = flags[Dirty::RenderTargetControl];
215 flags[Dirty::RenderTargetControl] = false;
216
217 bool can_rescale = true;
218 std::array<ImageId, NUM_RT> tmp_color_images{};
219 ImageId tmp_depth_image{};
220 const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
221 if (view_id) {
222 const auto& view = slot_image_views[view_id];
223 const auto image_id = view.image_id;
224 id_save = image_id;
225 auto& image = slot_images[image_id];
226 can_rescale &= ImageCanRescale(image);
227 } else {
228 id_save = CORRUPT_ID;
246 } 229 }
247 return false;
248 }; 230 };
249 for (size_t index = 0; index < NUM_RT; ++index) { 231 for (size_t index = 0; index < NUM_RT; ++index) {
250 if (scale_up(tmp_color_images[index])) { 232 ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
251 BindRenderTarget(&render_targets.color_buffer_ids[index], 233 if (flags[Dirty::ColorBuffer0 + index] || force) {
252 FindColorBuffer(index, is_clear)); 234 flags[Dirty::ColorBuffer0 + index] = false;
235 BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear));
253 } 236 }
237 check_rescale(color_buffer_id, tmp_color_images[index]);
254 } 238 }
255 if (scale_up(tmp_depth_image)) { 239 if (flags[Dirty::ZetaBuffer] || force) {
240 flags[Dirty::ZetaBuffer] = false;
256 BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear)); 241 BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
257 } 242 }
258 } else { 243 check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
259 const auto scale_down = [this](ImageId image_id) { 244
260 if (image_id != CORRUPT_ID) { 245 if (can_rescale) {
261 Image& image = slot_images[image_id]; 246 const auto scale_up = [this](ImageId image_id) {
262 return ScaleDown(image); 247 if (image_id != CORRUPT_ID) {
248 Image& image = slot_images[image_id];
249 ScaleUp(image);
250 }
251 };
252 for (size_t index = 0; index < NUM_RT; ++index) {
253 scale_up(tmp_color_images[index]);
263 } 254 }
264 return false; 255 scale_up(tmp_depth_image);
265 }; 256 } else {
266 for (size_t index = 0; index < NUM_RT; ++index) { 257 const auto scale_down = [this](ImageId image_id) {
267 if (scale_down(tmp_color_images[index])) { 258 if (image_id != CORRUPT_ID) {
268 BindRenderTarget(&render_targets.color_buffer_ids[index], 259 Image& image = slot_images[image_id];
269 FindColorBuffer(index, is_clear)); 260 ScaleDown(image);
261 }
262 };
263 for (size_t index = 0; index < NUM_RT; ++index) {
264 scale_down(tmp_color_images[index]);
270 } 265 }
266 scale_down(tmp_depth_image);
271 } 267 }
272 if (scale_down(tmp_depth_image)) { 268 } while (has_deleted_images);
273 BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
274 }
275 }
276 // Rescale End 269 // Rescale End
277 270
278 for (size_t index = 0; index < NUM_RT; ++index) { 271 for (size_t index = 0; index < NUM_RT; ++index) {
@@ -708,43 +701,54 @@ bool TextureCache<P>::ImageCanRescale(Image& image) {
708} 701}
709 702
710template <class P> 703template <class P>
711void TextureCache<P>::InvalidateScale(Image& image, bool invalidate_rt) { 704void TextureCache<P>::InvalidateScale(Image& image) {
712 const std::span<const ImageViewId> image_view_ids = image.image_view_ids; 705 const std::span<const ImageViewId> image_view_ids = image.image_view_ids;
713 if (invalidate_rt) { 706 auto& dirty = maxwell3d.dirty.flags;
714 auto& dirty = maxwell3d.dirty.flags; 707 dirty[Dirty::RenderTargets] = true;
715 dirty[Dirty::RenderTargets] = true; 708 dirty[Dirty::ZetaBuffer] = true;
716 dirty[Dirty::ZetaBuffer] = true; 709 for (size_t rt = 0; rt < NUM_RT; ++rt) {
717 for (size_t rt = 0; rt < NUM_RT; ++rt) { 710 dirty[Dirty::ColorBuffer0 + rt] = true;
718 dirty[Dirty::ColorBuffer0 + rt] = true; 711 }
719 } 712 for (const ImageViewId image_view_id : image_view_ids) {
720 for (const ImageViewId image_view_id : image_view_ids) { 713 std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{});
721 std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{}); 714 if (render_targets.depth_buffer_id == image_view_id) {
722 if (render_targets.depth_buffer_id == image_view_id) { 715 render_targets.depth_buffer_id = ImageViewId{};
723 render_targets.depth_buffer_id = ImageViewId{};
724 }
725 } 716 }
726 } 717 }
727 RemoveImageViewReferences(image_view_ids); 718 RemoveImageViewReferences(image_view_ids);
728 RemoveFramebuffers(image_view_ids); 719 RemoveFramebuffers(image_view_ids);
720 for (const ImageViewId image_view_id : image_view_ids) {
721 sentenced_image_view.Push(std::move(slot_image_views[image_view_id]));
722 slot_image_views.erase(image_view_id);
723 }
724 image.image_view_ids.clear();
725 image.image_view_infos.clear();
726 if constexpr (ENABLE_VALIDATION) {
727 std::ranges::fill(graphics_image_view_ids, CORRUPT_ID);
728 std::ranges::fill(compute_image_view_ids, CORRUPT_ID);
729 }
730 graphics_image_table.Invalidate();
731 compute_image_table.Invalidate();
732 has_deleted_images = true;
729} 733}
730 734
731template <class P> 735template <class P>
732bool TextureCache<P>::ScaleUp(Image& image, bool invalidate_rt) { 736bool TextureCache<P>::ScaleUp(Image& image) {
733 const bool rescaled = image.ScaleUp(); 737 const bool rescaled = image.ScaleUp();
734 if (!rescaled) { 738 if (!rescaled) {
735 return false; 739 return false;
736 } 740 }
737 InvalidateScale(image, invalidate_rt); 741 InvalidateScale(image);
738 return true; 742 return true;
739} 743}
740 744
741template <class P> 745template <class P>
742bool TextureCache<P>::ScaleDown(Image& image, bool invalidate_rt) { 746bool TextureCache<P>::ScaleDown(Image& image) {
743 const bool rescaled = image.ScaleDown(); 747 const bool rescaled = image.ScaleDown();
744 if (!rescaled) { 748 if (!rescaled) {
745 return false; 749 return false;
746 } 750 }
747 InvalidateScale(image, invalidate_rt); 751 InvalidateScale(image);
748 return true; 752 return true;
749} 753}
750 754
@@ -861,12 +865,12 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
861 if (can_rescale) { 865 if (can_rescale) {
862 for (const ImageId sibling_id : all_siblings) { 866 for (const ImageId sibling_id : all_siblings) {
863 Image& sibling = slot_images[sibling_id]; 867 Image& sibling = slot_images[sibling_id];
864 ScaleUp(sibling, true); 868 ScaleUp(sibling);
865 } 869 }
866 } else { 870 } else {
867 for (const ImageId sibling_id : all_siblings) { 871 for (const ImageId sibling_id : all_siblings) {
868 Image& sibling = slot_images[sibling_id]; 872 Image& sibling = slot_images[sibling_id];
869 ScaleDown(sibling, true); 873 ScaleDown(sibling);
870 } 874 }
871 } 875 }
872 876
@@ -893,9 +897,9 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
893 RefreshContents(new_image, new_image_id); 897 RefreshContents(new_image, new_image_id);
894 898
895 if (can_rescale) { 899 if (can_rescale) {
896 new_image.ScaleUp(); 900 ScaleUp(new_image);
897 } else { 901 } else {
898 new_image.ScaleDown(); 902 ScaleDown(new_image);
899 } 903 }
900 904
901 for (const ImageId overlap_id : overlap_ids) { 905 for (const ImageId overlap_id : overlap_ids) {
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 042678786..cdd99242b 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -327,9 +327,9 @@ private:
327 [[nodiscard]] bool IsFullClear(ImageViewId id); 327 [[nodiscard]] bool IsFullClear(ImageViewId id);
328 328
329 bool ImageCanRescale(Image& image); 329 bool ImageCanRescale(Image& image);
330 void InvalidateScale(Image& image, bool invalidate_rt = false); 330 void InvalidateScale(Image& image);
331 bool ScaleUp(Image& image, bool invalidate_rt = false); 331 bool ScaleUp(Image& image);
332 bool ScaleDown(Image& image, bool invalidate_rt = false); 332 bool ScaleDown(Image& image);
333 333
334 Runtime& runtime; 334 Runtime& runtime;
335 VideoCore::RasterizerInterface& rasterizer; 335 VideoCore::RasterizerInterface& rasterizer;