summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp24
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp23
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h4
-rw-r--r--src/video_core/texture_cache/image_base.cpp2
-rw-r--r--src/video_core/texture_cache/image_base.h6
-rw-r--r--src/video_core/texture_cache/texture_cache.h22
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
726void Image::DownloadMemory(ImageBufferMap& map, 726void 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
748GLuint Image::StorageHandle() noexcept { 755GLuint Image::StorageHandle() noexcept {
@@ -979,7 +986,7 @@ bool Image::Scale(bool up_scale) {
979 return true; 986 return true;
980} 987}
981 988
982bool Image::ScaleUp() { 989bool 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
1008bool Image::ScaleDown() { 1019bool 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
203private: 203private:
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
1075void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) { 1075void 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
1130bool Image::ScaleUp() { 1137bool 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
1215bool Image::ScaleDown() { 1226bool 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
136private: 136private:
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>
1464void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) { 1464void 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) {
1519template <class P> 1509template <class P>
1520void TextureCache<P>::DeleteImage(ImageId image_id) { 1510void 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()) {