diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 43 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 93 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 3 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.h | 5 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 31 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 2 |
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 | ||
| 879 | bool Image::Scale() { | 879 | bool 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 | ||
| 594 | void BlitScale(VKScheduler& scheduler, VkImage src_image, VkImage dst_image, const ImageInfo& info, | 594 | void 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 | ||
| 153 | class ImageView : public VideoCommon::ImageViewBase { | 156 | class 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 { | |||
| 60 | ImageBase::ImageBase(const ImageInfo& info_, GPUVAddr gpu_addr_, VAddr cpu_addr_) | 60 | ImageBase::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 | ||
| 856 | template <class P> | 856 | template <class P> |
| 857 | u64 TextureCache<P>::GetScaledImageSizeBytes(Image& image) { | 857 | u64 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 | ||
| 866 | template <class P> | 866 | template <class P> |
| 867 | bool TextureCache<P>::ScaleUp(Image& image) { | 867 | bool 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> | |||
| 1478 | void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) { | 1477 | void 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; |