summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2021-10-18 22:56:36 +0200
committerFernando Sahmkow <fsahmkow27@gmail.com>2021-11-16 22:11:31 +0100
commit3b61de74e6dc7526ffa8f03c21d81e2c3566ce90 (patch)
tree4f97e24ed00d7e46564e6aa8ecd3c05d6f6525ff
parentTexture Cache: ease the requirements of textures being blacklisted. (diff)
downloadyuzu-3b61de74e6dc7526ffa8f03c21d81e2c3566ce90.tar
yuzu-3b61de74e6dc7526ffa8f03c21d81e2c3566ce90.tar.gz
yuzu-3b61de74e6dc7526ffa8f03c21d81e2c3566ce90.tar.bz2
yuzu-3b61de74e6dc7526ffa8f03c21d81e2c3566ce90.tar.lz
yuzu-3b61de74e6dc7526ffa8f03c21d81e2c3566ce90.tar.xz
yuzu-3b61de74e6dc7526ffa8f03c21d81e2c3566ce90.tar.zst
yuzu-3b61de74e6dc7526ffa8f03c21d81e2c3566ce90.zip
-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,
std::span<const VideoCommon::BufferImageCopy> copies) {
const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
if (is_rescaled) {
- ScaleDown();
+ ScaleDown(true);
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, map.buffer);
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, map.offset, unswizzled_size_bytes);
@@ -725,6 +725,10 @@ void Image::UploadMemory(const ImageBufferMap& map,
void Image::DownloadMemory(ImageBufferMap& map,
std::span<const VideoCommon::BufferImageCopy> copies) {
+ const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
+ if (is_rescaled) {
+ ScaleDown();
+ }
glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API
glBindBuffer(GL_PIXEL_PACK_BUFFER, map.buffer);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
@@ -743,6 +747,9 @@ void Image::DownloadMemory(ImageBufferMap& map,
}
CopyImageToBuffer(copy, map.offset);
}
+ if (is_rescaled) {
+ ScaleUp(true);
+ }
}
GLuint Image::StorageHandle() noexcept {
@@ -979,7 +986,7 @@ bool Image::Scale(bool up_scale) {
return true;
}
-bool Image::ScaleUp() {
+bool Image::ScaleUp(bool ignore) {
if (True(flags & ImageFlagBits::Rescaled)) {
return false;
}
@@ -997,7 +1004,11 @@ bool Image::ScaleUp() {
flags &= ~ImageFlagBits::Rescaled;
return false;
}
- scale_count++;
+ has_scaled = true;
+ if (ignore) {
+ current_texture = upscaled_backup.handle;
+ return true;
+ }
if (!Scale()) {
flags &= ~ImageFlagBits::Rescaled;
return false;
@@ -1005,7 +1016,7 @@ bool Image::ScaleUp() {
return true;
}
-bool Image::ScaleDown() {
+bool Image::ScaleDown(bool ignore) {
if (False(flags & ImageFlagBits::Rescaled)) {
return false;
}
@@ -1013,7 +1024,10 @@ bool Image::ScaleDown() {
if (!runtime->resolution.active) {
return false;
}
- scale_count++;
+ if (ignore) {
+ current_texture = texture.handle;
+ return true;
+ }
if (!Scale(false)) {
flags &= ~ImageFlagBits::Rescaled;
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:
return gl_type;
}
- bool ScaleUp();
+ bool ScaleUp(bool ignore = false);
- bool ScaleDown();
+ bool ScaleDown(bool ignore = false);
private:
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
// TODO: Move this to another API
const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
if (is_rescaled) {
- ScaleDown();
+ ScaleDown(true);
}
scheduler->RequestOutsideRenderPassOperationContext();
std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask);
@@ -1073,6 +1073,10 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag
}
void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) {
+ const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
+ if (is_rescaled) {
+ ScaleDown();
+ }
std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask);
scheduler->RequestOutsideRenderPassOperationContext();
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
cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
0, memory_write_barrier, nullptr, image_write_barrier);
});
+ if (is_rescaled) {
+ ScaleUp(true);
+ }
}
-bool Image::ScaleUp() {
+bool Image::ScaleUp(bool ignore) {
if (True(flags & ImageFlagBits::Rescaled)) {
return false;
}
@@ -1137,7 +1144,7 @@ bool Image::ScaleUp() {
if (!resolution.active) {
return false;
}
- scale_count++;
+ has_scaled = true;
const auto& device = runtime->device;
const bool is_2d = info.type == ImageType::e2D;
const u32 scaled_width = resolution.ScaleUp(info.size.width);
@@ -1149,8 +1156,12 @@ bool Image::ScaleUp() {
scaled_image = MakeImage(device, scaled_info);
auto& allocator = runtime->memory_allocator;
scaled_commit = MemoryCommit(allocator.Commit(scaled_image, MemoryUsage::DeviceLocal));
+ ignore = false;
}
current_image = *scaled_image;
+ if (ignore) {
+ return true;
+ }
if (aspect_mask == 0) {
aspect_mask = ImageAspectMask(info.format);
@@ -1212,7 +1223,7 @@ bool Image::ScaleUp() {
return true;
}
-bool Image::ScaleDown() {
+bool Image::ScaleDown(bool ignore) {
if (False(flags & ImageFlagBits::Rescaled)) {
return false;
}
@@ -1221,6 +1232,10 @@ bool Image::ScaleDown() {
if (!resolution.active) {
return false;
}
+ if (ignore) {
+ current_image = *original_image;
+ return true;
+ }
const auto& device = runtime->device;
const bool is_2d = info.type == ImageType::e2D;
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:
return std::exchange(initialized, true);
}
- bool ScaleUp();
+ bool ScaleUp(bool ignore = false);
- bool ScaleDown();
+ bool ScaleDown(bool ignore = false);
private:
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_
: info{info_}, guest_size_bytes{CalculateGuestSizeInBytes(info)},
unswizzled_size_bytes{CalculateUnswizzledSizeBytes(info)},
converted_size_bytes{CalculateConvertedSizeBytes(info)}, scale_rating{}, scale_tick{},
- scale_count{}, gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_},
+ has_scaled{}, gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_},
cpu_addr_end{cpu_addr + guest_size_bytes}, mip_level_offsets{CalculateMipLevelOffsets(info)} {
if (info.type == ImageType::e3D) {
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 {
void CheckBadOverlapState();
void CheckAliasState();
- bool HasScaled() {
- return scale_count > 0;
+ bool HasScaled() const {
+ return has_scaled;
}
ImageInfo info;
@@ -88,7 +88,7 @@ struct ImageBase {
u32 converted_size_bytes = 0;
u32 scale_rating = 0;
u64 scale_tick = 0;
- u32 scale_count = 0;
+ bool has_scaled = false;
ImageFlagBits flags = ImageFlagBits::CpuModified;
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&
// On OpenGL we can be more conservatives as the driver takes care.
expected_memory = DEFAULT_EXPECTED_MEMORY + 512_MiB;
critical_memory = DEFAULT_CRITICAL_MEMORY + 1_GiB;
- minimum_memory = expected_memory;
+ minimum_memory = 0;
}
}
@@ -1464,16 +1464,6 @@ template <class P>
void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) {
ASSERT(False(image.flags & ImageFlagBits::Tracked));
image.flags |= ImageFlagBits::Tracked;
- if (image.HasScaled()) {
- total_used_memory -= GetScaledImageSizeBytes(image);
- }
- u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
- if ((IsPixelFormatASTC(image.info.format) &&
- True(image.flags & ImageFlagBits::AcceleratedUpload)) ||
- True(image.flags & ImageFlagBits::Converted)) {
- tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
- }
- total_used_memory -= Common::AlignUp(tentative_size, 1024);
if (False(image.flags & ImageFlagBits::Sparse)) {
rasterizer.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1);
return;
@@ -1519,6 +1509,16 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) {
template <class P>
void TextureCache<P>::DeleteImage(ImageId image_id) {
ImageBase& image = slot_images[image_id];
+ if (image.HasScaled()) {
+ total_used_memory -= GetScaledImageSizeBytes(image);
+ }
+ u64 tentative_size = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
+ if ((IsPixelFormatASTC(image.info.format) &&
+ True(image.flags & ImageFlagBits::AcceleratedUpload)) ||
+ True(image.flags & ImageFlagBits::Converted)) {
+ tentative_size = EstimatedDecompressedSize(tentative_size, image.info.format);
+ }
+ total_used_memory -= Common::AlignUp(tentative_size, 1024);
const GPUVAddr gpu_addr = image.gpu_addr;
const auto alloc_it = image_allocs_table.find(gpu_addr);
if (alloc_it == image_allocs_table.end()) {