diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 23 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 4 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/texture_cache/image_base.h | 6 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 22 |
7 files changed, 57 insertions, 28 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 34d3723e5..a6e9eb60b 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -697,7 +697,7 @@ void Image::UploadMemory(const ImageBufferMap& map, | |||
| 697 | std::span<const VideoCommon::BufferImageCopy> copies) { | 697 | std::span<const VideoCommon::BufferImageCopy> copies) { |
| 698 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | 698 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); |
| 699 | if (is_rescaled) { | 699 | if (is_rescaled) { |
| 700 | ScaleDown(); | 700 | ScaleDown(true); |
| 701 | } | 701 | } |
| 702 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, map.buffer); | 702 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, map.buffer); |
| 703 | glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, map.offset, unswizzled_size_bytes); | 703 | glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, map.offset, unswizzled_size_bytes); |
| @@ -725,6 +725,10 @@ void Image::UploadMemory(const ImageBufferMap& map, | |||
| 725 | 725 | ||
| 726 | void Image::DownloadMemory(ImageBufferMap& map, | 726 | void Image::DownloadMemory(ImageBufferMap& map, |
| 727 | std::span<const VideoCommon::BufferImageCopy> copies) { | 727 | std::span<const VideoCommon::BufferImageCopy> copies) { |
| 728 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | ||
| 729 | if (is_rescaled) { | ||
| 730 | ScaleDown(); | ||
| 731 | } | ||
| 728 | glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API | 732 | glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API |
| 729 | glBindBuffer(GL_PIXEL_PACK_BUFFER, map.buffer); | 733 | glBindBuffer(GL_PIXEL_PACK_BUFFER, map.buffer); |
| 730 | glPixelStorei(GL_PACK_ALIGNMENT, 1); | 734 | glPixelStorei(GL_PACK_ALIGNMENT, 1); |
| @@ -743,6 +747,9 @@ void Image::DownloadMemory(ImageBufferMap& map, | |||
| 743 | } | 747 | } |
| 744 | CopyImageToBuffer(copy, map.offset); | 748 | CopyImageToBuffer(copy, map.offset); |
| 745 | } | 749 | } |
| 750 | if (is_rescaled) { | ||
| 751 | ScaleUp(true); | ||
| 752 | } | ||
| 746 | } | 753 | } |
| 747 | 754 | ||
| 748 | GLuint Image::StorageHandle() noexcept { | 755 | GLuint Image::StorageHandle() noexcept { |
| @@ -979,7 +986,7 @@ bool Image::Scale(bool up_scale) { | |||
| 979 | return true; | 986 | return true; |
| 980 | } | 987 | } |
| 981 | 988 | ||
| 982 | bool Image::ScaleUp() { | 989 | bool Image::ScaleUp(bool ignore) { |
| 983 | if (True(flags & ImageFlagBits::Rescaled)) { | 990 | if (True(flags & ImageFlagBits::Rescaled)) { |
| 984 | return false; | 991 | return false; |
| 985 | } | 992 | } |
| @@ -997,7 +1004,11 @@ bool Image::ScaleUp() { | |||
| 997 | flags &= ~ImageFlagBits::Rescaled; | 1004 | flags &= ~ImageFlagBits::Rescaled; |
| 998 | return false; | 1005 | return false; |
| 999 | } | 1006 | } |
| 1000 | scale_count++; | 1007 | has_scaled = true; |
| 1008 | if (ignore) { | ||
| 1009 | current_texture = upscaled_backup.handle; | ||
| 1010 | return true; | ||
| 1011 | } | ||
| 1001 | if (!Scale()) { | 1012 | if (!Scale()) { |
| 1002 | flags &= ~ImageFlagBits::Rescaled; | 1013 | flags &= ~ImageFlagBits::Rescaled; |
| 1003 | return false; | 1014 | return false; |
| @@ -1005,7 +1016,7 @@ bool Image::ScaleUp() { | |||
| 1005 | return true; | 1016 | return true; |
| 1006 | } | 1017 | } |
| 1007 | 1018 | ||
| 1008 | bool Image::ScaleDown() { | 1019 | bool Image::ScaleDown(bool ignore) { |
| 1009 | if (False(flags & ImageFlagBits::Rescaled)) { | 1020 | if (False(flags & ImageFlagBits::Rescaled)) { |
| 1010 | return false; | 1021 | return false; |
| 1011 | } | 1022 | } |
| @@ -1013,7 +1024,10 @@ bool Image::ScaleDown() { | |||
| 1013 | if (!runtime->resolution.active) { | 1024 | if (!runtime->resolution.active) { |
| 1014 | return false; | 1025 | return false; |
| 1015 | } | 1026 | } |
| 1016 | scale_count++; | 1027 | if (ignore) { |
| 1028 | current_texture = texture.handle; | ||
| 1029 | return true; | ||
| 1030 | } | ||
| 1017 | if (!Scale(false)) { | 1031 | if (!Scale(false)) { |
| 1018 | flags &= ~ImageFlagBits::Rescaled; | 1032 | flags &= ~ImageFlagBits::Rescaled; |
| 1019 | return false; | 1033 | return false; |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 81aaef3da..eeb5133d5 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -196,9 +196,9 @@ public: | |||
| 196 | return gl_type; | 196 | return gl_type; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | bool ScaleUp(); | 199 | bool ScaleUp(bool ignore = false); |
| 200 | 200 | ||
| 201 | bool ScaleDown(); | 201 | bool ScaleDown(bool ignore = false); |
| 202 | 202 | ||
| 203 | private: | 203 | private: |
| 204 | void CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); | 204 | void CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 51367c01d..02aac3b98 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -1055,7 +1055,7 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag | |||
| 1055 | // TODO: Move this to another API | 1055 | // TODO: Move this to another API |
| 1056 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | 1056 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); |
| 1057 | if (is_rescaled) { | 1057 | if (is_rescaled) { |
| 1058 | ScaleDown(); | 1058 | ScaleDown(true); |
| 1059 | } | 1059 | } |
| 1060 | scheduler->RequestOutsideRenderPassOperationContext(); | 1060 | scheduler->RequestOutsideRenderPassOperationContext(); |
| 1061 | std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); | 1061 | std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); |
| @@ -1073,6 +1073,10 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag | |||
| 1073 | } | 1073 | } |
| 1074 | 1074 | ||
| 1075 | void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { | 1075 | void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { |
| 1076 | const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); | ||
| 1077 | if (is_rescaled) { | ||
| 1078 | ScaleDown(); | ||
| 1079 | } | ||
| 1076 | std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); | 1080 | std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask); |
| 1077 | scheduler->RequestOutsideRenderPassOperationContext(); | 1081 | scheduler->RequestOutsideRenderPassOperationContext(); |
| 1078 | scheduler->Record([buffer = map.buffer, image = *original_image, aspect_mask = aspect_mask, | 1082 | scheduler->Record([buffer = map.buffer, image = *original_image, aspect_mask = aspect_mask, |
| @@ -1125,9 +1129,12 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm | |||
| 1125 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | 1129 | cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
| 1126 | 0, memory_write_barrier, nullptr, image_write_barrier); | 1130 | 0, memory_write_barrier, nullptr, image_write_barrier); |
| 1127 | }); | 1131 | }); |
| 1132 | if (is_rescaled) { | ||
| 1133 | ScaleUp(true); | ||
| 1134 | } | ||
| 1128 | } | 1135 | } |
| 1129 | 1136 | ||
| 1130 | bool Image::ScaleUp() { | 1137 | bool Image::ScaleUp(bool ignore) { |
| 1131 | if (True(flags & ImageFlagBits::Rescaled)) { | 1138 | if (True(flags & ImageFlagBits::Rescaled)) { |
| 1132 | return false; | 1139 | return false; |
| 1133 | } | 1140 | } |
| @@ -1137,7 +1144,7 @@ bool Image::ScaleUp() { | |||
| 1137 | if (!resolution.active) { | 1144 | if (!resolution.active) { |
| 1138 | return false; | 1145 | return false; |
| 1139 | } | 1146 | } |
| 1140 | scale_count++; | 1147 | has_scaled = true; |
| 1141 | const auto& device = runtime->device; | 1148 | const auto& device = runtime->device; |
| 1142 | const bool is_2d = info.type == ImageType::e2D; | 1149 | const bool is_2d = info.type == ImageType::e2D; |
| 1143 | const u32 scaled_width = resolution.ScaleUp(info.size.width); | 1150 | const u32 scaled_width = resolution.ScaleUp(info.size.width); |
| @@ -1149,8 +1156,12 @@ bool Image::ScaleUp() { | |||
| 1149 | scaled_image = MakeImage(device, scaled_info); | 1156 | scaled_image = MakeImage(device, scaled_info); |
| 1150 | auto& allocator = runtime->memory_allocator; | 1157 | auto& allocator = runtime->memory_allocator; |
| 1151 | scaled_commit = MemoryCommit(allocator.Commit(scaled_image, MemoryUsage::DeviceLocal)); | 1158 | scaled_commit = MemoryCommit(allocator.Commit(scaled_image, MemoryUsage::DeviceLocal)); |
| 1159 | ignore = false; | ||
| 1152 | } | 1160 | } |
| 1153 | current_image = *scaled_image; | 1161 | current_image = *scaled_image; |
| 1162 | if (ignore) { | ||
| 1163 | return true; | ||
| 1164 | } | ||
| 1154 | 1165 | ||
| 1155 | if (aspect_mask == 0) { | 1166 | if (aspect_mask == 0) { |
| 1156 | aspect_mask = ImageAspectMask(info.format); | 1167 | aspect_mask = ImageAspectMask(info.format); |
| @@ -1212,7 +1223,7 @@ bool Image::ScaleUp() { | |||
| 1212 | return true; | 1223 | return true; |
| 1213 | } | 1224 | } |
| 1214 | 1225 | ||
| 1215 | bool Image::ScaleDown() { | 1226 | bool Image::ScaleDown(bool ignore) { |
| 1216 | if (False(flags & ImageFlagBits::Rescaled)) { | 1227 | if (False(flags & ImageFlagBits::Rescaled)) { |
| 1217 | return false; | 1228 | return false; |
| 1218 | } | 1229 | } |
| @@ -1221,6 +1232,10 @@ bool Image::ScaleDown() { | |||
| 1221 | if (!resolution.active) { | 1232 | if (!resolution.active) { |
| 1222 | return false; | 1233 | return false; |
| 1223 | } | 1234 | } |
| 1235 | if (ignore) { | ||
| 1236 | current_image = *original_image; | ||
| 1237 | return true; | ||
| 1238 | } | ||
| 1224 | const auto& device = runtime->device; | 1239 | const auto& device = runtime->device; |
| 1225 | const bool is_2d = info.type == ImageType::e2D; | 1240 | const bool is_2d = info.type == ImageType::e2D; |
| 1226 | const u32 scaled_width = resolution.ScaleUp(info.size.width); | 1241 | const u32 scaled_width = resolution.ScaleUp(info.size.width); |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index df854a20c..8dbddfaf7 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -129,9 +129,9 @@ public: | |||
| 129 | return std::exchange(initialized, true); | 129 | return std::exchange(initialized, true); |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | bool ScaleUp(); | 132 | bool ScaleUp(bool ignore = false); |
| 133 | 133 | ||
| 134 | bool ScaleDown(); | 134 | bool ScaleDown(bool ignore = false); |
| 135 | 135 | ||
| 136 | private: | 136 | private: |
| 137 | VKScheduler* scheduler{}; | 137 | VKScheduler* scheduler{}; |
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp index 3db2ec825..3db2fdf34 100644 --- a/src/video_core/texture_cache/image_base.cpp +++ b/src/video_core/texture_cache/image_base.cpp | |||
| @@ -61,7 +61,7 @@ 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{}, scale_tick{}, | 63 | converted_size_bytes{CalculateConvertedSizeBytes(info)}, scale_rating{}, scale_tick{}, |
| 64 | scale_count{}, gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_}, | 64 | has_scaled{}, 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 cd4b5f636..02c669766 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h | |||
| @@ -77,8 +77,8 @@ struct ImageBase { | |||
| 77 | void CheckBadOverlapState(); | 77 | void CheckBadOverlapState(); |
| 78 | void CheckAliasState(); | 78 | void CheckAliasState(); |
| 79 | 79 | ||
| 80 | bool HasScaled() { | 80 | bool HasScaled() const { |
| 81 | return scale_count > 0; | 81 | return has_scaled; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | ImageInfo info; | 84 | ImageInfo info; |
| @@ -88,7 +88,7 @@ struct ImageBase { | |||
| 88 | u32 converted_size_bytes = 0; | 88 | u32 converted_size_bytes = 0; |
| 89 | u32 scale_rating = 0; | 89 | u32 scale_rating = 0; |
| 90 | u64 scale_tick = 0; | 90 | u64 scale_tick = 0; |
| 91 | u32 scale_count = 0; | 91 | bool has_scaled = false; |
| 92 | ImageFlagBits flags = ImageFlagBits::CpuModified; | 92 | ImageFlagBits flags = ImageFlagBits::CpuModified; |
| 93 | 93 | ||
| 94 | 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 c885586e8..13914dc8b 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -60,7 +60,7 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& | |||
| 60 | // On OpenGL we can be more conservatives as the driver takes care. | 60 | // On OpenGL we can be more conservatives as the driver takes care. |
| 61 | expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB; | 61 | expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB; |
| 62 | critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB; | 62 | critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB; |
| 63 | minimum_memory = expected_memory; | 63 | minimum_memory = 0; |
| 64 | } | 64 | } |
| 65 | } | 65 | } |
| 66 | 66 | ||
| @@ -1464,16 +1464,6 @@ template <class P> | |||
| 1464 | void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) { | 1464 | void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) { |
| 1465 | ASSERT(False(image.flags & ImageFlagBits::Tracked)); | 1465 | ASSERT(False(image.flags & ImageFlagBits::Tracked)); |
| 1466 | image.flags |= ImageFlagBits::Tracked; | 1466 | image.flags |= ImageFlagBits::Tracked; |
| 1467 | if (image.HasScaled()) { | ||
| 1468 | total_used_memory -= GetScaledImageSizeBytes(image); | ||
| 1469 | } | ||
| 1470 | u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes); | ||
| 1471 | if ((IsPixelFormatASTC(image.info.format) && | ||
| 1472 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || | ||
| 1473 | True(image.flags & ImageFlagBits::Converted)) { | ||
| 1474 | tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); | ||
| 1475 | } | ||
| 1476 | total_used_memory -= Common::AlignUp(tentative_size, 1024); | ||
| 1477 | if (False(image.flags & ImageFlagBits::Sparse)) { | 1467 | if (False(image.flags & ImageFlagBits::Sparse)) { |
| 1478 | rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1); | 1468 | rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1); |
| 1479 | return; | 1469 | return; |
| @@ -1519,6 +1509,16 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) { | |||
| 1519 | template <class P> | 1509 | template <class P> |
| 1520 | void TextureCache<P>::DeleteImage(ImageId image_id) { | 1510 | void TextureCache<P>::DeleteImage(ImageId image_id) { |
| 1521 | ImageBase& image = slot_images[image_id]; | 1511 | ImageBase& image = slot_images[image_id]; |
| 1512 | if (image.HasScaled()) { | ||
| 1513 | total_used_memory -= GetScaledImageSizeBytes(image); | ||
| 1514 | } | ||
| 1515 | u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes); | ||
| 1516 | if ((IsPixelFormatASTC(image.info.format) && | ||
| 1517 | True(image.flags & ImageFlagBits::AcceleratedUpload)) || | ||
| 1518 | True(image.flags & ImageFlagBits::Converted)) { | ||
| 1519 | tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format); | ||
| 1520 | } | ||
| 1521 | total_used_memory -= Common::AlignUp(tentative_size, 1024); | ||
| 1522 | const GPUVAddr gpu_addr = image.gpu_addr; | 1522 | const GPUVAddr gpu_addr = image.gpu_addr; |
| 1523 | const auto alloc_it = image_allocs_table.find(gpu_addr); | 1523 | const auto alloc_it = image_allocs_table.find(gpu_addr); |
| 1524 | if (alloc_it == image_allocs_table.end()) { | 1524 | if (alloc_it == image_allocs_table.end()) { |