summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-10-17 18:01:18 +0200
committerGravatar Fernando Sahmkow2021-11-16 22:11:31 +0100
commit425ab9ef4b982213f4ee0d53196f5474e255374f (patch)
tree467bc959ea481d58514d11ca73e8f31b3557d4aa /src
parentPresentation: add Nearest Neighbor filter. (diff)
downloadyuzu-425ab9ef4b982213f4ee0d53196f5474e255374f.tar.gz
yuzu-425ab9ef4b982213f4ee0d53196f5474e255374f.tar.xz
yuzu-425ab9ef4b982213f4ee0d53196f5474e255374f.zip
Texture Cache: Fix downscaling and correct memory comsumption.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp43
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp93
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h3
-rw-r--r--src/video_core/texture_cache/image_base.cpp4
-rw-r--r--src/video_core/texture_cache/image_base.h5
-rw-r--r--src/video_core/texture_cache/texture_cache.h31
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h2
8 files changed, 147 insertions, 36 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 944a3aa65..34d3723e5 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -876,7 +876,7 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b
876 } 876 }
877} 877}
878 878
879bool Image::Scale() { 879bool Image::Scale(bool up_scale) {
880 const auto format_type = GetFormatType(info.format); 880 const auto format_type = GetFormatType(info.format);
881 const GLenum attachment = [format_type] { 881 const GLenum attachment = [format_type] {
882 switch (format_type) { 882 switch (format_type) {
@@ -944,14 +944,25 @@ bool Image::Scale() {
944 const GLuint draw_fbo = runtime->rescale_draw_fbos[fbo_index].handle; 944 const GLuint draw_fbo = runtime->rescale_draw_fbos[fbo_index].handle;
945 for (s32 layer = 0; layer < info.resources.layers; ++layer) { 945 for (s32 layer = 0; layer < info.resources.layers; ++layer) {
946 for (s32 level = 0; level < info.resources.levels; ++level) { 946 for (s32 level = 0; level < info.resources.levels; ++level) {
947 const u32 src_level_width = std::max(1u, original_width >> level); 947 const u32 src_level_width =
948 const u32 src_level_height = std::max(1u, original_height >> level); 948 std::max(1u, (up_scale ? original_width : scaled_width) >> level);
949 const u32 dst_level_width = std::max(1u, scaled_width >> level); 949 const u32 src_level_height =
950 const u32 dst_level_height = std::max(1u, scaled_height >> level); 950 std::max(1u, (up_scale ? original_height : scaled_height) >> level);
951 951 const u32 dst_level_width =
952 glNamedFramebufferTextureLayer(read_fbo, attachment, texture.handle, level, layer); 952 std::max(1u, (up_scale ? scaled_width : original_width) >> level);
953 glNamedFramebufferTextureLayer(draw_fbo, attachment, upscaled_backup.handle, level, 953 const u32 dst_level_height =
954 layer); 954 std::max(1u, (up_scale ? scaled_height : original_height) >> level);
955
956 if (up_scale) {
957 glNamedFramebufferTextureLayer(read_fbo, attachment, texture.handle, level, layer);
958 glNamedFramebufferTextureLayer(draw_fbo, attachment, upscaled_backup.handle, level,
959 layer);
960 } else {
961 glNamedFramebufferTextureLayer(read_fbo, attachment, upscaled_backup.handle, level,
962 layer);
963 glNamedFramebufferTextureLayer(draw_fbo, attachment, texture.handle, level, layer);
964 }
965
955 glBlitNamedFramebuffer(read_fbo, draw_fbo, 0, 0, src_level_width, src_level_height, 0, 966 glBlitNamedFramebuffer(read_fbo, draw_fbo, 0, 0, src_level_width, src_level_height, 0,
956 0, dst_level_width, dst_level_height, mask, filter); 967 0, dst_level_width, dst_level_height, mask, filter);
957 } 968 }
@@ -959,7 +970,12 @@ bool Image::Scale() {
959 if (scissor_test != GL_FALSE) { 970 if (scissor_test != GL_FALSE) {
960 glEnablei(GL_SCISSOR_TEST, 0); 971 glEnablei(GL_SCISSOR_TEST, 0);
961 } 972 }
962 current_texture = upscaled_backup.handle; 973 if (up_scale) {
974 current_texture = upscaled_backup.handle;
975 } else {
976 current_texture = texture.handle;
977 }
978
963 return true; 979 return true;
964} 980}
965 981
@@ -981,6 +997,7 @@ bool Image::ScaleUp() {
981 flags &= ~ImageFlagBits::Rescaled; 997 flags &= ~ImageFlagBits::Rescaled;
982 return false; 998 return false;
983 } 999 }
1000 scale_count++;
984 if (!Scale()) { 1001 if (!Scale()) {
985 flags &= ~ImageFlagBits::Rescaled; 1002 flags &= ~ImageFlagBits::Rescaled;
986 return false; 1003 return false;
@@ -996,7 +1013,11 @@ bool Image::ScaleDown() {
996 if (!runtime->resolution.active) { 1013 if (!runtime->resolution.active) {
997 return false; 1014 return false;
998 } 1015 }
999 current_texture = texture.handle; 1016 scale_count++;
1017 if (!Scale(false)) {
1018 flags &= ~ImageFlagBits::Rescaled;
1019 return false;
1020 }
1000 return true; 1021 return true;
1001} 1022}
1002 1023
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index f90dbfe9e..81aaef3da 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -205,7 +205,7 @@ private:
205 205
206 void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); 206 void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset);
207 207
208 bool Scale(); 208 bool Scale(bool up_scale = true);
209 209
210 OGLTexture texture; 210 OGLTexture texture;
211 OGLTexture upscaled_backup; 211 OGLTexture upscaled_backup;
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 17c62e27d..51367c01d 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -592,7 +592,8 @@ struct RangedBarrierRange {
592} 592}
593 593
594void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info, 594void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info,
595 VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution) { 595 VkImageAspectFlags aspect_mask, const Settings::ResolutionScalingInfo& resolution,
596 bool up_scaling = true) {
596 const bool is_2d = info.type == ImageType::e2D; 597 const bool is_2d = info.type == ImageType::e2D;
597 const auto resources = info.resources; 598 const auto resources = info.resources;
598 const VkExtent2D extent{ 599 const VkExtent2D extent{
@@ -605,14 +606,16 @@ void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, con
605 606
606 scheduler.RequestOutsideRenderPassOperationContext(); 607 scheduler.RequestOutsideRenderPassOperationContext();
607 scheduler.Record([dst_image, src_image, extent, resources, aspect_mask, resolution, is_2d, 608 scheduler.Record([dst_image, src_image, extent, resources, aspect_mask, resolution, is_2d,
608 vk_filter](vk::CommandBuffer cmdbuf) { 609 vk_filter, up_scaling](vk::CommandBuffer cmdbuf) {
609 const VkOffset2D src_size{ 610 const VkOffset2D src_size{
610 .x = static_cast<s32>(extent.width), 611 .x = static_cast<s32>(up_scaling ? extent.width : resolution.ScaleUp(extent.width)),
611 .y = static_cast<s32>(extent.height), 612 .y = static_cast<s32>(is_2d && up_scaling ? extent.height
613 : resolution.ScaleUp(extent.height)),
612 }; 614 };
613 const VkOffset2D dst_size{ 615 const VkOffset2D dst_size{
614 .x = static_cast<s32>(resolution.ScaleUp(extent.width)), 616 .x = static_cast<s32>(up_scaling ? resolution.ScaleUp(extent.width) : extent.width),
615 .y = static_cast<s32>(is_2d ? resolution.ScaleUp(extent.height) : extent.height), 617 .y = static_cast<s32>(is_2d && up_scaling ? resolution.ScaleUp(extent.height)
618 : extent.height),
616 }; 619 };
617 boost::container::small_vector<VkImageBlit, 4> regions; 620 boost::container::small_vector<VkImageBlit, 4> regions;
618 regions.reserve(resources.levels); 621 regions.reserve(resources.levels);
@@ -1134,6 +1137,7 @@ bool Image::ScaleUp() {
1134 if (!resolution.active) { 1137 if (!resolution.active) {
1135 return false; 1138 return false;
1136 } 1139 }
1140 scale_count++;
1137 const auto& device = runtime->device; 1141 const auto& device = runtime->device;
1138 const bool is_2d = info.type == ImageType::e2D; 1142 const bool is_2d = info.type == ImageType::e2D;
1139 const u32 scaled_width = resolution.ScaleUp(info.size.width); 1143 const u32 scaled_width = resolution.ScaleUp(info.size.width);
@@ -1161,8 +1165,10 @@ bool Image::ScaleUp() {
1161 using namespace VideoCommon; 1165 using namespace VideoCommon;
1162 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy; 1166 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy;
1163 1167
1164 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format); 1168 if (!scale_view) {
1165 scale_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this); 1169 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format);
1170 scale_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this);
1171 }
1166 auto* view_ptr = scale_view.get(); 1172 auto* view_ptr = scale_view.get();
1167 1173
1168 const Region2D src_region{ 1174 const Region2D src_region{
@@ -1178,7 +1184,10 @@ bool Image::ScaleUp() {
1178 .height = scaled_height, 1184 .height = scaled_height,
1179 }; 1185 };
1180 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) { 1186 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
1181 scale_framebuffer = std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent); 1187 if (!scale_framebuffer) {
1188 scale_framebuffer =
1189 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1190 }
1182 const auto color_view = scale_view->Handle(Shader::TextureType::Color2D); 1191 const auto color_view = scale_view->Handle(Shader::TextureType::Color2D);
1183 1192
1184 runtime->blit_image_helper.BlitColor( 1193 runtime->blit_image_helper.BlitColor(
@@ -1186,7 +1195,10 @@ bool Image::ScaleUp() {
1186 Tegra::Engines::Fermi2D::Filter::Bilinear, BLIT_OPERATION); 1195 Tegra::Engines::Fermi2D::Filter::Bilinear, BLIT_OPERATION);
1187 } else if (!runtime->device.IsBlitDepthStencilSupported() && 1196 } else if (!runtime->device.IsBlitDepthStencilSupported() &&
1188 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { 1197 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
1189 scale_framebuffer = std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent); 1198 if (!scale_framebuffer) {
1199 scale_framebuffer =
1200 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1201 }
1190 runtime->blit_image_helper.BlitDepthStencil( 1202 runtime->blit_image_helper.BlitDepthStencil(
1191 scale_framebuffer.get(), scale_view->DepthView(), scale_view->StencilView(), 1203 scale_framebuffer.get(), scale_view->DepthView(), scale_view->StencilView(),
1192 dst_region, src_region, Tegra::Engines::Fermi2D::Filter::Point, BLIT_OPERATION); 1204 dst_region, src_region, Tegra::Engines::Fermi2D::Filter::Point, BLIT_OPERATION);
@@ -1209,6 +1221,67 @@ bool Image::ScaleDown() {
1209 if (!resolution.active) { 1221 if (!resolution.active) {
1210 return false; 1222 return false;
1211 } 1223 }
1224 const auto& device = runtime->device;
1225 const bool is_2d = info.type == ImageType::e2D;
1226 const u32 scaled_width = resolution.ScaleUp(info.size.width);
1227 const u32 scaled_height = is_2d ? resolution.ScaleUp(info.size.height) : info.size.height;
1228 if (aspect_mask == 0) {
1229 aspect_mask = ImageAspectMask(info.format);
1230 }
1231 static constexpr auto OPTIMAL_FORMAT = FormatType::Optimal;
1232 const PixelFormat format = StorageFormat(info.format);
1233 const auto vk_format = MaxwellToVK::SurfaceFormat(device, OPTIMAL_FORMAT, false, format).format;
1234 const auto blit_usage = VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
1235 if (device.IsFormatSupported(vk_format, blit_usage, OPTIMAL_FORMAT)) {
1236 BlitScale(*scheduler, *scaled_image, *original_image, info, aspect_mask, resolution, false);
1237 } else {
1238 using namespace VideoCommon;
1239 static constexpr auto BLIT_OPERATION = Tegra::Engines::Fermi2D::Operation::SrcCopy;
1240
1241 if (!normal_view) {
1242 const auto view_info = ImageViewInfo(ImageViewType::e2D, info.format);
1243 normal_view = std::make_unique<ImageView>(*runtime, view_info, NULL_IMAGE_ID, *this);
1244 }
1245 auto* view_ptr = normal_view.get();
1246
1247 const Region2D src_region{
1248 .start = {0, 0},
1249 .end = {static_cast<s32>(scaled_width), static_cast<s32>(scaled_height)},
1250 };
1251 const Region2D dst_region{
1252 .start = {0, 0},
1253 .end = {static_cast<s32>(info.size.width), static_cast<s32>(info.size.height)},
1254 };
1255 const VkExtent2D extent{
1256 .width = scaled_width,
1257 .height = scaled_height,
1258 };
1259 if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
1260 if (!normal_framebuffer) {
1261 normal_framebuffer =
1262 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1263 }
1264 const auto color_view = normal_view->Handle(Shader::TextureType::Color2D);
1265
1266 runtime->blit_image_helper.BlitColor(
1267 normal_framebuffer.get(), color_view, dst_region, src_region,
1268 Tegra::Engines::Fermi2D::Filter::Bilinear, BLIT_OPERATION);
1269 } else if (!runtime->device.IsBlitDepthStencilSupported() &&
1270 aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
1271 if (!normal_framebuffer) {
1272 normal_framebuffer =
1273 std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
1274 }
1275 runtime->blit_image_helper.BlitDepthStencil(
1276 normal_framebuffer.get(), normal_view->DepthView(), normal_view->StencilView(),
1277 dst_region, src_region, Tegra::Engines::Fermi2D::Filter::Point, BLIT_OPERATION);
1278 } else {
1279 // TODO: Use helper blits where applicable
1280 flags &= ~ImageFlagBits::Rescaled;
1281 LOG_ERROR(Render_Vulkan, "Device does not support scaling format {}", format);
1282 return false;
1283 }
1284 }
1212 ASSERT(info.type != ImageType::Linear); 1285 ASSERT(info.type != ImageType::Linear);
1213 current_image = *original_image; 1286 current_image = *original_image;
1214 return true; 1287 return true;
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 6dc190632..df854a20c 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -148,6 +148,9 @@ private:
148 148
149 std::unique_ptr<Framebuffer> scale_framebuffer; 149 std::unique_ptr<Framebuffer> scale_framebuffer;
150 std::unique_ptr<ImageView> scale_view; 150 std::unique_ptr<ImageView> scale_view;
151
152 std::unique_ptr<Framebuffer> normal_framebuffer;
153 std::unique_ptr<ImageView> normal_view;
151}; 154};
152 155
153class ImageView : public VideoCommon::ImageViewBase { 156class ImageView : public VideoCommon::ImageViewBase {
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp
index 1909c9ecb..3db2ec825 100644
--- a/src/video_core/texture_cache/image_base.cpp
+++ b/src/video_core/texture_cache/image_base.cpp
@@ -60,8 +60,8 @@ namespace {
60ImageBase::ImageBase(const ImageInfo& info_, GPUVAddr gpu_addr_, VAddr cpu_addr_) 60ImageBase::ImageBase(const ImageInfo& info_, GPUVAddr gpu_addr_, VAddr cpu_addr_)
61 : info{info_}, guest_size_bytes{CalculateGuestSizeInBytes(info)}, 61 : info{info_}, guest_size_bytes{CalculateGuestSizeInBytes(info)},
62 unswizzled_size_bytes{CalculateUnswizzledSizeBytes(info)}, 62 unswizzled_size_bytes{CalculateUnswizzledSizeBytes(info)},
63 converted_size_bytes{CalculateConvertedSizeBytes(info)}, scale_rating{}, 63 converted_size_bytes{CalculateConvertedSizeBytes(info)}, scale_rating{}, scale_tick{},
64 scale_tick{}, gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_}, 64 scale_count{}, gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_},
65 cpu_addr_end{cpu_addr + guest_size_bytes}, mip_level_offsets{CalculateMipLevelOffsets(info)} { 65 cpu_addr_end{cpu_addr + guest_size_bytes}, mip_level_offsets{CalculateMipLevelOffsets(info)} {
66 if (info.type == ImageType::e3D) { 66 if (info.type == ImageType::e3D) {
67 slice_offsets = CalculateSliceOffsets(info); 67 slice_offsets = CalculateSliceOffsets(info);
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index bab290ac7..cd4b5f636 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -77,6 +77,10 @@ struct ImageBase {
77 void CheckBadOverlapState(); 77 void CheckBadOverlapState();
78 void CheckAliasState(); 78 void CheckAliasState();
79 79
80 bool HasScaled() {
81 return scale_count > 0;
82 }
83
80 ImageInfo info; 84 ImageInfo info;
81 85
82 u32 guest_size_bytes = 0; 86 u32 guest_size_bytes = 0;
@@ -84,6 +88,7 @@ struct ImageBase {
84 u32 converted_size_bytes = 0; 88 u32 converted_size_bytes = 0;
85 u32 scale_rating = 0; 89 u32 scale_rating = 0;
86 u64 scale_tick = 0; 90 u64 scale_tick = 0;
91 u32 scale_count = 0;
87 ImageFlagBits flags = ImageFlagBits::CpuModified; 92 ImageFlagBits flags = ImageFlagBits::CpuModified;
88 93
89 GPUVAddr gpu_addr = 0; 94 GPUVAddr gpu_addr = 0;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index a035d2b18..cf0d33a45 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -854,8 +854,8 @@ void TextureCache<P>::InvalidateScale(Image& image) {
854} 854}
855 855
856template <class P> 856template <class P>
857u64 TextureCache<P>::GetScaledImageSizeBytes(Image& image) { 857u64 TextureCache<P>::GetScaledImageSizeBytes(ImageBase& image) {
858 const f32 add_to_size = Settings::values.resolution_info.up_factor - 1.0f; 858 const f32 add_to_size = Settings::values.resolution_info.up_factor;
859 const bool sign = std::signbit(add_to_size); 859 const bool sign = std::signbit(add_to_size);
860 const u32 image_size_bytes = std::max(image.guest_size_bytes, image.unswizzled_size_bytes); 860 const u32 image_size_bytes = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
861 const u64 tentative_size = image_size_bytes * static_cast<u64>(std::abs(add_to_size)); 861 const u64 tentative_size = image_size_bytes * static_cast<u64>(std::abs(add_to_size));
@@ -865,11 +865,14 @@ u64 TextureCache<P>::GetScaledImageSizeBytes(Image& image) {
865 865
866template <class P> 866template <class P>
867bool TextureCache<P>::ScaleUp(Image& image) { 867bool TextureCache<P>::ScaleUp(Image& image) {
868 const bool has_copy = image.HasScaled();
868 const bool rescaled = image.ScaleUp(); 869 const bool rescaled = image.ScaleUp();
869 if (!rescaled) { 870 if (!rescaled) {
870 return false; 871 return false;
871 } 872 }
872 total_used_memory += GetScaledImageSizeBytes(image); 873 if (!has_copy) {
874 total_used_memory += GetScaledImageSizeBytes(image);
875 }
873 InvalidateScale(image); 876 InvalidateScale(image);
874 return true; 877 return true;
875} 878}
@@ -880,7 +883,10 @@ bool TextureCache<P>::ScaleDown(Image& image) {
880 if (!rescaled) { 883 if (!rescaled) {
881 return false; 884 return false;
882 } 885 }
883 total_used_memory -= GetScaledImageSizeBytes(image); 886 const bool has_copy = image.HasScaled();
887 if (!has_copy) {
888 total_used_memory -= GetScaledImageSizeBytes(image);
889 }
884 InvalidateScale(image); 890 InvalidateScale(image);
885 return true; 891 return true;
886} 892}
@@ -1391,13 +1397,6 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
1391 "Trying to unregister an already registered image"); 1397 "Trying to unregister an already registered image");
1392 image.flags &= ~ImageFlagBits::Registered; 1398 image.flags &= ~ImageFlagBits::Registered;
1393 image.flags &= ~ImageFlagBits::BadOverlap; 1399 image.flags &= ~ImageFlagBits::BadOverlap;
1394 u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
1395 if ((IsPixelFormatASTC(image.info.format) &&
1396 True(image.flags & ImageFlagBits::AcceleratedUpload)) ||
1397 True(image.flags & ImageFlagBits::Converted)) {
1398 tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
1399 }
1400 total_used_memory -= Common::AlignUp(tentative_size, 1024);
1401 lru_cache.Free(image.lru_index); 1400 lru_cache.Free(image.lru_index);
1402 const auto& clear_page_table = 1401 const auto& clear_page_table =
1403 [this, image_id]( 1402 [this, image_id](
@@ -1478,6 +1477,16 @@ template <class P>
1478void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) { 1477void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) {
1479 ASSERT(False(image.flags & ImageFlagBits::Tracked)); 1478 ASSERT(False(image.flags & ImageFlagBits::Tracked));
1480 image.flags |= ImageFlagBits::Tracked; 1479 image.flags |= ImageFlagBits::Tracked;
1480 if (image.HasScaled()) {
1481 total_used_memory -= GetScaledImageSizeBytes(image);
1482 }
1483 u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
1484 if ((IsPixelFormatASTC(image.info.format) &&
1485 True(image.flags & ImageFlagBits::AcceleratedUpload)) ||
1486 True(image.flags & ImageFlagBits::Converted)) {
1487 tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
1488 }
1489 total_used_memory -= Common::AlignUp(tentative_size, 1024);
1481 if (False(image.flags & ImageFlagBits::Sparse)) { 1490 if (False(image.flags & ImageFlagBits::Sparse)) {
1482 rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1); 1491 rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1);
1483 return; 1492 return;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 4dbe050af..e210393ba 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -331,7 +331,7 @@ private:
331 void InvalidateScale(Image& image); 331 void InvalidateScale(Image& image);
332 bool ScaleUp(Image& image); 332 bool ScaleUp(Image& image);
333 bool ScaleDown(Image& image); 333 bool ScaleDown(Image& image);
334 u64 GetScaledImageSizeBytes(Image& image); 334 u64 GetScaledImageSizeBytes(ImageBase& image);
335 335
336 Runtime& runtime; 336 Runtime& runtime;
337 VideoCore::RasterizerInterface& rasterizer; 337 VideoCore::RasterizerInterface& rasterizer;