From 22f4b290b6f0894d29302102f539dd8753961f04 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 18 Jul 2021 18:40:14 +0200 Subject: VideoCore: Initial Setup for the Resolution Scaler. --- src/video_core/texture_cache/image_base.h | 4 + src/video_core/texture_cache/image_info.h | 2 +- src/video_core/texture_cache/texture_cache.h | 113 +++++++++++++++++++++- src/video_core/texture_cache/texture_cache_base.h | 10 ++ 4 files changed, 126 insertions(+), 3 deletions(-) (limited to 'src/video_core/texture_cache') diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h index 0c17a791b..1cd30fd37 100644 --- a/src/video_core/texture_cache/image_base.h +++ b/src/video_core/texture_cache/image_base.h @@ -33,6 +33,10 @@ enum class ImageFlagBits : u32 { ///< garbage collection priority Alias = 1 << 11, ///< This image has aliases and has priority on garbage ///< collection + + // Rescaler + Rescaled = 1 << 12, + RescaleChecked = 1 << 13, }; DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h index 5049fc36e..16d4cee37 100644 --- a/src/video_core/texture_cache/image_info.h +++ b/src/video_core/texture_cache/image_info.h @@ -15,7 +15,7 @@ using Tegra::Texture::TICEntry; using VideoCore::Surface::PixelFormat; struct ImageInfo { - explicit ImageInfo() = default; + ImageInfo() = default; explicit ImageInfo(const TICEntry& config) noexcept; explicit ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept; explicit ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index f70c1f764..560da4f16 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -35,6 +35,7 @@ TextureCache
::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& Tegra::MemoryManager& gpu_memory_) : runtime{runtime_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_}, kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_} { + runtime.Init(); // Configure null sampler TSCEntry sampler_descriptor{}; sampler_descriptor.min_filter.Assign(Tegra::Texture::TextureFilter::Linear); @@ -103,6 +104,7 @@ void TextureCache
::TickFrame() { sentenced_images.Tick(); sentenced_framebuffers.Tick(); sentenced_image_view.Tick(); + runtime.TickFrame(); ++frame_tick; } @@ -208,18 +210,63 @@ void TextureCache
::UpdateRenderTargets(bool is_clear) {
const bool force = flags[Dirty::RenderTargetControl];
flags[Dirty::RenderTargetControl] = false;
+ bool can_rescale = true;
+ std::array ::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
return image_id;
}
+template ::ImageCanRescale(Image& image) {
+ if (True(image.flags & ImageFlagBits::Rescaled) ||
+ True(image.flags & ImageFlagBits::RescaleChecked)) {
+ return true;
+ }
+ const auto& info = image.info;
+ const bool can_this_rescale =
+ (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
+ if (!can_this_rescale) {
+ image.flags &= ~ImageFlagBits::RescaleChecked;
+ return false;
+ }
+ image.flags |= ImageFlagBits::RescaleChecked;
+ for (const auto& alias : image.aliased_images) {
+ Image& other_image = slot_images[alias.id];
+ if (!ImageCanRescale(other_image)) {
+ image.flags &= ~ImageFlagBits::RescaleChecked;
+ return false;
+ }
+ }
+ image.flags &= ~ImageFlagBits::RescaleChecked;
+ return true;
+}
+
template ::InsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
RelaxedOptions options) {
@@ -660,12 +732,18 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
std::vector ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
cpu_addr = solution->cpu_addr;
new_info.resources = solution->resources;
overlap_ids.push_back(overlap_id);
+ all_siblings.push_back(overlap_id);
return;
}
static constexpr auto options = RelaxedOptions::Size | RelaxedOptions::Format;
@@ -688,10 +767,12 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
if (IsSubresource(new_info, overlap, gpu_addr, options, broken_views, native_bgr)) {
left_aliased_ids.push_back(overlap_id);
overlap.flags |= ImageFlagBits::Alias;
+ all_siblings.push_back(overlap_id);
} else if (IsSubresource(overlap.info, new_image_base, overlap.gpu_addr, options,
broken_views, native_bgr)) {
right_aliased_ids.push_back(overlap_id);
overlap.flags |= ImageFlagBits::Alias;
+ all_siblings.push_back(overlap_id);
} else {
bad_overlap_ids.push_back(overlap_id);
overlap.flags |= ImageFlagBits::BadOverlap;
@@ -709,8 +790,36 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
}
};
ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu);
+
+ bool can_rescale =
+ (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
+ for (const ImageId sibling_id : all_siblings) {
+ if (!can_rescale) {
+ break;
+ }
+ Image& sibling = slot_images[sibling_id];
+ can_rescale &= ImageCanRescale(sibling);
+ }
+
+ if (can_rescale) {
+ for (const ImageId sibling_id : all_siblings) {
+ Image& sibling = slot_images[sibling_id];
+ sibling.ScaleUp();
+ }
+ } else {
+ for (const ImageId sibling_id : all_siblings) {
+ Image& sibling = slot_images[sibling_id];
+ sibling.ScaleDown();
+ }
+ }
+
const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr);
Image& new_image = slot_images[new_image_id];
+ if (can_rescale) {
+ new_image.ScaleUp();
+ } else {
+ new_image.ScaleDown();
+ }
if (!gpu_memory.IsContinousRange(new_image.gpu_addr, new_image.guest_size_bytes)) {
new_image.flags |= ImageFlagBits::Sparse;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 2d1893c1c..a4a2c0832 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -142,6 +142,14 @@ public:
const Tegra::Engines::Fermi2D::Surface& src,
const Tegra::Engines::Fermi2D::Config& copy);
+ /// Invalidate the contents of the color buffer index
+ /// These contents become unspecified, the cache can assume aggressive optimizations.
+ void InvalidateColorBuffer(size_t index);
+
+ /// Invalidate the contents of the depth buffer
+ /// These contents become unspecified, the cache can assume aggressive optimizations.
+ void InvalidateDepthBuffer();
+
/// Try to find a cached image view in the given CPU address
[[nodiscard]] ImageView* TryFindFramebufferImageView(VAddr cpu_addr);
@@ -318,6 +326,8 @@ private:
/// Returns true if the current clear parameters clear the whole image of a given image view
[[nodiscard]] bool IsFullClear(ImageViewId id);
+ bool ImageCanRescale(Image& image);
+
Runtime& runtime;
VideoCore::RasterizerInterface& rasterizer;
Tegra::Engines::Maxwell3D& maxwell3d;
--
cgit v1.2.3
From ba18047e8d06584de0ce18cdbb303a6d9a8742aa Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Mon, 19 Jul 2021 04:32:03 +0200
Subject: Texture Cache: Implement Vulkan UpScaling & DownScaling
---
src/video_core/texture_cache/image_info.cpp | 3 +
src/video_core/texture_cache/texture_cache.h | 84 +++++++++++++++++++----
src/video_core/texture_cache/texture_cache_base.h | 3 +
3 files changed, 77 insertions(+), 13 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 64fd7010a..022ca9033 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -41,6 +41,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
ASSERT(config.BaseLayer() == 0);
type = ImageType::e1D;
size.width = config.Width();
+ resources.layers = 1;
break;
case TextureType::Texture1DArray:
UNIMPLEMENTED_IF(config.BaseLayer() != 0);
@@ -82,10 +83,12 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
size.width = config.Width();
size.height = config.Height();
size.depth = config.Depth();
+ resources.layers = 1;
break;
case TextureType::Texture1DBuffer:
type = ImageType::Buffer;
size.width = config.Width();
+ resources.layers = 1;
break;
default:
UNREACHABLE_MSG("Invalid texture_type={}", static_cast ::UpdateRenderTargets(bool is_clear) {
const auto scale_up = [this](ImageId image_id) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
- image.ScaleUp();
+ return ScaleUp(image);
}
+ return false;
};
for (size_t index = 0; index < NUM_RT; ++index) {
- scale_up(tmp_color_images[index]);
+ if (scale_up(tmp_color_images[index])) {
+ BindRenderTarget(&render_targets.color_buffer_ids[index],
+ FindColorBuffer(index, is_clear));
+ }
+ }
+ if (scale_up(tmp_depth_image)) {
+ BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
}
- scale_up(tmp_depth_image);
} else {
const auto scale_down = [this](ImageId image_id) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
- image.ScaleDown();
+ return ScaleDown(image);
}
+ return false;
};
for (size_t index = 0; index < NUM_RT; ++index) {
- scale_down(tmp_color_images[index]);
+ if (scale_down(tmp_color_images[index])) {
+ BindRenderTarget(&render_targets.color_buffer_ids[index],
+ FindColorBuffer(index, is_clear));
+ }
+ }
+ if (scale_down(tmp_depth_image)) {
+ BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
}
- scale_down(tmp_depth_image);
}
// Rescale End
@@ -695,6 +707,47 @@ bool TextureCache ::ImageCanRescale(Image& image) {
return true;
}
+template ::InvalidateScale(Image& image, bool invalidate_rt) {
+ const std::span ::ScaleUp(Image& image, bool invalidate_rt) {
+ const bool rescaled = image.ScaleUp();
+ if (!rescaled) {
+ return false;
+ }
+ InvalidateScale(image, invalidate_rt);
+ return true;
+}
+
+template ::ScaleDown(Image& image, bool invalidate_rt) {
+ const bool rescaled = image.ScaleDown();
+ if (!rescaled) {
+ return false;
+ }
+ InvalidateScale(image, invalidate_rt);
+ return true;
+}
+
template ::InsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
RelaxedOptions options) {
@@ -793,33 +846,32 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
bool can_rescale =
(info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
+ bool any_rescaled = false;
for (const ImageId sibling_id : all_siblings) {
if (!can_rescale) {
break;
}
Image& sibling = slot_images[sibling_id];
can_rescale &= ImageCanRescale(sibling);
+ any_rescaled |= True(sibling.flags & ImageFlagBits::Rescaled);
}
+ can_rescale &= any_rescaled;
+
if (can_rescale) {
for (const ImageId sibling_id : all_siblings) {
Image& sibling = slot_images[sibling_id];
- sibling.ScaleUp();
+ ScaleUp(sibling, true);
}
} else {
for (const ImageId sibling_id : all_siblings) {
Image& sibling = slot_images[sibling_id];
- sibling.ScaleDown();
+ ScaleDown(sibling, true);
}
}
const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr);
Image& new_image = slot_images[new_image_id];
- if (can_rescale) {
- new_image.ScaleUp();
- } else {
- new_image.ScaleDown();
- }
if (!gpu_memory.IsContinousRange(new_image.gpu_addr, new_image.guest_size_bytes)) {
new_image.flags |= ImageFlagBits::Sparse;
@@ -840,6 +892,12 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
// TODO: Only upload what we need
RefreshContents(new_image, new_image_id);
+ if (can_rescale) {
+ new_image.ScaleUp();
+ } else {
+ new_image.ScaleDown();
+ }
+
for (const ImageId overlap_id : overlap_ids) {
Image& overlap = slot_images[overlap_id];
if (overlap.info.num_samples != new_image.info.num_samples) {
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index a4a2c0832..042678786 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -327,6 +327,9 @@ private:
[[nodiscard]] bool IsFullClear(ImageViewId id);
bool ImageCanRescale(Image& image);
+ void InvalidateScale(Image& image, bool invalidate_rt = false);
+ bool ScaleUp(Image& image, bool invalidate_rt = false);
+ bool ScaleDown(Image& image, bool invalidate_rt = false);
Runtime& runtime;
VideoCore::RasterizerInterface& rasterizer;
--
cgit v1.2.3
From 84f2aea8962146be899131b032fcdf9b4e1f6ddf Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Tue, 20 Jul 2021 07:40:05 +0200
Subject: Texture Cache: More rescaling fixes.
---
src/video_core/texture_cache/texture_cache.h | 162 +++++++++++-----------
src/video_core/texture_cache/texture_cache_base.h | 6 +-
2 files changed, 86 insertions(+), 82 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 95a9e8fe9..b7d1ae92d 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -204,75 +204,68 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
return;
}
- flags[Dirty::RenderTargets] = false;
-
- // Render target control is used on all render targets, so force look ups when this one is up
- const bool force = flags[Dirty::RenderTargetControl];
- flags[Dirty::RenderTargetControl] = false;
-
- bool can_rescale = true;
- std::array ::ImageCanRescale(Image& image) {
}
template ::InvalidateScale(Image& image, bool invalidate_rt) {
+void TextureCache ::InvalidateScale(Image& image) {
const std::span ::ScaleUp(Image& image, bool invalidate_rt) {
+bool TextureCache ::ScaleUp(Image& image) {
const bool rescaled = image.ScaleUp();
if (!rescaled) {
return false;
}
- InvalidateScale(image, invalidate_rt);
+ InvalidateScale(image);
return true;
}
template ::ScaleDown(Image& image, bool invalidate_rt) {
+bool TextureCache ::ScaleDown(Image& image) {
const bool rescaled = image.ScaleDown();
if (!rescaled) {
return false;
}
- InvalidateScale(image, invalidate_rt);
+ InvalidateScale(image);
return true;
}
@@ -861,12 +865,12 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
if (can_rescale) {
for (const ImageId sibling_id : all_siblings) {
Image& sibling = slot_images[sibling_id];
- ScaleUp(sibling, true);
+ ScaleUp(sibling);
}
} else {
for (const ImageId sibling_id : all_siblings) {
Image& sibling = slot_images[sibling_id];
- ScaleDown(sibling, true);
+ ScaleDown(sibling);
}
}
@@ -893,9 +897,9 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
RefreshContents(new_image, new_image_id);
if (can_rescale) {
- new_image.ScaleUp();
+ ScaleUp(new_image);
} else {
- new_image.ScaleDown();
+ ScaleDown(new_image);
}
for (const ImageId overlap_id : overlap_ids) {
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 042678786..cdd99242b 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -327,9 +327,9 @@ private:
[[nodiscard]] bool IsFullClear(ImageViewId id);
bool ImageCanRescale(Image& image);
- void InvalidateScale(Image& image, bool invalidate_rt = false);
- bool ScaleUp(Image& image, bool invalidate_rt = false);
- bool ScaleDown(Image& image, bool invalidate_rt = false);
+ void InvalidateScale(Image& image);
+ bool ScaleUp(Image& image);
+ bool ScaleDown(Image& image);
Runtime& runtime;
VideoCore::RasterizerInterface& rasterizer;
--
cgit v1.2.3
From 778700ff9d6eca96945deebcd4415e70d58330d9 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Tue, 20 Jul 2021 19:36:38 +0200
Subject: TextureCache: Modify Viewports/Scissors according to Rescale.
---
src/video_core/texture_cache/texture_cache.h | 25 +++++++++++++++++++++--
src/video_core/texture_cache/texture_cache_base.h | 3 +++
2 files changed, 26 insertions(+), 2 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index b7d1ae92d..4e5031acc 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -7,6 +7,7 @@
#include ::UpdateRenderTargets(bool is_clear) {
return;
}
+ bool rescaled;
do {
flags[Dirty::RenderTargets] = false;
@@ -243,6 +245,7 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
if (can_rescale) {
+ rescaled = true;
const auto scale_up = [this](ImageId image_id) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
@@ -254,6 +257,7 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
}
scale_up(tmp_depth_image);
} else {
+ rescaled = false;
const auto scale_down = [this](ImageId image_id) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
@@ -268,6 +272,12 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
} while (has_deleted_images);
// Rescale End
+ if (is_rescaling != rescaled) {
+ flags[Dirty::RescaleViewports] = true;
+ flags[Dirty::RescaleScissors] = true;
+ is_rescaling = rescaled;
+ }
+
for (size_t index = 0; index < NUM_RT; ++index) {
ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id));
@@ -279,9 +289,15 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
for (size_t index = 0; index < NUM_RT; ++index) {
render_targets.draw_buffers[index] = static_cast ::PopAsyncFlushes() {
committed_downloads.pop();
}
+template ::IsRescaling() {
+ return is_rescaling;
+}
+
template ::IsRegionGpuModified(VAddr addr, size_t size) {
bool is_modified = false;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index cdd99242b..1f51fcee8 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -168,6 +168,8 @@ public:
/// Return true when a CPU region is modified from the GPU
[[nodiscard]] bool IsRegionGpuModified(VAddr addr, size_t size);
+ [[nodiscard]] bool IsRescaling();
+
std::mutex mutex;
private:
@@ -362,6 +364,7 @@ private:
VAddr virtual_invalid_space{};
bool has_deleted_images = false;
+ bool is_rescaling = false;
u64 total_used_memory = 0;
u64 minimum_memory;
u64 expected_memory;
--
cgit v1.2.3
From 8704c939136e88876d65fc670bce98d8250a6588 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Tue, 20 Jul 2021 22:51:25 +0200
Subject: TextureCache: Fix rescaling of ImageCopies
---
src/video_core/texture_cache/texture_cache.h | 43 ++++++++++++++++++++---
src/video_core/texture_cache/texture_cache_base.h | 2 +-
2 files changed, 40 insertions(+), 5 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 4e5031acc..df697cdeb 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -929,8 +929,8 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented");
} else {
const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value();
- const auto copies = MakeShrinkImageCopies(new_info, overlap.info, base);
- runtime.CopyImage(new_image, overlap, copies);
+ auto copies = MakeShrinkImageCopies(new_info, overlap.info, base);
+ runtime.CopyImage(new_image, overlap, std::move(copies));
}
if (True(overlap.flags & ImageFlagBits::Tracked)) {
UntrackImage(overlap, overlap_id);
@@ -1569,9 +1569,33 @@ void TextureCache ::PrepareImageView(ImageViewId image_view_id, bool is_modifi
}
template ::CopyImage(ImageId dst_id, ImageId src_id, std::span ::CopyImage(ImageId dst_id, ImageId src_id, std::vector ::RenderTargetFromImage(
ImageId image_id, const ImageViewInfo& view_info) {
const ImageViewId view_id = FindOrEmplaceImageView(image_id, view_info);
const ImageBase& image = slot_images[image_id];
+ const bool is_rescaled = True(image.flags & ImageFlagBits::Rescaled);
const bool is_color = GetFormatType(image.info.format) == SurfaceType::ColorTexture;
const ImageViewId color_view_id = is_color ? view_id : ImageViewId{};
const ImageViewId depth_view_id = is_color ? ImageViewId{} : view_id;
- const Extent3D extent = MipSize(image.info.size, view_info.range.base.level);
+ Extent3D extent = MipSize(image.info.size, view_info.range.base.level);
+ if (is_rescaled) {
+ const auto& resolution = Settings::values.resolution_info;
+ const auto scale_up = [&](u32 value) {
+ return std::max ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
PrepareImage(src_id, false, false);
PrepareImage(dst_id, true, false);
- ImageBase& dst_image = slot_images[dst_id];
- const ImageBase& src_image = slot_images[src_id];
+ Image& dst_image = slot_images[dst_id];
+ const Image& src_image = slot_images[src_id];
+
+ const bool is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
+ bool is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
+
+ if (is_src_rescaled && !is_dst_rescaled) {
+ if (ImageCanRescale(dst_image)) {
+ is_dst_rescaled = dst_image.ScaleUp();
+ }
+ }
+
+ const auto& resolution = Settings::values.resolution_info;
+ const auto scale_up = [&](u32 value) -> u32 {
+ if (value == 0) {
+ return 0U;
+ }
+ return std::max ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
const ImageViewInfo src_view_info(ImageViewType::e2D, images.src_format, src_range);
const auto [src_framebuffer_id, src_view_id] = RenderTargetFromImage(src_id, src_view_info);
const auto [src_samples_x, src_samples_y] = SamplesLog2(src_image.info.num_samples);
- const Region2D src_region{
+ Region2D src_region{
Offset2D{.x = copy.src_x0 >> src_samples_x, .y = copy.src_y0 >> src_samples_y},
Offset2D{.x = copy.src_x1 >> src_samples_x, .y = copy.src_y1 >> src_samples_y},
};
+ if (is_src_rescaled) {
+ scale_region(src_region);
+ }
const std::optional dst_base = dst_image.TryFindBase(dst.Address());
const SubresourceRange dst_range{.base = dst_base.value(), .extent = {1, 1}};
const ImageViewInfo dst_view_info(ImageViewType::e2D, images.dst_format, dst_range);
const auto [dst_framebuffer_id, dst_view_id] = RenderTargetFromImage(dst_id, dst_view_info);
const auto [dst_samples_x, dst_samples_y] = SamplesLog2(dst_image.info.num_samples);
- const Region2D dst_region{
+ Region2D dst_region{
Offset2D{.x = copy.dst_x0 >> dst_samples_x, .y = copy.dst_y0 >> dst_samples_y},
Offset2D{.x = copy.dst_x1 >> dst_samples_x, .y = copy.dst_y1 >> dst_samples_y},
};
+ if (is_dst_rescaled) {
+ scale_region(dst_region);
+ }
// Always call this after src_framebuffer_id was queried, as the address might be invalidated.
Framebuffer* const dst_framebuffer = &slot_framebuffers[dst_framebuffer_id];
@@ -1514,18 +1544,28 @@ void TextureCache ::MarkModification(ImageBase& image) noexcept {
template ::SynchronizeAliases(ImageId image_id) {
boost::container::small_vector ::SynchronizeAliases(ImageId image_id) {
return lhs_image.modification_tick < rhs_image.modification_tick;
});
for (const AliasedImage* const aliased : aliased_images) {
+ if (any_rescaled) {
+ Image& aliased_image = slot_images[aliased->id];
+ if (can_rescale) {
+ ScaleUp(aliased_image);
+ } else {
+ ScaleDown(aliased_image);
+ }
+ }
CopyImage(image_id, aliased->id, aliased->copies);
}
}
--
cgit v1.2.3
From d5143c83a9eacf23cc66616bcd1a1b0ccfda5082 Mon Sep 17 00:00:00 2001
From: ameerj
Date: Thu, 22 Jul 2021 00:16:19 -0400
Subject: texture_cache: Fix typo in aliased image rescaling
---
src/video_core/texture_cache/texture_cache.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 25fea8240..179f37526 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1552,7 +1552,7 @@ void TextureCache ::SynchronizeAliases(ImageId image_id) {
if (image.modification_tick < aliased_image.modification_tick) {
most_recent_tick = std::max(most_recent_tick, aliased_image.modification_tick);
aliased_images.push_back(&aliased);
- any_rescaled |= True(image.flags & ImageFlagBits::Rescaled);
+ any_rescaled |= True(aliased_image.flags & ImageFlagBits::Rescaled);
}
}
if (aliased_images.empty()) {
--
cgit v1.2.3
From 74efa57c1b78b4a07ad0003e847bd5f0aa7c7bb5 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp
Date: Sun, 25 Jul 2021 21:44:13 -0300
Subject: texture_cache: Add image getters
---
src/video_core/texture_cache/texture_cache.h | 10 ++++++++++
src/video_core/texture_cache/texture_cache_base.h | 6 ++++++
2 files changed, 16 insertions(+)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 179f37526..ae74a6ecf 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -119,6 +119,16 @@ typename P::ImageView& TextureCache ::GetImageView(ImageViewId id) noexcept {
return slot_image_views[id];
}
+template ::GetImage(ImageId id) const noexcept {
+ return slot_images[id];
+}
+
+template ::GetImage(ImageId id) noexcept {
+ return slot_images[id];
+}
+
template ::MarkModification(ImageId id) noexcept {
MarkModification(slot_images[id]);
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index deddf0d30..0d2d9ec2e 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -95,6 +95,12 @@ public:
/// Return a reference to the given image view id
[[nodiscard]] ImageView& GetImageView(ImageViewId id) noexcept;
+ /// Return a constant reference to the given image id
+ [[nodiscard]] const Image& GetImage(ImageId id) const noexcept;
+
+ /// Return a reference to the given image id
+ [[nodiscard]] Image& GetImage(ImageId id) noexcept;
+
/// Mark an image as modified from the GPU
void MarkModification(ImageId id) noexcept;
--
cgit v1.2.3
From 0e8cf38f392f2ea6f7f5195070ad721b78590c04 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Mon, 26 Jul 2021 09:33:00 +0200
Subject: Texture Cache: Implement Blacklisting.
---
src/video_core/texture_cache/image_base.h | 1 +
src/video_core/texture_cache/texture_cache.h | 34 ++++++++++++++++++++++-
src/video_core/texture_cache/texture_cache_base.h | 2 ++
3 files changed, 36 insertions(+), 1 deletion(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 1cd30fd37..10dd52e28 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -37,6 +37,7 @@ enum class ImageFlagBits : u32 {
// Rescaler
Rescaled = 1 << 12,
RescaleChecked = 1 << 13,
+ Blacklisted = 1 << 14,
};
DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index ae74a6ecf..ce5994d5f 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -227,6 +227,7 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
flags[Dirty::RenderTargetControl] = false;
bool can_rescale = true;
+ bool any_blacklisted = false;
std::array ::UpdateRenderTargets(bool is_clear) {
id_save = image_id;
auto& image = slot_images[image_id];
can_rescale &= ImageCanRescale(image);
+ any_blacklisted |= True(image.flags & ImageFlagBits::Blacklisted);
} else {
id_save = CORRUPT_ID;
}
@@ -268,10 +270,13 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
scale_up(tmp_depth_image);
} else {
rescaled = false;
- const auto scale_down = [this](ImageId image_id) {
+ const auto scale_down = [this, any_blacklisted](ImageId image_id) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
ScaleDown(image);
+ if (any_blacklisted) {
+ image.flags |= ImageFlagBits::Blacklisted;
+ }
}
};
for (size_t index = 0; index < NUM_RT; ++index) {
@@ -736,8 +741,22 @@ ImageId TextureCache ::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
return image_id;
}
+template ::BlackListImage(ImageId image_id) {
+ auto& image = slot_images[image_id];
+ if (True(image.flags & ImageFlagBits::Blacklisted)) {
+ return false;
+ }
+ image.flags |= ImageFlagBits::Blacklisted;
+ ScaleDown(image);
+ return true;
+}
+
template ::ImageCanRescale(Image& image) {
+ if (True(image.flags & ImageFlagBits::Blacklisted)) {
+ return false;
+ }
if (True(image.flags & ImageFlagBits::Rescaled) ||
True(image.flags & ImageFlagBits::RescaleChecked)) {
return true;
@@ -912,6 +931,7 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
bool can_rescale =
(info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
bool any_rescaled = false;
+ bool any_blacklisted = false;
for (const ImageId sibling_id : all_siblings) {
if (!can_rescale) {
break;
@@ -919,6 +939,7 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
Image& sibling = slot_images[sibling_id];
can_rescale &= ImageCanRescale(sibling);
any_rescaled |= True(sibling.flags & ImageFlagBits::Rescaled);
+ any_blacklisted |= True(sibling.flags & ImageFlagBits::Blacklisted);
}
can_rescale &= any_rescaled;
@@ -932,6 +953,9 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
for (const ImageId sibling_id : all_siblings) {
Image& sibling = slot_images[sibling_id];
ScaleDown(sibling);
+ if (any_blacklisted) {
+ sibling.flags |= ImageFlagBits::Blacklisted;
+ }
}
}
@@ -1556,6 +1580,7 @@ void TextureCache ::SynchronizeAliases(ImageId image_id) {
boost::container::small_vector ::SynchronizeAliases(ImageId image_id) {
most_recent_tick = std::max(most_recent_tick, aliased_image.modification_tick);
aliased_images.push_back(&aliased);
any_rescaled |= True(aliased_image.flags & ImageFlagBits::Rescaled);
+ any_blacklisted |= True(aliased_image.flags & ImageFlagBits::Blacklisted);
}
}
if (aliased_images.empty()) {
@@ -1574,6 +1600,9 @@ void TextureCache ::SynchronizeAliases(ImageId image_id) {
ScaleUp(image);
} else {
ScaleDown(image);
+ if (any_blacklisted) {
+ image.flags |= ImageFlagBits::Blacklisted;
+ }
}
}
image.modification_tick = most_recent_tick;
@@ -1589,6 +1618,9 @@ void TextureCache ::SynchronizeAliases(ImageId image_id) {
ScaleUp(aliased_image);
} else {
ScaleDown(aliased_image);
+ if (any_blacklisted) {
+ aliased_image.flags |= ImageFlagBits::Blacklisted;
+ }
}
}
CopyImage(image_id, aliased->id, aliased->copies);
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 0d2d9ec2e..35a29cd9b 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -176,6 +176,8 @@ public:
[[nodiscard]] bool IsRescaling();
+ [[nodiscard]] bool BlackListImage(ImageId image_id);
+
std::mutex mutex;
private:
--
cgit v1.2.3
From 07c564f38b238af9be7a9d8aee1149a353c2880b Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Tue, 27 Jul 2021 01:29:55 +0200
Subject: Texture Cache: Implement Rating System.
---
src/video_core/texture_cache/image_base.cpp | 6 ++--
src/video_core/texture_cache/image_base.h | 2 ++
src/video_core/texture_cache/image_info.cpp | 11 ++++++++
src/video_core/texture_cache/image_info.h | 1 +
src/video_core/texture_cache/texture_cache.h | 42 ++++++++++++++++++++--------
5 files changed, 47 insertions(+), 15 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp
index 6052d148a..e9e725edf 100644
--- a/src/video_core/texture_cache/image_base.cpp
+++ b/src/video_core/texture_cache/image_base.cpp
@@ -60,9 +60,9 @@ namespace {
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)}, gpu_addr{gpu_addr_},
- cpu_addr{cpu_addr_}, cpu_addr_end{cpu_addr + guest_size_bytes},
- mip_level_offsets{CalculateMipLevelOffsets(info)} {
+ converted_size_bytes{CalculateConvertedSizeBytes(info)}, scale_rating{},
+ scale_tick{}, 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);
slice_subresources = CalculateSliceSubresources(info);
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 10dd52e28..97f107b4d 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -78,6 +78,8 @@ struct ImageBase {
u32 guest_size_bytes = 0;
u32 unswizzled_size_bytes = 0;
u32 converted_size_bytes = 0;
+ u32 scale_rating = 0;
+ u64 scale_tick = 0;
ImageFlagBits flags = ImageFlagBits::CpuModified;
GPUVAddr gpu_addr = 0;
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 022ca9033..7fa8fd4fe 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -31,6 +31,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
.depth = config.block_depth,
};
}
+ rescaleable = false;
tile_width_spacing = config.tile_width_spacing;
if (config.texture_type != TextureType::Texture2D &&
config.texture_type != TextureType::Texture2DNoMipmap) {
@@ -53,12 +54,14 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
case TextureType::Texture2DNoMipmap:
ASSERT(config.Depth() == 1);
type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D;
+ rescaleable = !config.IsPitchLinear();
size.width = config.Width();
size.height = config.Height();
resources.layers = config.BaseLayer() + 1;
break;
case TextureType::Texture2DArray:
type = ImageType::e2D;
+ rescaleable = true;
size.width = config.Width();
size.height = config.Height();
resources.layers = config.BaseLayer() + config.Depth();
@@ -98,12 +101,14 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
// FIXME: Call this without passing *this
layer_stride = CalculateLayerStride(*this);
maybe_unaligned_layer_stride = CalculateLayerSize(*this);
+ rescaleable &= (block.depth == 0) && resources.levels == 1;
}
}
ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept {
const auto& rt = regs.rt[index];
format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format);
+ rescaleable = false;
if (rt.tile_mode.is_pitch_linear) {
ASSERT(rt.tile_mode.is_3d == 0);
type = ImageType::Linear;
@@ -129,6 +134,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
type = ImageType::e3D;
size.depth = rt.depth;
} else {
+ rescaleable = block.depth == 0 && size.height > 256;
type = ImageType::e2D;
resources.layers = rt.depth;
}
@@ -138,6 +144,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format);
size.width = regs.zeta_width;
size.height = regs.zeta_height;
+ rescaleable = false;
resources.levels = 1;
layer_stride = regs.zeta.layer_stride * 4;
maybe_unaligned_layer_stride = layer_stride;
@@ -156,6 +163,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
type = ImageType::e3D;
size.depth = regs.zeta_depth;
} else {
+ rescaleable = block.depth == 0 && size.height > 256;
type = ImageType::e2D;
resources.layers = regs.zeta_depth;
}
@@ -164,6 +172,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
UNIMPLEMENTED_IF_MSG(config.layer != 0, "Surface layer is not zero");
format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(config.format);
+ rescaleable = false;
if (config.linear == Tegra::Engines::Fermi2D::MemoryLayout::Pitch) {
type = ImageType::Linear;
size = Extent3D{
@@ -174,6 +183,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
pitch = config.pitch;
} else {
type = config.block_depth > 0 ? ImageType::e3D : ImageType::e2D;
+
block = Extent3D{
.width = config.block_width,
.height = config.block_height,
@@ -186,6 +196,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
.height = config.height,
.depth = 1,
};
+ rescaleable = block.depth == 0 && size.height > 256;
}
}
diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h
index 16d4cee37..e874d2870 100644
--- a/src/video_core/texture_cache/image_info.h
+++ b/src/video_core/texture_cache/image_info.h
@@ -33,6 +33,7 @@ struct ImageInfo {
u32 maybe_unaligned_layer_stride = 0;
u32 num_samples = 1;
u32 tile_width_spacing = 0;
+ bool rescaleable = false;
};
} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index ce5994d5f..be40f6b88 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -216,7 +216,10 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
return;
}
+ u32 scale_rating;
bool rescaled;
+ std::array ::UpdateRenderTargets(bool is_clear) {
const bool force = flags[Dirty::RenderTargetControl];
flags[Dirty::RenderTargetControl] = false;
+ scale_rating = 0;
+ bool any_rescaled = false;
bool can_rescale = true;
bool any_blacklisted = false;
- std::array ::UpdateRenderTargets(bool is_clear) {
auto& image = slot_images[image_id];
can_rescale &= ImageCanRescale(image);
any_blacklisted |= True(image.flags & ImageFlagBits::Blacklisted);
+ any_rescaled |= True(image.flags & ImageFlagBits::Rescaled);
+ scale_rating = std::max ::UpdateRenderTargets(bool is_clear) {
check_rescale(render_targets.depth_buffer_id, tmp_depth_image);
if (can_rescale) {
- rescaled = true;
+ rescaled = any_rescaled || scale_rating >= 2;
const auto scale_up = [this](ImageId image_id) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
ScaleUp(image);
}
};
- for (size_t index = 0; index < NUM_RT; ++index) {
- scale_up(tmp_color_images[index]);
+ if (rescaled) {
+ for (size_t index = 0; index < NUM_RT; ++index) {
+ scale_up(tmp_color_images[index]);
+ }
+ scale_up(tmp_depth_image);
}
- scale_up(tmp_depth_image);
} else {
rescaled = false;
const auto scale_down = [this, any_blacklisted](ImageId image_id) {
@@ -283,10 +292,23 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
scale_down(tmp_color_images[index]);
}
scale_down(tmp_depth_image);
+ scale_rating = 0;
}
} while (has_deleted_images);
// Rescale End
+ const auto set_rating = [this, scale_rating](ImageId image_id) {
+ if (image_id != CORRUPT_ID) {
+ Image& image = slot_images[image_id];
+ image.scale_rating = scale_rating;
+ image.scale_tick = frame_tick + 1;
+ }
+ };
+ for (size_t index = 0; index < NUM_RT; ++index) {
+ set_rating(tmp_color_images[index]);
+ }
+ set_rating(tmp_depth_image);
+
if (is_rescaling != rescaled) {
flags[Dirty::RescaleViewports] = true;
flags[Dirty::RescaleScissors] = true;
@@ -761,10 +783,7 @@ bool TextureCache ::ImageCanRescale(Image& image) {
True(image.flags & ImageFlagBits::RescaleChecked)) {
return true;
}
- const auto& info = image.info;
- const bool can_this_rescale =
- (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
- if (!can_this_rescale) {
+ if (!image.info.rescaleable) {
image.flags &= ~ImageFlagBits::RescaleChecked;
return false;
}
@@ -928,8 +947,7 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
};
ForEachSparseImageInRegion(gpu_addr, size_bytes, region_check_gpu);
- bool can_rescale =
- (info.type == ImageType::e1D || info.type == ImageType::e2D) && info.block.depth == 0;
+ bool can_rescale = info.rescaleable;
bool any_rescaled = false;
bool any_blacklisted = false;
for (const ImageId sibling_id : all_siblings) {
--
cgit v1.2.3
From 56ccda1d9952368d0c1e29d7c4b486c547de9549 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp
Date: Wed, 28 Jul 2021 02:47:06 -0300
Subject: texture_cache: Simplify image view queries and blacklisting
---
src/video_core/texture_cache/image_base.cpp | 2 +
src/video_core/texture_cache/image_base.h | 3 ++
src/video_core/texture_cache/image_view_base.cpp | 2 +-
src/video_core/texture_cache/image_view_base.h | 4 +-
src/video_core/texture_cache/texture_cache.h | 47 +++++++++++++----------
src/video_core/texture_cache/texture_cache_base.h | 30 +++++++++------
src/video_core/texture_cache/types.h | 7 ++++
7 files changed, 60 insertions(+), 35 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp
index e9e725edf..25a211df8 100644
--- a/src/video_core/texture_cache/image_base.cpp
+++ b/src/video_core/texture_cache/image_base.cpp
@@ -69,6 +69,8 @@ ImageBase::ImageBase(const ImageInfo& info_, GPUVAddr gpu_addr_, VAddr cpu_addr_
}
}
+ImageBase::ImageBase(const NullImageParams&) {}
+
ImageMapView::ImageMapView(GPUVAddr gpu_addr_, VAddr cpu_addr_, size_t size_, ImageId image_id_)
: gpu_addr{gpu_addr_}, cpu_addr{cpu_addr_}, size{size_}, image_id{image_id_} {}
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 97f107b4d..9c34687e0 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -48,8 +48,11 @@ struct AliasedImage {
ImageId id;
};
+struct NullImageParams {};
+
struct ImageBase {
explicit ImageBase(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr);
+ explicit ImageBase(const NullImageParams&);
[[nodiscard]] std::optional ::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
Tegra::MemoryManager& gpu_memory_)
: runtime{runtime_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_},
kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_} {
- runtime.Init();
// Configure null sampler
TSCEntry sampler_descriptor{};
sampler_descriptor.min_filter.Assign(Tegra::Texture::TextureFilter::Linear);
@@ -46,7 +45,8 @@ TextureCache ::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
// Make sure the first index is reserved for the null resources
// This way the null resource becomes a compile time constant
- void(slot_image_views.insert(runtime, NullImageParams{}));
+ void(slot_images.insert(NullImageParams{}));
+ void(slot_image_views.insert(runtime, NullImageViewParams{}));
void(slot_samplers.insert(runtime, sampler_descriptor));
if constexpr (HAS_DEVICE_MEMORY_INFO) {
@@ -57,7 +57,7 @@ TextureCache ::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY);
minimum_memory = 0;
} else {
- // on OGL we can be more conservatives as the driver takes care.
+ // 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;
@@ -135,15 +135,14 @@ void TextureCache ::MarkModification(ImageId id) noexcept {
}
template ::FillGraphicsImageViews(std::span ::FillGraphicsImageViews(std::span ::FillComputeImageViews(std::span ::FillComputeImageViews(std::span ::GetFramebuffer() {
}
template ::FillImageViews(DescriptorTable ::PopAsyncFlushes() {
}
template ::IsRescaling() {
+bool TextureCache ::IsRescaling() const noexcept {
return is_rescaling;
}
@@ -775,12 +783,11 @@ bool TextureCache ::BlackListImage(ImageId image_id) {
}
template ::ImageCanRescale(Image& image) {
+bool TextureCache ::ImageCanRescale(ImageBase& image) {
if (True(image.flags & ImageFlagBits::Blacklisted)) {
return false;
}
- if (True(image.flags & ImageFlagBits::Rescaled) ||
- True(image.flags & ImageFlagBits::RescaleChecked)) {
+ if (True(image.flags & (ImageFlagBits::Rescaled | ImageFlagBits::RescaleChecked))) {
return true;
}
if (!image.info.rescaleable) {
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 35a29cd9b..b6cc09682 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -39,6 +39,16 @@ using VideoCore::Surface::PixelFormatFromDepthFormat;
using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
using namespace Common::Literals;
+struct ImageViewInOut {
+ u32 index;
+ bool blacklist;
+ union {
+ struct Empty {
+ } empty{};
+ ImageViewId id;
+ };
+};
+
template ::FillGraphicsImageViews(std::span ::FillComputeImageViews(std::span ::GetImageView(ImageViewId id) noexcept {
return slot_image_views[id];
}
-template ::GetImage(ImageId id) const noexcept {
- return slot_images[id];
-}
-
-template ::GetImage(ImageId id) noexcept {
- return slot_images[id];
-}
-
template ::MarkModification(ImageId id) noexcept {
MarkModification(slot_images[id]);
@@ -634,6 +624,12 @@ bool TextureCache ::IsRescaling() const noexcept {
return is_rescaling;
}
+template ::IsRescaling(const ImageViewBase& image_view) const noexcept {
+ const ImageBase& image = slot_images[image_view.image_id];
+ return True(image.flags & ImageFlagBits::Rescaled);
+}
+
template ::IsRegionGpuModified(VAddr addr, size_t size) {
bool is_modified = false;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index b6cc09682..8b417b611 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -21,6 +21,7 @@
#include "video_core/texture_cache/descriptor_table.h"
#include "video_core/texture_cache/image_base.h"
#include "video_core/texture_cache/image_info.h"
+#include "video_core/texture_cache/image_view_base.h"
#include "video_core/texture_cache/image_view_info.h"
#include "video_core/texture_cache/render_targets.h"
#include "video_core/texture_cache/slot_vector.h"
@@ -100,12 +101,6 @@ public:
/// Return a reference to the given image view id
[[nodiscard]] ImageView& GetImageView(ImageViewId id) noexcept;
- /// Return a constant reference to the given image id
- [[nodiscard]] const Image& GetImage(ImageId id) const noexcept;
-
- /// Return a reference to the given image id
- [[nodiscard]] Image& GetImage(ImageId id) noexcept;
-
/// Mark an image as modified from the GPU
void MarkModification(ImageId id) noexcept;
@@ -181,6 +176,8 @@ public:
[[nodiscard]] bool IsRescaling() const noexcept;
+ [[nodiscard]] bool IsRescaling(const ImageViewBase& image_view) const noexcept;
+
[[nodiscard]] bool BlackListImage(ImageId image_id);
std::mutex mutex;
--
cgit v1.2.3
From ed675cfd8cc89d64c763becfd991d1dd40deac5a Mon Sep 17 00:00:00 2001
From: ameerj
Date: Wed, 4 Aug 2021 19:02:30 -0400
Subject: texture_cache: Disable dst_image scaling in BlitImage
Fixes scaling in Super Mario Party
---
src/video_core/texture_cache/texture_cache.h | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 0e70c4db2..d86f80b5d 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -478,11 +478,13 @@ void TextureCache ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
const bool is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
bool is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
- if (is_src_rescaled && !is_dst_rescaled) {
- if (ImageCanRescale(dst_image)) {
- is_dst_rescaled = dst_image.ScaleUp();
- }
- }
+ // TODO: This requires the rendertarget image views to be updated with the upscaled sizes,
+ // otherwise the blit will use a larger framebuffer size than the image view attachment.
+ // if (is_src_rescaled && !is_dst_rescaled) {
+ // if (ImageCanRescale(dst_image)) {
+ // is_dst_rescaled = dst_image.ScaleUp();
+ // }
+ // }
const auto& resolution = Settings::values.resolution_info;
const auto scale_up = [&](u32 value) -> u32 {
--
cgit v1.2.3
From 4b1393a691d1d8d79c57e7b73734cb8287b91760 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Sat, 7 Aug 2021 02:15:24 +0200
Subject: Texture Cache: Correctly fix Blits Rescaling.
---
src/video_core/texture_cache/texture_cache.h | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index d86f80b5d..2de439889 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -473,18 +473,21 @@ void TextureCache ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
PrepareImage(dst_id, true, false);
Image& dst_image = slot_images[dst_id];
- const Image& src_image = slot_images[src_id];
+ Image& src_image = slot_images[src_id];
- const bool is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
+ bool is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
bool is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
- // TODO: This requires the rendertarget image views to be updated with the upscaled sizes,
- // otherwise the blit will use a larger framebuffer size than the image view attachment.
- // if (is_src_rescaled && !is_dst_rescaled) {
- // if (ImageCanRescale(dst_image)) {
- // is_dst_rescaled = dst_image.ScaleUp();
- // }
- // }
+ if (is_src_rescaled != is_dst_rescaled) {
+ if (ImageCanRescale(dst_image)) {
+ ScaleUp(dst_image);
+ is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
+ }
+ if (ImageCanRescale(src_image)) {
+ ScaleUp(src_image);
+ is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
+ }
+ }
const auto& resolution = Settings::values.resolution_info;
const auto scale_up = [&](u32 value) -> u32 {
--
cgit v1.2.3
From d7c97921696486a95aaaf5c805b9fcc12230de77 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Sat, 7 Aug 2021 04:32:17 +0200
Subject: TextureCache: Fix Buffer Views Scaling.
---
src/video_core/texture_cache/image_view_base.cpp | 11 ++++++-----
src/video_core/texture_cache/texture_cache.h | 3 +++
2 files changed, 9 insertions(+), 5 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_view_base.cpp b/src/video_core/texture_cache/image_view_base.cpp
index e66dc9320..c7b4fc231 100644
--- a/src/video_core/texture_cache/image_view_base.cpp
+++ b/src/video_core/texture_cache/image_view_base.cpp
@@ -37,11 +37,12 @@ ImageViewBase::ImageViewBase(const ImageViewInfo& info, const ImageInfo& image_i
}
ImageViewBase::ImageViewBase(const ImageInfo& info, const ImageViewInfo& view_info)
- : format{info.format}, type{ImageViewType::Buffer}, size{
- .width = info.size.width,
- .height = 1,
- .depth = 1,
- } {
+ : image_id{NULL_IMAGE_ID}, format{info.format}, type{ImageViewType::Buffer},
+ size{
+ .width = info.size.width,
+ .height = 1,
+ .depth = 1,
+ } {
ASSERT_MSG(view_info.type == ImageViewType::Buffer, "Expected texture buffer");
}
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 2de439889..764984546 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -631,6 +631,9 @@ bool TextureCache ::IsRescaling() const noexcept {
template ::IsRescaling(const ImageViewBase& image_view) const noexcept {
+ if (image_view.type == ImageViewType::Buffer) {
+ return false;
+ }
const ImageBase& image = slot_images[image_view.image_id];
return True(image.flags & ImageFlagBits::Rescaled);
}
--
cgit v1.2.3
From 68e038404cc0069d9f59068a60b56e67b4321e7a Mon Sep 17 00:00:00 2001
From: ameerj
Date: Sat, 14 Aug 2021 00:01:47 -0400
Subject: shader, video_core: Fix GCC build errors
---
src/video_core/texture_cache/texture_cache_base.h | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 8b417b611..517a4c224 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -41,13 +41,9 @@ using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
using namespace Common::Literals;
struct ImageViewInOut {
- u32 index;
- bool blacklist;
- union {
- struct Empty {
- } empty{};
- ImageViewId id;
- };
+ u32 index{};
+ bool blacklist{};
+ ImageViewId id{};
};
template ::UpdateRenderTargets(bool is_clear) {
return;
}
- u32 scale_rating;
- bool rescaled;
+ u32 scale_rating = 0;
+ bool rescaled = false;
std::array ::UpdateRenderTargets(bool is_clear) {
bool can_rescale = true;
bool any_blacklisted = false;
const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
- if (view_id) {
+ if (view_id != NULL_IMAGE_VIEW_ID && view_id != ImageViewId{}) {
const auto& view = slot_image_views[view_id];
const auto image_id = view.image_id;
id_save = image_id;
@@ -265,6 +265,7 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
scale_up(tmp_color_images[index]);
}
scale_up(tmp_depth_image);
+ scale_rating = 2;
}
} else {
rescaled = false;
--
cgit v1.2.3
From ea82bd4b7e4c4f23a40f8a35858d8b74950fc347 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Mon, 20 Sep 2021 22:18:15 +0200
Subject: Texture Cache: Fix Rescaling on Multisample
---
src/video_core/texture_cache/image_info.cpp | 4 ++--
src/video_core/texture_cache/texture_cache.h | 17 +++++++++++++----
2 files changed, 15 insertions(+), 6 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index bdf306bf9..7fa8fd4fe 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -101,7 +101,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
// FIXME: Call this without passing *this
layer_stride = CalculateLayerStride(*this);
maybe_unaligned_layer_stride = CalculateLayerSize(*this);
- rescaleable &= (block.depth == 0) && resources.levels == 1 && num_samples == 1;
+ rescaleable &= (block.depth == 0) && resources.levels == 1;
}
}
@@ -134,7 +134,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
type = ImageType::e3D;
size.depth = rt.depth;
} else {
- rescaleable = block.depth == 0 && size.height > 256 && num_samples == 1;
+ rescaleable = block.depth == 0 && size.height > 256;
type = ImageType::e2D;
resources.layers = rt.depth;
}
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index a543776fd..b60f840c1 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -476,17 +476,26 @@ void TextureCache ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
Image& dst_image = slot_images[dst_id];
Image& src_image = slot_images[src_id];
+ bool is_resolve = src_image.info.num_samples != 1 && dst_image.info.num_samples == 1;
+
bool is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
bool is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
if (is_src_rescaled != is_dst_rescaled) {
- if (ImageCanRescale(dst_image)) {
- ScaleUp(dst_image);
- is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
- }
if (ImageCanRescale(src_image)) {
ScaleUp(src_image);
is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
+ if (is_resolve) {
+ dst_image.info.rescaleable = true;
+ for (const auto& alias : dst_image.aliased_images) {
+ Image& other_image = slot_images[alias.id];
+ other_image.info.rescaleable = true;
+ }
+ }
+ }
+ if (ImageCanRescale(dst_image)) {
+ ScaleUp(dst_image);
+ is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
}
}
--
cgit v1.2.3
From 237a43004fb27a273495a0b44515cf7389dea553 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Sun, 3 Oct 2021 22:42:29 +0200
Subject: Texture Cache: Fix calculations when scaling.
---
src/video_core/texture_cache/texture_cache.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index b60f840c1..691198853 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -858,6 +858,12 @@ bool TextureCache ::ScaleUp(Image& image) {
if (!rescaled) {
return false;
}
+ const auto& add_to_size = Settings::values.resolution_info.up_factor - 1.0f;
+ const auto sign = std::signbit(add_to_size);
+ const u64 tentative_size = static_cast ::ScaleDown(Image& image) {
if (!rescaled) {
return false;
}
+ const auto& add_to_size = Settings::values.resolution_info.up_factor - 1.0f;
+ const auto sign = std::signbit(add_to_size);
+ const u64 tentative_size = static_cast ::InvalidateScale(Image& image) {
has_deleted_images = true;
}
+template ::GetScaledImageSizeBytes(Image& image) {
+ const f32 add_to_size = Settings::values.resolution_info.up_factor - 1.0f;
+ const bool sign = std::signbit(add_to_size);
+ const u32 image_size_bytes = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
+ const u64 tentative_size = static_cast ::ScaleUp(Image& image) {
const bool rescaled = image.ScaleUp();
if (!rescaled) {
return false;
}
- const auto& add_to_size = Settings::values.resolution_info.up_factor - 1.0f;
- const auto sign = std::signbit(add_to_size);
- const u64 tentative_size = static_cast ::ScaleDown(Image& image) {
if (!rescaled) {
return false;
}
- const auto& add_to_size = Settings::values.resolution_info.up_factor - 1.0f;
- const auto sign = std::signbit(add_to_size);
- const u64 tentative_size = static_cast ::CopyImage(ImageId dst_id, ImageId src_id, std::vector ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
Image& dst_image = slot_images[dst_id];
Image& src_image = slot_images[src_id];
-
- bool is_resolve = src_image.info.num_samples != 1 && dst_image.info.num_samples == 1;
-
bool is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
bool is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
+ const bool is_resolve = src_image.info.num_samples != 1 && dst_image.info.num_samples == 1;
if (is_src_rescaled != is_dst_rescaled) {
if (ImageCanRescale(src_image)) {
ScaleUp(src_image);
@@ -498,7 +496,13 @@ void TextureCache ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
}
}
-
+ if (is_resolve && (is_src_rescaled != is_dst_rescaled)) {
+ // A resolve requires both images to be the same dimensions. Resize down if needed.
+ ScaleDown(src_image);
+ ScaleDown(dst_image);
+ is_src_rescaled = True(src_image.flags & ImageFlagBits::Rescaled);
+ is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
+ }
const auto& resolution = Settings::values.resolution_info;
const auto scale_up = [&](u32 value) -> u32 {
if (value == 0) {
@@ -506,7 +510,6 @@ void TextureCache ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
}
return std::max ::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
is_dst_rescaled = True(dst_image.flags & ImageFlagBits::Rescaled);
}
const auto& resolution = Settings::values.resolution_info;
- const auto scale_up = [&](u32 value) -> u32 {
- if (value == 0) {
- return 0U;
- }
- return std::max ::CopyImage(ImageId dst_id, ImageId src_id, std::vector ::RenderTargetFromImage(
Extent3D extent = MipSize(image.info.size, view_info.range.base.level);
if (is_rescaled) {
const auto& resolution = Settings::values.resolution_info;
- const auto scale_up = [&](u32 value) {
- return std::max ::BlackListImage(ImageId image_id) {
template ::ImageCanRescale(ImageBase& image) {
- if (True(image.flags & ImageFlagBits::Blacklisted)) {
+ if (!image.info.rescaleable || True(image.flags & ImageFlagBits::Blacklisted)) {
return false;
}
- if (True(image.flags & (ImageFlagBits::Rescaled | ImageFlagBits::RescaleChecked))) {
+ if (True(image.flags & (ImageFlagBits::Rescaled | ImageFlagBits::CheckingRescalable))) {
return true;
}
- if (!image.info.rescaleable) {
- image.flags &= ~ImageFlagBits::RescaleChecked;
- return false;
+ if (True(image.flags & ImageFlagBits::IsRescalable)) {
+ return true;
}
- image.flags |= ImageFlagBits::RescaleChecked;
+ image.flags |= ImageFlagBits::CheckingRescalable;
for (const auto& alias : image.aliased_images) {
Image& other_image = slot_images[alias.id];
if (!ImageCanRescale(other_image)) {
- image.flags &= ~ImageFlagBits::RescaleChecked;
+ image.flags &= ~ImageFlagBits::CheckingRescalable;
return false;
}
}
- image.flags &= ~ImageFlagBits::RescaleChecked;
+ image.flags &= ~ImageFlagBits::CheckingRescalable;
+ image.flags |= ImageFlagBits::IsRescalable;
return true;
}
--
cgit v1.2.3
From 0f14c9379eae9c3caf8f4b932eace0a84d728f94 Mon Sep 17 00:00:00 2001
From: ameerj
Date: Thu, 14 Oct 2021 14:12:25 -0400
Subject: texture_cache_base: Remove unused function declarations
---
src/video_core/texture_cache/texture_cache_base.h | 8 --------
1 file changed, 8 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 40e003b60..4dbe050af 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -144,14 +144,6 @@ public:
const Tegra::Engines::Fermi2D::Surface& src,
const Tegra::Engines::Fermi2D::Config& copy);
- /// Invalidate the contents of the color buffer index
- /// These contents become unspecified, the cache can assume aggressive optimizations.
- void InvalidateColorBuffer(size_t index);
-
- /// Invalidate the contents of the depth buffer
- /// These contents become unspecified, the cache can assume aggressive optimizations.
- void InvalidateDepthBuffer();
-
/// Try to find a cached image view in the given CPU address
[[nodiscard]] ImageView* TryFindFramebufferImageView(VAddr cpu_addr);
--
cgit v1.2.3
From b7ccc58f235d9e442677eb10259b7196a387c6bc Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Fri, 15 Oct 2021 22:59:16 +0200
Subject: Texture Cahe: Fix downscaling on SMO.
---
src/video_core/texture_cache/image_info.cpp | 4 ++++
src/video_core/texture_cache/image_info.h | 1 +
src/video_core/texture_cache/texture_cache.h | 3 +++
3 files changed, 8 insertions(+)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 7fa8fd4fe..d8e414247 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -102,6 +102,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
layer_stride = CalculateLayerStride(*this);
maybe_unaligned_layer_stride = CalculateLayerSize(*this);
rescaleable &= (block.depth == 0) && resources.levels == 1;
+ downscaleable = size.height > 512;
}
}
@@ -135,6 +136,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
size.depth = rt.depth;
} else {
rescaleable = block.depth == 0 && size.height > 256;
+ downscaleable = size.height > 512;
type = ImageType::e2D;
resources.layers = rt.depth;
}
@@ -164,6 +166,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
size.depth = regs.zeta_depth;
} else {
rescaleable = block.depth == 0 && size.height > 256;
+ downscaleable = size.height > 512;
type = ImageType::e2D;
resources.layers = regs.zeta_depth;
}
@@ -197,6 +200,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
.depth = 1,
};
rescaleable = block.depth == 0 && size.height > 256;
+ downscaleable = size.height > 512;
}
}
diff --git a/src/video_core/texture_cache/image_info.h b/src/video_core/texture_cache/image_info.h
index e874d2870..5932dcaba 100644
--- a/src/video_core/texture_cache/image_info.h
+++ b/src/video_core/texture_cache/image_info.h
@@ -34,6 +34,7 @@ struct ImageInfo {
u32 num_samples = 1;
u32 tile_width_spacing = 0;
bool rescaleable = false;
+ bool downscaleable = false;
};
} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index c1fb12679..261cb6c48 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -798,6 +798,9 @@ bool TextureCache ::ImageCanRescale(ImageBase& image) {
if (!image.info.rescaleable || True(image.flags & ImageFlagBits::Blacklisted)) {
return false;
}
+ if (Settings::values.resolution_info.downscale && !image.info.downscaleable) {
+ return false;
+ }
if (True(image.flags & (ImageFlagBits::Rescaled | ImageFlagBits::CheckingRescalable))) {
return true;
}
--
cgit v1.2.3
From ef1dc4263586f5b81b53a5158db2c1cd2086ed4c Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Sun, 17 Oct 2021 01:22:13 +0200
Subject: Texture cache: Fix memory consumption and ignore rating when a depth
texture is rendered.
---
src/video_core/texture_cache/texture_cache.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 261cb6c48..c06cddae9 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -230,7 +230,8 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
auto& image = slot_images[image_id];
can_rescale &= ImageCanRescale(image);
any_blacklisted |= True(image.flags & ImageFlagBits::Blacklisted);
- any_rescaled |= True(image.flags & ImageFlagBits::Rescaled);
+ any_rescaled |= True(image.flags & ImageFlagBits::Rescaled) ||
+ GetFormatType(image.info.format) != SurfaceType::ColorTexture;
scale_rating = std::max ::GetScaledImageSizeBytes(Image& image) {
const f32 add_to_size = Settings::values.resolution_info.up_factor - 1.0f;
const bool sign = std::signbit(add_to_size);
const u32 image_size_bytes = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
- const u64 tentative_size = image_size_bytes * static_cast ::ScaleDown(Image& image) {
if (!rescaled) {
return false;
}
- total_used_memory += GetScaledImageSizeBytes(image);
+ total_used_memory -= GetScaledImageSizeBytes(image);
InvalidateScale(image);
return true;
}
--
cgit v1.2.3
From d4f5193bd308988a80f52941d9eefc4c857bfa99 Mon Sep 17 00:00:00 2001
From: FernandoS27
Date: Sun, 17 Oct 2021 02:21:26 +0200
Subject: Texture Cache: Rescale conversions between depth and color
---
src/video_core/texture_cache/texture_cache.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index c06cddae9..a035d2b18 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1774,7 +1774,7 @@ void TextureCache ::CopyImage(ImageId dst_id, ImageId src_id, std::vector ::InvalidateScale(Image& image) {
}
template ::GetScaledImageSizeBytes(Image& image) {
- const f32 add_to_size = Settings::values.resolution_info.up_factor - 1.0f;
+u64 TextureCache ::GetScaledImageSizeBytes(ImageBase& image) {
+ const f32 add_to_size = Settings::values.resolution_info.up_factor;
const bool sign = std::signbit(add_to_size);
const u32 image_size_bytes = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
const u64 tentative_size = image_size_bytes * static_cast ::GetScaledImageSizeBytes(Image& image) {
template ::ScaleUp(Image& image) {
+ const bool has_copy = image.HasScaled();
const bool rescaled = image.ScaleUp();
if (!rescaled) {
return false;
}
- total_used_memory += GetScaledImageSizeBytes(image);
+ if (!has_copy) {
+ total_used_memory += GetScaledImageSizeBytes(image);
+ }
InvalidateScale(image);
return true;
}
@@ -880,7 +883,10 @@ bool TextureCache ::ScaleDown(Image& image) {
if (!rescaled) {
return false;
}
- total_used_memory -= GetScaledImageSizeBytes(image);
+ const bool has_copy = image.HasScaled();
+ if (!has_copy) {
+ total_used_memory -= GetScaledImageSizeBytes(image);
+ }
InvalidateScale(image);
return true;
}
@@ -1391,13 +1397,6 @@ void TextureCache ::UnregisterImage(ImageId image_id) {
"Trying to unregister an already registered image");
image.flags &= ~ImageFlagBits::Registered;
image.flags &= ~ImageFlagBits::BadOverlap;
- 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);
lru_cache.Free(image.lru_index);
const auto& clear_page_table =
[this, image_id](
@@ -1478,6 +1477,16 @@ template ::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;
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:
void InvalidateScale(Image& image);
bool ScaleUp(Image& image);
bool ScaleDown(Image& image);
- u64 GetScaledImageSizeBytes(Image& image);
+ u64 GetScaledImageSizeBytes(ImageBase& image);
Runtime& runtime;
VideoCore::RasterizerInterface& rasterizer;
--
cgit v1.2.3
From c2ca55c9d576940cfb37ba8569b1656b72c65569 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Mon, 18 Oct 2021 14:04:54 +0200
Subject: Texture Cache: ease the requirements of textures being blacklisted.
---
src/video_core/texture_cache/texture_cache.h | 27 ++++++-----------------
src/video_core/texture_cache/texture_cache_base.h | 2 --
2 files changed, 7 insertions(+), 22 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index cf0d33a45..c885586e8 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -221,7 +221,6 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
scale_rating = 0;
bool any_rescaled = false;
bool can_rescale = true;
- bool any_blacklisted = false;
const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) {
if (view_id != NULL_IMAGE_VIEW_ID && view_id != ImageViewId{}) {
const auto& view = slot_image_views[view_id];
@@ -229,7 +228,6 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
id_save = image_id;
auto& image = slot_images[image_id];
can_rescale &= ImageCanRescale(image);
- any_blacklisted |= True(image.flags & ImageFlagBits::Blacklisted);
any_rescaled |= True(image.flags & ImageFlagBits::Rescaled) ||
GetFormatType(image.info.format) != SurfaceType::ColorTexture;
scale_rating = std::max ::UpdateRenderTargets(bool is_clear) {
}
} else {
rescaled = false;
- const auto scale_down = [this, any_blacklisted](ImageId image_id) {
+ const auto scale_down = [this](ImageId image_id) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
ScaleDown(image);
- if (any_blacklisted) {
- image.flags |= ImageFlagBits::Blacklisted;
- }
}
};
for (size_t index = 0; index < NUM_RT; ++index) {
scale_down(tmp_color_images[index]);
}
scale_down(tmp_depth_image);
- scale_rating = 0;
+ scale_rating = 1;
}
} while (has_deleted_images);
// Rescale End
@@ -352,7 +347,10 @@ void TextureCache ::FillImageViews(DescriptorTable ::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
return image_id;
}
-template ::BlackListImage(ImageId image_id) {
- auto& image = slot_images[image_id];
- if (True(image.flags & ImageFlagBits::Blacklisted)) {
- return false;
- }
- image.flags |= ImageFlagBits::Blacklisted;
- ScaleDown(image);
- return true;
-}
-
template ::ImageCanRescale(ImageBase& image) {
- if (!image.info.rescaleable || True(image.flags & ImageFlagBits::Blacklisted)) {
+ if (!image.info.rescaleable) {
return false;
}
if (Settings::values.resolution_info.downscale && !image.info.downscaleable) {
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index e210393ba..4f876b2f4 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -166,8 +166,6 @@ public:
[[nodiscard]] bool IsRescaling(const ImageViewBase& image_view) const noexcept;
- [[nodiscard]] bool BlackListImage(ImageId image_id);
-
std::mutex mutex;
private:
--
cgit v1.2.3
From 3b61de74e6dc7526ffa8f03c21d81e2c3566ce90 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Mon, 18 Oct 2021 22:56:36 +0200
Subject: Texture Cache: fix memory managment and optimize scaled downloads,
uploads.
---
src/video_core/texture_cache/image_base.cpp | 2 +-
src/video_core/texture_cache/image_base.h | 6 +++---
src/video_core/texture_cache/texture_cache.h | 22 +++++++++++-----------
3 files changed, 15 insertions(+), 15 deletions(-)
(limited to 'src/video_core/texture_cache')
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 ::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 ::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 ::UntrackImage(ImageBase& image, ImageId image_id) {
template ::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()) {
--
cgit v1.2.3
From d37d10e7a7b9037a259b27923716e5ce3084d6c3 Mon Sep 17 00:00:00 2001
From: FernandoS27
Date: Wed, 20 Oct 2021 18:27:25 +0200
Subject: TextureCache: fix rescaling in aliases and overlap joins.
---
src/video_core/texture_cache/texture_cache.h | 41 ++++++++++++++++++++--------
src/video_core/texture_cache/util.cpp | 8 ++++--
src/video_core/texture_cache/util.h | 3 +-
3 files changed, 38 insertions(+), 14 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 13914dc8b..a32c11d04 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1037,8 +1037,11 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
if (overlap.info.num_samples != new_image.info.num_samples) {
LOG_WARNING(HW_GPU, "Copying between images with different samples is not implemented");
} else {
+ const auto& resolution = Settings::values.resolution_info;
const SubresourceBase base = new_image.TryFindBase(overlap.gpu_addr).value();
- auto copies = MakeShrinkImageCopies(new_info, overlap.info, base);
+ const u32 up_scale = can_rescale ? resolution.up_scale : 1;
+ const u32 down_shift = can_rescale ? resolution.down_shift : 0;
+ auto copies = MakeShrinkImageCopies(new_info, overlap.info, base, up_scale, down_shift);
runtime.CopyImage(new_image, overlap, std::move(copies));
}
if (True(overlap.flags & ImageFlagBits::Tracked)) {
@@ -1659,19 +1662,35 @@ void TextureCache ::SynchronizeAliases(ImageId image_id) {
const ImageBase& rhs_image = slot_images[rhs->id];
return lhs_image.modification_tick < rhs_image.modification_tick;
});
+ const auto& resolution = Settings::values.resolution_info;
for (const AliasedImage* const aliased : aliased_images) {
- if (any_rescaled) {
- Image& aliased_image = slot_images[aliased->id];
- if (can_rescale) {
- ScaleUp(aliased_image);
- } else {
- ScaleDown(aliased_image);
- if (any_blacklisted) {
- aliased_image.flags |= ImageFlagBits::Blacklisted;
- }
+ if (!resolution.active | !any_rescaled) {
+ CopyImage(image_id, aliased->id, aliased->copies);
+ continue;
+ }
+ Image& aliased_image = slot_images[aliased->id];
+ if (!can_rescale) {
+ ScaleDown(aliased_image);
+ if (any_blacklisted) {
+ aliased_image.flags |= ImageFlagBits::Blacklisted;
+ }
+ CopyImage(image_id, aliased->id, aliased->copies);
+ continue;
+ }
+ ScaleUp(aliased_image);
+
+ const bool both_2d{image.info.type == ImageType::e2D &&
+ aliased_image.info.type == ImageType::e2D};
+ auto copies = aliased->copies;
+ for (auto copy : copies) {
+ copy.extent.width = std::max ::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
if constexpr (HAS_DEVICE_MEMORY_INFO) {
const auto device_memory = runtime.GetDeviceLocalMemory();
- const u64 possible_expected_memory = (device_memory * 3) / 10;
- const u64 possible_critical_memory = (device_memory * 6) / 10;
+ const u64 possible_expected_memory = (device_memory * 4) / 10;
+ const u64 possible_critical_memory = (device_memory * 7) / 10;
expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY);
critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY);
minimum_memory = 0;
@@ -69,7 +69,7 @@ void TextureCache ::RunGarbageCollector() {
const bool high_priority_mode = total_used_memory >= expected_memory;
const bool aggressive_mode = total_used_memory >= critical_memory;
const u64 ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 100ULL;
- size_t num_iterations = aggressive_mode ? 10000 : (high_priority_mode ? 100 : 5);
+ size_t num_iterations = aggressive_mode ? 300 : (high_priority_mode ? 50 : 10);
const auto clean_up = [this, &num_iterations, high_priority_mode](ImageId image_id) {
if (num_iterations == 0) {
return true;
@@ -91,7 +91,7 @@ void TextureCache ::RunGarbageCollector() {
UntrackImage(image, image_id);
}
UnregisterImage(image_id);
- DeleteImage(image_id);
+ DeleteImage(image_id, image.scale_tick > frame_tick + 5);
return false;
};
lru_cache.ForEachItemBelow(frame_tick - ticks_to_destroy, clean_up);
@@ -287,7 +287,9 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
image.scale_rating = scale_rating;
- image.scale_tick = frame_tick + 1;
+ if (image.scale_tick <= frame_tick) {
+ image.scale_tick = frame_tick + 1;
+ }
}
};
for (size_t index = 0; index < NUM_RT; ++index) {
@@ -810,6 +812,9 @@ bool TextureCache ::ImageCanRescale(ImageBase& image) {
template ::InvalidateScale(Image& image) {
+ if (image.scale_tick <= frame_tick) {
+ image.scale_tick = frame_tick + 1;
+ }
const std::span ::InvalidateScale(Image& image) {
template ::GetScaledImageSizeBytes(ImageBase& image) {
- const f32 add_to_size = Settings::values.resolution_info.up_factor;
- const bool sign = std::signbit(add_to_size);
- const u32 image_size_bytes = std::max(image.guest_size_bytes, image.unswizzled_size_bytes);
- const u64 tentative_size = image_size_bytes * static_cast ::UntrackImage(ImageBase& image, ImageId image_id) {
}
template ::DeleteImage(ImageId image_id) {
+void TextureCache ::DeleteImage(ImageId image_id, bool immediate_delete) {
ImageBase& image = slot_images[image_id];
if (image.HasScaled()) {
total_used_memory -= GetScaledImageSizeBytes(image);
@@ -1576,10 +1584,14 @@ void TextureCache ::DeleteImage(ImageId image_id) {
num_removed_overlaps);
}
for (const ImageViewId image_view_id : image_view_ids) {
- sentenced_image_view.Push(std::move(slot_image_views[image_view_id]));
+ if (!immediate_delete) {
+ sentenced_image_view.Push(std::move(slot_image_views[image_view_id]));
+ }
slot_image_views.erase(image_view_id);
}
- sentenced_images.Push(std::move(slot_images[image_id]));
+ if (!immediate_delete) {
+ sentenced_images.Push(std::move(slot_images[image_id]));
+ }
slot_images.erase(image_id);
alloc_images.erase(alloc_image_it);
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 4f876b2f4..eea589269 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -292,7 +292,7 @@ private:
void UntrackImage(ImageBase& image, ImageId image_id);
/// Delete image from the cache
- void DeleteImage(ImageId image);
+ void DeleteImage(ImageId image, bool immediate_delete = false);
/// Remove image views references from the cache
void RemoveImageViewReferences(std::span ::BindRenderTarget(ImageViewId* old_id, ImageViewId new_id)
if (*old_id == new_id) {
return;
}
- if (*old_id) {
- const ImageViewBase& old_view = slot_image_views[*old_id];
+ if (new_id) {
+ const ImageViewBase& old_view = slot_image_views[new_id];
if (True(old_view.flags & ImageViewFlagBits::PreemtiveDownload)) {
uncommitted_downloads.push_back(old_view.image_id);
}
--
cgit v1.2.3
From 099b0b3167d6dc47b764331f40aa935e8a9ef86a Mon Sep 17 00:00:00 2001
From: FernandoS27
Date: Sat, 23 Oct 2021 17:17:02 +0200
Subject: Texture Cache: Fix memory usage on ScaleDown.
---
src/video_core/texture_cache/texture_cache.h | 4 ----
1 file changed, 4 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index dd9553806..26ab857c9 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -878,10 +878,6 @@ bool TextureCache ::ScaleDown(Image& image) {
if (!rescaled) {
return false;
}
- const bool has_copy = image.HasScaled();
- if (!has_copy) {
- total_used_memory -= GetScaledImageSizeBytes(image);
- }
InvalidateScale(image);
return true;
}
--
cgit v1.2.3
From 917b2466ad996cae75d9a0ca31226597b256acf9 Mon Sep 17 00:00:00 2001
From: ameerj
Date: Sun, 24 Oct 2021 23:07:15 -0400
Subject: texture_cache: Refactor Render Target scaling function
---
src/video_core/texture_cache/texture_cache.h | 33 +++++++++++++----------
src/video_core/texture_cache/texture_cache_base.h | 5 ++++
2 files changed, 24 insertions(+), 14 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 26ab857c9..c8031b695 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -192,19 +192,8 @@ void TextureCache ::SynchronizeComputeDescriptors() {
}
template ::UpdateRenderTargets(bool is_clear) {
- using namespace VideoCommon::Dirty;
+bool TextureCache ::RescaleRenderTargets(bool is_clear) {
auto& flags = maxwell3d.dirty.flags;
- if (!flags[Dirty::RenderTargets]) {
- for (size_t index = 0; index < NUM_RT; ++index) {
- ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
- PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id));
- }
- const ImageViewId depth_buffer_id = render_targets.depth_buffer_id;
- PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
- return;
- }
-
u32 scale_rating = 0;
bool rescaled = false;
std::array ::UpdateRenderTargets(bool is_clear) {
scale_rating = 1;
}
} while (has_deleted_images);
- // Rescale End
-
const auto set_rating = [this, scale_rating](ImageId image_id) {
if (image_id != CORRUPT_ID) {
Image& image = slot_images[image_id];
@@ -297,6 +284,24 @@ void TextureCache ::UpdateRenderTargets(bool is_clear) {
}
set_rating(tmp_depth_image);
+ return rescaled;
+}
+
+template ::UpdateRenderTargets(bool is_clear) {
+ using namespace VideoCommon::Dirty;
+ auto& flags = maxwell3d.dirty.flags;
+ if (!flags[Dirty::RenderTargets]) {
+ for (size_t index = 0; index < NUM_RT; ++index) {
+ ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
+ PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id));
+ }
+ const ImageViewId depth_buffer_id = render_targets.depth_buffer_id;
+ PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
+ return;
+ }
+
+ const bool rescaled = RescaleRenderTargets(is_clear);
if (is_rescaling != rescaled) {
flags[Dirty::RescaleViewports] = true;
flags[Dirty::RescaleScissors] = true;
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index eea589269..643ad811c 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -119,6 +119,11 @@ public:
/// Refresh the state for compute image view and sampler descriptors
void SynchronizeComputeDescriptors();
+ /// Updates the Render Targets if they can be rescaled
+ /// @param is_clear True when the render targets are being used for clears
+ /// @retval True if the Render Targets have been rescaled.
+ bool RescaleRenderTargets(bool is_clear);
+
/// Update bound render targets and upload memory if necessary
/// @param is_clear True when the render targets are being used for clears
void UpdateRenderTargets(bool is_clear);
--
cgit v1.2.3
From de1c8c5c2c3131bb122351e676014cdc7c442e78 Mon Sep 17 00:00:00 2001
From: FernandoS27
Date: Fri, 29 Oct 2021 17:02:57 +0200
Subject: Texture Cahe/Shader decompiler: Resize PointSize on rescaling,
refactor and make reaper more agressive on 4Gb GPUs.
---
src/video_core/texture_cache/image_base.h | 1 -
src/video_core/texture_cache/image_info.cpp | 6 +++---
src/video_core/texture_cache/texture_cache.h | 18 ++----------------
3 files changed, 5 insertions(+), 20 deletions(-)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 02c669766..89c111c00 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -38,7 +38,6 @@ enum class ImageFlagBits : u32 {
Rescaled = 1 << 12,
CheckingRescalable = 1 << 13,
IsRescalable = 1 << 14,
- Blacklisted = 1 << 15,
};
DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index d8e414247..015a2d33d 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -135,7 +135,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
type = ImageType::e3D;
size.depth = rt.depth;
} else {
- rescaleable = block.depth == 0 && size.height > 256;
+ rescaleable = block.depth == 0;
downscaleable = size.height > 512;
type = ImageType::e2D;
resources.layers = rt.depth;
@@ -165,7 +165,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
type = ImageType::e3D;
size.depth = regs.zeta_depth;
} else {
- rescaleable = block.depth == 0 && size.height > 256;
+ rescaleable = block.depth == 0;
downscaleable = size.height > 512;
type = ImageType::e2D;
resources.layers = regs.zeta_depth;
@@ -199,7 +199,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
.height = config.height,
.depth = 1,
};
- rescaleable = block.depth == 0 && size.height > 256;
+ rescaleable = block.depth == 0;
downscaleable = size.height > 512;
}
}
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index c8031b695..aec130a32 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -53,8 +53,8 @@ TextureCache ::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
const auto device_memory = runtime.GetDeviceLocalMemory();
const u64 possible_expected_memory = (device_memory * 4) / 10;
const u64 possible_critical_memory = (device_memory * 7) / 10;
- expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY);
- critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY);
+ expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY - 256_MiB);
+ critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY - 512_MiB);
minimum_memory = 0;
} else {
// On OpenGL we can be more conservatives as the driver takes care.
@@ -355,7 +355,6 @@ void TextureCache ::FillImageViews(DescriptorTable ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
bool can_rescale = info.rescaleable;
bool any_rescaled = false;
- bool any_blacklisted = false;
for (const ImageId sibling_id : all_siblings) {
if (!can_rescale) {
break;
@@ -993,7 +991,6 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
Image& sibling = slot_images[sibling_id];
can_rescale &= ImageCanRescale(sibling);
any_rescaled |= True(sibling.flags & ImageFlagBits::Rescaled);
- any_blacklisted |= True(sibling.flags & ImageFlagBits::Blacklisted);
}
can_rescale &= any_rescaled;
@@ -1007,9 +1004,6 @@ ImageId TextureCache ::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
for (const ImageId sibling_id : all_siblings) {
Image& sibling = slot_images[sibling_id];
ScaleDown(sibling);
- if (any_blacklisted) {
- sibling.flags |= ImageFlagBits::Blacklisted;
- }
}
}
@@ -1644,7 +1638,6 @@ void TextureCache ::SynchronizeAliases(ImageId image_id) {
boost::container::small_vector ::SynchronizeAliases(ImageId image_id) {
most_recent_tick = std::max(most_recent_tick, aliased_image.modification_tick);
aliased_images.push_back(&aliased);
any_rescaled |= True(aliased_image.flags & ImageFlagBits::Rescaled);
- any_blacklisted |= True(aliased_image.flags & ImageFlagBits::Blacklisted);
}
}
if (aliased_images.empty()) {
@@ -1664,9 +1656,6 @@ void TextureCache ::SynchronizeAliases(ImageId image_id) {
ScaleUp(image);
} else {
ScaleDown(image);
- if (any_blacklisted) {
- image.flags |= ImageFlagBits::Blacklisted;
- }
}
}
image.modification_tick = most_recent_tick;
@@ -1684,9 +1673,6 @@ void TextureCache ::SynchronizeAliases(ImageId image_id) {
Image& aliased_image = slot_images[aliased->id];
if (!can_rescale) {
ScaleDown(aliased_image);
- if (any_blacklisted) {
- aliased_image.flags |= ImageFlagBits::Blacklisted;
- }
CopyImage(image_id, aliased->id, aliased->copies);
continue;
}
--
cgit v1.2.3
From 6c97ab571a3d169d1d2a5472040d4373ea61184d Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Sat, 30 Oct 2021 01:50:32 +0200
Subject: Texture Cache: revert Image changes.
---
src/video_core/texture_cache/image_info.cpp | 4 ++++
1 file changed, 4 insertions(+)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 015a2d33d..afb94082b 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -16,6 +16,7 @@ namespace VideoCommon {
using Tegra::Texture::TextureType;
using Tegra::Texture::TICEntry;
using VideoCore::Surface::PixelFormat;
+using VideoCore::Surface::SurfaceType;
ImageInfo::ImageInfo(const TICEntry& config) noexcept {
format = PixelFormatFromTextureInfo(config.format, config.r_type, config.g_type, config.b_type,
@@ -102,6 +103,7 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
layer_stride = CalculateLayerStride(*this);
maybe_unaligned_layer_stride = CalculateLayerSize(*this);
rescaleable &= (block.depth == 0) && resources.levels == 1;
+ rescaleable &= size.height > 256 || GetFormatType(format) != SurfaceType::ColorTexture;
downscaleable = size.height > 512;
}
}
@@ -136,6 +138,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
size.depth = rt.depth;
} else {
rescaleable = block.depth == 0;
+ rescaleable &= size.height > 256;
downscaleable = size.height > 512;
type = ImageType::e2D;
resources.layers = rt.depth;
@@ -200,6 +203,7 @@ ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
.depth = 1,
};
rescaleable = block.depth == 0;
+ rescaleable &= size.height > 256;
downscaleable = size.height > 512;
}
}
--
cgit v1.2.3
From 978f598ff64d3bd0299d06c47e6cbd63a496122c Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow
Date: Wed, 17 Nov 2021 00:59:46 +0100
Subject: TextureCache: Fix OGL cleaning
---
src/video_core/texture_cache/texture_cache.h | 3 +++
1 file changed, 3 insertions(+)
(limited to 'src/video_core/texture_cache')
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index aec130a32..4d2874bf2 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1620,6 +1620,9 @@ void TextureCache ::RemoveFramebuffers(std::span