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/texture_cache.h | 113 ++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 2 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 tmp_color_images{}; + ImageId tmp_depth_image{}; + const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) { + if (view_id) { + const auto& view = slot_image_views[view_id]; + const auto image_id = view.image_id; + id_save = image_id; + auto& image = slot_images[image_id]; + can_rescale &= ImageCanRescale(image); + } else { + id_save = CORRUPT_ID; + } + }; for (size_t index = 0; index < NUM_RT; ++index) { ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; if (flags[Dirty::ColorBuffer0 + index] || force) { flags[Dirty::ColorBuffer0 + index] = false; BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear)); } - PrepareImageView(color_buffer_id, true, is_clear && IsFullClear(color_buffer_id)); + check_rescale(color_buffer_id, tmp_color_images[index]); } if (flags[Dirty::ZetaBuffer] || force) { flags[Dirty::ZetaBuffer] = false; BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear)); } + check_rescale(render_targets.depth_buffer_id, tmp_depth_image); + + if (can_rescale) { + const auto scale_up = [this](ImageId image_id) { + if (image_id != CORRUPT_ID) { + Image& image = slot_images[image_id]; + image.ScaleUp(); + } + }; + for (size_t index = 0; index < NUM_RT; ++index) { + scale_up(tmp_color_images[index]); + } + 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(); + } + }; + for (size_t index = 0; index < NUM_RT; ++index) { + scale_down(tmp_color_images[index]); + } + scale_down(tmp_depth_image); + } + // Rescale End + + 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)); @@ -623,6 +670,31 @@ ImageId TextureCache

::FindImage(const ImageInfo& info, GPUVAddr gpu_addr, return image_id; } +template +bool TextureCache

::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 ImageId TextureCache

::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 right_aliased_ids; std::unordered_set ignore_textures; std::vector bad_overlap_ids; + std::vector all_siblings; + const bool this_is_linear = info.type == ImageType::Linear; const auto region_check = [&](ImageId overlap_id, ImageBase& overlap) { if (True(overlap.flags & ImageFlagBits::Remapped)) { ignore_textures.insert(overlap_id); return; } - if (info.type == ImageType::Linear) { + const bool overlap_is_linear = overlap.info.type == ImageType::Linear; + if (this_is_linear != overlap_is_linear) { + return; + } + if (this_is_linear && overlap_is_linear) { if (info.pitch == overlap.info.pitch && gpu_addr == overlap.gpu_addr) { // Alias linear images with the same pitch left_aliased_ids.push_back(overlap_id); @@ -681,6 +759,7 @@ ImageId TextureCache

::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; -- 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/texture_cache.h | 84 +++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 13 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 560da4f16..95a9e8fe9 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -242,24 +242,36 @@ void TextureCache

::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 +void TextureCache

::InvalidateScale(Image& image, bool invalidate_rt) { + const std::span image_view_ids = image.image_view_ids; + if (invalidate_rt) { + auto& dirty = maxwell3d.dirty.flags; + dirty[Dirty::RenderTargets] = true; + dirty[Dirty::ZetaBuffer] = true; + for (size_t rt = 0; rt < NUM_RT; ++rt) { + dirty[Dirty::ColorBuffer0 + rt] = true; + } + for (const ImageViewId image_view_id : image_view_ids) { + std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{}); + if (render_targets.depth_buffer_id == image_view_id) { + render_targets.depth_buffer_id = ImageViewId{}; + } + } + } + RemoveImageViewReferences(image_view_ids); + RemoveFramebuffers(image_view_ids); +} + +template +bool TextureCache

::ScaleUp(Image& image, bool invalidate_rt) { + const bool rescaled = image.ScaleUp(); + if (!rescaled) { + return false; + } + InvalidateScale(image, invalidate_rt); + return true; +} + +template +bool TextureCache

::ScaleDown(Image& image, bool invalidate_rt) { + const bool rescaled = image.ScaleDown(); + if (!rescaled) { + return false; + } + InvalidateScale(image, invalidate_rt); + return true; +} + template ImageId TextureCache

::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) { -- 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 ++++++++++++++------------- 1 file changed, 83 insertions(+), 79 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 tmp_color_images{}; - ImageId tmp_depth_image{}; - const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) { - if (view_id) { - const auto& view = slot_image_views[view_id]; - const auto image_id = view.image_id; - id_save = image_id; - auto& image = slot_images[image_id]; - can_rescale &= ImageCanRescale(image); - } else { - id_save = CORRUPT_ID; - } - }; - for (size_t index = 0; index < NUM_RT; ++index) { - ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; - if (flags[Dirty::ColorBuffer0 + index] || force) { - flags[Dirty::ColorBuffer0 + index] = false; - BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear)); - } - check_rescale(color_buffer_id, tmp_color_images[index]); - } - if (flags[Dirty::ZetaBuffer] || force) { - flags[Dirty::ZetaBuffer] = false; - BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear)); - } - check_rescale(render_targets.depth_buffer_id, tmp_depth_image); - if (can_rescale) { - const auto scale_up = [this](ImageId image_id) { - if (image_id != CORRUPT_ID) { - Image& image = slot_images[image_id]; - return ScaleUp(image); + do { + flags[Dirty::RenderTargets] = false; + + has_deleted_images = 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 tmp_color_images{}; + ImageId tmp_depth_image{}; + const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) { + if (view_id) { + const auto& view = slot_image_views[view_id]; + const auto image_id = view.image_id; + id_save = image_id; + auto& image = slot_images[image_id]; + can_rescale &= ImageCanRescale(image); + } else { + id_save = CORRUPT_ID; } - return false; }; for (size_t index = 0; index < NUM_RT; ++index) { - if (scale_up(tmp_color_images[index])) { - BindRenderTarget(&render_targets.color_buffer_ids[index], - FindColorBuffer(index, is_clear)); + ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index]; + if (flags[Dirty::ColorBuffer0 + index] || force) { + flags[Dirty::ColorBuffer0 + index] = false; + BindRenderTarget(&color_buffer_id, FindColorBuffer(index, is_clear)); } + check_rescale(color_buffer_id, tmp_color_images[index]); } - if (scale_up(tmp_depth_image)) { + if (flags[Dirty::ZetaBuffer] || force) { + flags[Dirty::ZetaBuffer] = false; BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear)); } - } else { - const auto scale_down = [this](ImageId image_id) { - if (image_id != CORRUPT_ID) { - Image& image = slot_images[image_id]; - return ScaleDown(image); + check_rescale(render_targets.depth_buffer_id, tmp_depth_image); + + if (can_rescale) { + 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]); } - return false; - }; - for (size_t index = 0; index < NUM_RT; ++index) { - if (scale_down(tmp_color_images[index])) { - BindRenderTarget(&render_targets.color_buffer_ids[index], - FindColorBuffer(index, 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]; + ScaleDown(image); + } + }; + for (size_t index = 0; index < NUM_RT; ++index) { + scale_down(tmp_color_images[index]); } + scale_down(tmp_depth_image); } - if (scale_down(tmp_depth_image)) { - BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear)); - } - } + } while (has_deleted_images); // Rescale End for (size_t index = 0; index < NUM_RT; ++index) { @@ -708,43 +701,54 @@ bool TextureCache

::ImageCanRescale(Image& image) { } template -void TextureCache

::InvalidateScale(Image& image, bool invalidate_rt) { +void TextureCache

::InvalidateScale(Image& image) { const std::span image_view_ids = image.image_view_ids; - if (invalidate_rt) { - auto& dirty = maxwell3d.dirty.flags; - dirty[Dirty::RenderTargets] = true; - dirty[Dirty::ZetaBuffer] = true; - for (size_t rt = 0; rt < NUM_RT; ++rt) { - dirty[Dirty::ColorBuffer0 + rt] = true; - } - for (const ImageViewId image_view_id : image_view_ids) { - std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{}); - if (render_targets.depth_buffer_id == image_view_id) { - render_targets.depth_buffer_id = ImageViewId{}; - } + auto& dirty = maxwell3d.dirty.flags; + dirty[Dirty::RenderTargets] = true; + dirty[Dirty::ZetaBuffer] = true; + for (size_t rt = 0; rt < NUM_RT; ++rt) { + dirty[Dirty::ColorBuffer0 + rt] = true; + } + for (const ImageViewId image_view_id : image_view_ids) { + std::ranges::replace(render_targets.color_buffer_ids, image_view_id, ImageViewId{}); + if (render_targets.depth_buffer_id == image_view_id) { + render_targets.depth_buffer_id = ImageViewId{}; } } RemoveImageViewReferences(image_view_ids); RemoveFramebuffers(image_view_ids); + for (const ImageViewId image_view_id : image_view_ids) { + sentenced_image_view.Push(std::move(slot_image_views[image_view_id])); + slot_image_views.erase(image_view_id); + } + image.image_view_ids.clear(); + image.image_view_infos.clear(); + if constexpr (ENABLE_VALIDATION) { + std::ranges::fill(graphics_image_view_ids, CORRUPT_ID); + std::ranges::fill(compute_image_view_ids, CORRUPT_ID); + } + graphics_image_table.Invalidate(); + compute_image_table.Invalidate(); + has_deleted_images = true; } template -bool TextureCache

::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 -bool TextureCache

::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) { -- 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 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 #include "common/alignment.h" +#include "common/settings.h" #include "video_core/dirty_flags.h" #include "video_core/engines/kepler_compute.h" #include "video_core/texture_cache/image_view_base.h" @@ -205,6 +206,7 @@ void TextureCache

::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(maxwell3d.regs.rt_control.Map(index)); } + u32 up_scale = 1; + u32 down_shift = 0; + if (is_rescaling) { + up_scale = Settings::values.resolution_info.up_scale; + down_shift = Settings::values.resolution_info.down_shift; + } render_targets.size = Extent2D{ - maxwell3d.regs.render_area.width, - maxwell3d.regs.render_area.height, + (maxwell3d.regs.render_area.width * up_scale) >> down_shift, + (maxwell3d.regs.render_area.height * up_scale) >> down_shift, }; flags[Dirty::DepthBiasGlobal] = true; @@ -538,6 +554,11 @@ void TextureCache

::PopAsyncFlushes() { committed_downloads.pop(); } +template +bool TextureCache

::IsRescaling() { + return is_rescaling; +} + template bool TextureCache

::IsRegionGpuModified(VAddr addr, size_t size) { bool is_modified = false; -- 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 +++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 -void TextureCache

::CopyImage(ImageId dst_id, ImageId src_id, std::span copies) { +void TextureCache

::CopyImage(ImageId dst_id, ImageId src_id, std::vector copies) { Image& dst = slot_images[dst_id]; Image& src = slot_images[src_id]; + const bool is_rescaled = True(src.flags & ImageFlagBits::Rescaled); + if (is_rescaled) { + ASSERT(True(dst.flags & ImageFlagBits::Rescaled)); + const bool both_2d{src.info.type == ImageType::e2D && dst.info.type == ImageType::e2D}; + const auto& resolution = Settings::values.resolution_info; + const auto scale_up = [&](u32 value) -> u32 { + if (value == 0) { + return 0U; + } + return std::max((value * resolution.up_scale) >> resolution.down_shift, 1U); + }; + for (auto& copy : copies) { + copy.src_offset.x = scale_up(copy.src_offset.x); + + copy.dst_offset.x = scale_up(copy.dst_offset.x); + + copy.extent.width = scale_up(copy.extent.width); + if (both_2d) { + copy.src_offset.y = scale_up(copy.src_offset.y); + copy.dst_offset.y = scale_up(copy.dst_offset.y); + copy.extent.height = scale_up(copy.extent.height); + } + } + } const auto dst_format_type = GetFormatType(dst.info.format); const auto src_format_type = GetFormatType(src.info.format); if (src_format_type == dst_format_type) { @@ -1639,10 +1663,21 @@ std::pair TextureCache

::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((value * resolution.up_scale) >> resolution.down_shift, 1U); + }; + extent.width = scale_up(extent.width); + if (image.info.type == ImageType::e2D) { + extent.height = scale_up(extent.height); + } + } const u32 num_samples = image.info.num_samples; const auto [samples_x, samples_y] = SamplesLog2(num_samples); const FramebufferId framebuffer_id = GetFramebufferId(RenderTargets{ -- cgit v1.2.3 From dfc65cd0a3b259588b47db1d32c827e7fc071aeb Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 21 Jul 2021 10:15:09 +0200 Subject: Texture Cache: Implement Rescaling on Aliases and Blits. --- src/video_core/texture_cache/texture_cache.h | 58 +++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 5 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index df697cdeb..25fea8240 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -437,8 +437,32 @@ void TextureCache

::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((value * resolution.up_scale) >> resolution.down_shift, 1U); + }; + + const auto scale_region = [&](Region2D& region) { + region.start.x = scale_up(region.start.x); + region.start.y = scale_up(region.start.y); + region.end.x = scale_up(region.end.x); + region.end.y = scale_up(region.end.y); + }; // TODO: Deduplicate const std::optional src_base = src_image.TryFindBase(src.Address()); @@ -446,20 +470,26 @@ void TextureCache

::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 void TextureCache

::SynchronizeAliases(ImageId image_id) { boost::container::small_vector aliased_images; - ImageBase& image = slot_images[image_id]; + Image& image = slot_images[image_id]; + bool any_rescaled = True(image.flags & ImageFlagBits::Rescaled); u64 most_recent_tick = image.modification_tick; for (const AliasedImage& aliased : image.aliased_images) { ImageBase& aliased_image = slot_images[aliased.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); } } if (aliased_images.empty()) { return; } + const bool can_rescale = ImageCanRescale(image); + if (any_rescaled) { + if (can_rescale) { + ScaleUp(image); + } else { + ScaleDown(image); + } + } image.modification_tick = most_recent_tick; std::ranges::sort(aliased_images, [this](const AliasedImage* lhs, const AliasedImage* rhs) { const ImageBase& lhs_image = slot_images[lhs->id]; @@ -1533,6 +1573,14 @@ void TextureCache

::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 <52414509+ameerj@users.noreply.github.com> 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/texture_cache.h') 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 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 +const typename P::Image& TextureCache

::GetImage(ImageId id) const noexcept { + return slot_images[id]; +} + +template +typename P::Image& TextureCache

::GetImage(ImageId id) noexcept { + return slot_images[id]; +} + template void TextureCache

::MarkModification(ImageId id) noexcept { MarkModification(slot_images[id]); -- 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/texture_cache.h | 34 +++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 tmp_color_images{}; ImageId tmp_depth_image{}; const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) { @@ -236,6 +237,7 @@ 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); } 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 +bool TextureCache

::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 bool TextureCache

::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 aliased_images; Image& image = slot_images[image_id]; bool any_rescaled = True(image.flags & ImageFlagBits::Rescaled); + bool any_blacklisted = True(image.flags & ImageFlagBits::Blacklisted); u64 most_recent_tick = image.modification_tick; for (const AliasedImage& aliased : image.aliased_images) { ImageBase& aliased_image = slot_images[aliased.id]; @@ -1563,6 +1588,7 @@ void TextureCache

::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); -- 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/texture_cache.h | 42 ++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 12 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 tmp_color_images{}; + ImageId tmp_depth_image{}; do { flags[Dirty::RenderTargets] = false; @@ -226,10 +229,10 @@ void TextureCache

::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 tmp_color_images{}; - ImageId tmp_depth_image{}; const auto check_rescale = [&](ImageViewId view_id, ImageId& id_save) { if (view_id) { const auto& view = slot_image_views[view_id]; @@ -238,6 +241,10 @@ 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); + scale_rating = std::max(scale_rating, image.scale_tick <= frame_tick + ? image.scale_rating + 1U + : image.scale_rating); } else { id_save = CORRUPT_ID; } @@ -257,17 +264,19 @@ void TextureCache

::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/texture_cache.h | 47 ++++++++++++++++------------ 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index be40f6b88..4e97a9e6a 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -36,7 +36,6 @@ 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); @@ -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 -void TextureCache

::FillGraphicsImageViews(std::span indices, - std::span image_view_ids) { - FillImageViews(graphics_image_table, graphics_image_view_ids, indices, image_view_ids); +template +void TextureCache

::FillGraphicsImageViews(std::span views) { + FillImageViews(graphics_image_table, graphics_image_view_ids, views); } template -void TextureCache

::FillComputeImageViews(std::span indices, - std::span image_view_ids) { - FillImageViews(compute_image_table, compute_image_view_ids, indices, image_view_ids); +void TextureCache

::FillComputeImageViews(std::span views) { + FillImageViews(compute_image_table, compute_image_view_ids, views); } template @@ -346,17 +345,26 @@ typename P::Framebuffer* TextureCache

::GetFramebuffer() { } template +template void TextureCache

::FillImageViews(DescriptorTable& table, std::span cached_image_view_ids, - std::span indices, - std::span image_view_ids) { - ASSERT(indices.size() <= image_view_ids.size()); + std::span views) { + bool has_blacklisted; do { has_deleted_images = false; - std::ranges::transform(indices, image_view_ids.begin(), [&](u32 index) { - return VisitImageView(table, cached_image_view_ids, index); - }); - } while (has_deleted_images); + if constexpr (has_blacklists) { + has_blacklisted = false; + } + for (ImageViewInOut& view : views) { + view.id = VisitImageView(table, cached_image_view_ids, view.index); + if constexpr (has_blacklists) { + if (view.blacklist && view.id != NULL_IMAGE_VIEW_ID) { + const ImageViewBase& image_view{slot_image_views[view.id]}; + has_blacklisted |= BlackListImage(image_view.image_id); + } + } + } + } while (has_deleted_images || (has_blacklists && has_blacklisted)); } template @@ -622,7 +630,7 @@ void TextureCache

::PopAsyncFlushes() { } template -bool TextureCache

::IsRescaling() { +bool TextureCache

::IsRescaling() const noexcept { return is_rescaling; } @@ -775,12 +783,11 @@ bool TextureCache

::BlackListImage(ImageId image_id) { } template -bool TextureCache

::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) { -- cgit v1.2.3 From 2182d2575010a5a85c99c09c6a1c57962242444d Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 28 Jul 2021 02:53:24 -0300 Subject: texture_cache: Fix blacklists on compute --- src/video_core/texture_cache/texture_cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 4e97a9e6a..4dbded635 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -142,7 +142,7 @@ void TextureCache

::FillGraphicsImageViews(std::span views) { template void TextureCache

::FillComputeImageViews(std::span views) { - FillImageViews(compute_image_table, compute_image_view_ids, views); + FillImageViews(compute_image_table, compute_image_view_ids, views); } template -- cgit v1.2.3 From c7a1cbad44487b2c5f9da31ce6d3c76b7dec4f05 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 31 Jul 2021 17:42:37 -0300 Subject: texture_cache: Add getter to query if image view is rescaled --- src/video_core/texture_cache/texture_cache.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 4dbded635..0e70c4db2 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -119,16 +119,6 @@ typename P::ImageView& TextureCache

::GetImageView(ImageViewId id) noexcept { return slot_image_views[id]; } -template -const typename P::Image& TextureCache

::GetImage(ImageId id) const noexcept { - return slot_images[id]; -} - -template -typename P::Image& TextureCache

::GetImage(ImageId id) noexcept { - return slot_images[id]; -} - template void TextureCache

::MarkModification(ImageId id) noexcept { MarkModification(slot_images[id]); @@ -634,6 +624,12 @@ bool TextureCache

::IsRescaling() const noexcept { return is_rescaling; } +template +bool TextureCache

::IsRescaling(const ImageViewBase& image_view) const noexcept { + const ImageBase& image = slot_images[image_view.image_id]; + return True(image.flags & ImageFlagBits::Rescaled); +} + template bool TextureCache

::IsRegionGpuModified(VAddr addr, size_t size) { bool is_modified = false; -- cgit v1.2.3 From ed675cfd8cc89d64c763becfd991d1dd40deac5a Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> 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/texture_cache.h') 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/texture_cache.h') 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/texture_cache.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 bool TextureCache

::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 19ca0c9ab5cbaa86e30743ea760e0aab5c40c1d6 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 20 Sep 2021 19:11:03 +0200 Subject: TextureCache: Base fixes on rescaling. --- src/video_core/texture_cache/texture_cache.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 764984546..a543776fd 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -205,8 +205,8 @@ void TextureCache

::UpdateRenderTargets(bool is_clear) { return; } - u32 scale_rating; - bool rescaled; + u32 scale_rating = 0; + bool rescaled = false; std::array tmp_color_images{}; ImageId tmp_depth_image{}; do { @@ -223,7 +223,7 @@ void TextureCache

::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/texture_cache.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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/texture_cache.h') 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( + std::max(image.guest_size_bytes, image.unswizzled_size_bytes) * std::abs(add_to_size)); + const u64 fitted_size = Common::AlignUp(tentative_size, 1024); + total_used_memory += sign ? -fitted_size : fitted_size; InvalidateScale(image); return true; } @@ -868,6 +874,12 @@ bool TextureCache

::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( + std::max(image.guest_size_bytes, image.unswizzled_size_bytes) * std::abs(add_to_size)); + const u64 fitted_size = Common::AlignUp(tentative_size, 1024); + total_used_memory += sign ? fitted_size : -fitted_size; InvalidateScale(image); return true; } -- cgit v1.2.3 From 88ef04dbaf26ab83ec85bfa3c68434c283c66e50 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 5 Oct 2021 00:07:51 -0400 Subject: texture_cache: Refactor scaled image size calculation --- src/video_core/texture_cache/texture_cache.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 691198853..b708e41b5 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -852,18 +852,23 @@ void TextureCache

::InvalidateScale(Image& image) { has_deleted_images = true; } +template +u64 TextureCache

::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(image_size_bytes * std::abs(add_to_size)); + const u64 fitted_size = Common::AlignUp(tentative_size, 1024); + return sign ? -fitted_size : fitted_size; +} + template bool TextureCache

::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( - std::max(image.guest_size_bytes, image.unswizzled_size_bytes) * std::abs(add_to_size)); - const u64 fitted_size = Common::AlignUp(tentative_size, 1024); - total_used_memory += sign ? -fitted_size : fitted_size; + total_used_memory += GetScaledImageSizeBytes(image); InvalidateScale(image); return true; } @@ -874,12 +879,7 @@ bool TextureCache

::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( - std::max(image.guest_size_bytes, image.unswizzled_size_bytes) * std::abs(add_to_size)); - const u64 fitted_size = Common::AlignUp(tentative_size, 1024); - total_used_memory += sign ? fitted_size : -fitted_size; + total_used_memory += GetScaledImageSizeBytes(image); InvalidateScale(image); return true; } -- cgit v1.2.3 From 31478c6c1b841b9a820742830b136775fafe270f Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Wed, 6 Oct 2021 01:18:00 -0400 Subject: video_core: Misc resolution scaling related refactoring --- src/video_core/texture_cache/texture_cache.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index b708e41b5..630c73005 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1726,9 +1726,7 @@ void TextureCache

::CopyImage(ImageId dst_id, ImageId src_id, std::vector Date: Wed, 6 Oct 2021 02:02:05 -0400 Subject: vk_texture_cache: Fix early returns on unsupported scales --- src/video_core/texture_cache/texture_cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 630c73005..de522cc43 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -857,7 +857,7 @@ u64 TextureCache

::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(image_size_bytes * std::abs(add_to_size)); + const u64 tentative_size = image_size_bytes * static_cast(std::abs(add_to_size)); const u64 fitted_size = Common::AlignUp(tentative_size, 1024); return sign ? -fitted_size : fitted_size; } -- cgit v1.2.3 From b14f2c7c826b8bbea02c1f2674ab024a5ae0695e Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Mon, 11 Oct 2021 23:55:53 -0400 Subject: texture_cache: Fix image resolves when src/dst are not both scaled --- src/video_core/texture_cache/texture_cache.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index de522cc43..38895c2e9 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -475,12 +475,10 @@ 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); + 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((value * resolution.up_scale) >> resolution.down_shift, 1U); }; - const auto scale_region = [&](Region2D& region) { region.start.x = scale_up(region.start.x); region.start.y = scale_up(region.start.y); -- cgit v1.2.3 From abd07e41582b6d8f7efdedb936cdd7a7fddf9912 Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 12 Oct 2021 00:35:01 -0400 Subject: video_core: Refactor resolution scale function --- src/video_core/texture_cache/texture_cache.h | 39 +++++++++------------------- 1 file changed, 12 insertions(+), 27 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 38895c2e9..c77332b46 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -504,17 +504,11 @@ void TextureCache

::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((value * resolution.up_scale) >> resolution.down_shift, 1U); - }; const auto scale_region = [&](Region2D& region) { - region.start.x = scale_up(region.start.x); - region.start.y = scale_up(region.start.y); - region.end.x = scale_up(region.end.x); - region.end.y = scale_up(region.end.y); + region.start.x = resolution.ScaleUp(region.start.x); + region.start.y = resolution.ScaleUp(region.start.y); + region.end.x = resolution.ScaleUp(region.end.x); + region.end.y = resolution.ScaleUp(region.end.y); }; // TODO: Deduplicate @@ -1721,20 +1715,14 @@ void TextureCache

::CopyImage(ImageId dst_id, ImageId src_id, std::vector u32 { - if (value == 0) { - return 0U; - } - return std::max((value * resolution.up_scale) >> resolution.down_shift, 1U); - }; for (auto& copy : copies) { - copy.src_offset.x = scale_up(copy.src_offset.x); - copy.dst_offset.x = scale_up(copy.dst_offset.x); - copy.extent.width = scale_up(copy.extent.width); + copy.src_offset.x = resolution.ScaleUp(copy.src_offset.x); + copy.dst_offset.x = resolution.ScaleUp(copy.dst_offset.x); + copy.extent.width = resolution.ScaleUp(copy.extent.width); if (both_2d) { - copy.src_offset.y = scale_up(copy.src_offset.y); - copy.dst_offset.y = scale_up(copy.dst_offset.y); - copy.extent.height = scale_up(copy.extent.height); + copy.src_offset.y = resolution.ScaleUp(copy.src_offset.y); + copy.dst_offset.y = resolution.ScaleUp(copy.dst_offset.y); + copy.extent.height = resolution.ScaleUp(copy.extent.height); } } } @@ -1812,12 +1800,9 @@ std::pair TextureCache

::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((value * resolution.up_scale) >> resolution.down_shift, 1U); - }; - extent.width = scale_up(extent.width); + extent.width = resolution.ScaleUp(extent.width); if (image.info.type == ImageType::e2D) { - extent.height = scale_up(extent.height); + extent.height = resolution.ScaleUp(extent.height); } } const u32 num_samples = image.info.num_samples; -- cgit v1.2.3 From 4de584005fe8ae00608f8c3267a78e7cf0eb52aa Mon Sep 17 00:00:00 2001 From: ameerj <52414509+ameerj@users.noreply.github.com> Date: Tue, 12 Oct 2021 01:45:54 -0400 Subject: texture_cache: Fix infinitely recursive ImageCanRescale check --- src/video_core/texture_cache/texture_cache.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index c77332b46..c1fb12679 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -795,25 +795,25 @@ bool TextureCache

::BlackListImage(ImageId image_id) { template bool TextureCache

::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 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/texture_cache.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/video_core/texture_cache/texture_cache.h') 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/texture_cache.h') 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(scale_rating, image.scale_tick <= frame_tick ? image.scale_rating + 1U : image.scale_rating); @@ -857,7 +858,7 @@ u64 TextureCache

::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(std::abs(add_to_size)); + const u64 tentative_size = image_size_bytes * static_cast(std::abs(add_to_size)); const u64 fitted_size = Common::AlignUp(tentative_size, 1024); return sign ? -fitted_size : fitted_size; } @@ -879,7 +880,7 @@ bool TextureCache

::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/texture_cache.h') 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 Date: Sun, 17 Oct 2021 18:01:18 +0200 Subject: Texture Cache: Fix downscaling and correct memory comsumption. --- src/video_core/texture_cache/texture_cache.h | 31 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index a035d2b18..cf0d33a45 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -854,8 +854,8 @@ void TextureCache

::InvalidateScale(Image& image) { } template -u64 TextureCache

::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(std::abs(add_to_size)); @@ -865,11 +865,14 @@ u64 TextureCache

::GetScaledImageSizeBytes(Image& image) { template bool TextureCache

::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 void TextureCache

::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; -- 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 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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(scale_rating, image.scale_tick <= frame_tick @@ -270,20 +268,17 @@ void TextureCache

::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& table, if constexpr (has_blacklists) { if (view.blacklist && view.id != NULL_IMAGE_VIEW_ID) { const ImageViewBase& image_view{slot_image_views[view.id]}; - has_blacklisted |= BlackListImage(image_view.image_id); + auto& image = slot_images[image_view.image_id]; + image.flags |= ImageFlagBits::Blacklisted; + has_blacklisted |= ScaleDown(image); + image.scale_rating = 0; } } } @@ -783,20 +781,9 @@ ImageId TextureCache

::FindImage(const ImageInfo& info, GPUVAddr gpu_addr, return image_id; } -template -bool TextureCache

::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 bool TextureCache

::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) { -- 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/texture_cache.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 void TextureCache

::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 void TextureCache

::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 ++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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( + (copy.extent.width * resolution.up_scale) >> resolution.down_shift, 1); + if (both_2d) { + copy.extent.height = std::max( + (copy.extent.height * resolution.up_scale) >> resolution.down_shift, 1); } } - CopyImage(image_id, aliased->id, aliased->copies); + CopyImage(image_id, aliased->id, copies); } } -- cgit v1.2.3 From bf01b7993dca835a516abdc2142be96bc0f216ec Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Wed, 20 Oct 2021 23:21:52 +0200 Subject: TextureCache: Improve Reaper. --- src/video_core/texture_cache/texture_cache.h | 38 ++++++++++++++++++---------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index a32c11d04..f1254ef62 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -51,8 +51,8 @@ TextureCache

::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 void TextureCache

::InvalidateScale(Image& image) { + if (image.scale_tick <= frame_tick) { + image.scale_tick = frame_tick + 1; + } const std::span image_view_ids = image.image_view_ids; auto& dirty = maxwell3d.dirty.flags; dirty[Dirty::RenderTargets] = true; @@ -842,12 +847,15 @@ void TextureCache

::InvalidateScale(Image& image) { template 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(std::abs(add_to_size)); + const u64 scale_up = static_cast(Settings::values.resolution_info.up_scale * + Settings::values.resolution_info.up_scale); + const u64 down_shift = static_cast(Settings::values.resolution_info.down_shift + + Settings::values.resolution_info.down_shift); + const u64 image_size_bytes = + static_cast(std::max(image.guest_size_bytes, image.unswizzled_size_bytes)); + const u64 tentative_size = (image_size_bytes * scale_up) >> down_shift; const u64 fitted_size = Common::AlignUp(tentative_size, 1024); - return sign ? -fitted_size : fitted_size; + return fitted_size; } template @@ -1510,7 +1518,7 @@ void TextureCache

::UntrackImage(ImageBase& image, ImageId image_id) { } template -void TextureCache

::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); -- cgit v1.2.3 From 5c6fa8893589fd70bc743c0d0b77c0c375b24bd3 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 23 Oct 2021 01:52:34 +0200 Subject: OpenGlTextureCache: Fix state invalidation on rescaling. --- src/video_core/texture_cache/texture_cache.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index f1254ef62..dd9553806 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -1810,8 +1810,8 @@ void TextureCache

::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/texture_cache.h') 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 <52414509+ameerj@users.noreply.github.com> 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 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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 -void TextureCache

::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 tmp_color_images{}; @@ -281,8 +270,6 @@ void TextureCache

::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 +void TextureCache

::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; -- 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/texture_cache.h | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'src/video_core/texture_cache/texture_cache.h') 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& table, if (view.blacklist && view.id != NULL_IMAGE_VIEW_ID) { const ImageViewBase& image_view{slot_image_views[view.id]}; auto& image = slot_images[image_view.image_id]; - image.flags |= ImageFlagBits::Blacklisted; has_blacklisted |= ScaleDown(image); image.scale_rating = 0; } @@ -985,7 +984,6 @@ ImageId TextureCache

::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 aliased_images; Image& image = slot_images[image_id]; bool any_rescaled = True(image.flags & ImageFlagBits::Rescaled); - bool any_blacklisted = True(image.flags & ImageFlagBits::Blacklisted); u64 most_recent_tick = image.modification_tick; for (const AliasedImage& aliased : image.aliased_images) { ImageBase& aliased_image = slot_images[aliased.id]; @@ -1652,7 +1645,6 @@ void TextureCache

::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 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/texture_cache.h') 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 removed_vi auto it = framebuffers.begin(); while (it != framebuffers.end()) { if (it->first.Contains(removed_views)) { + auto framebuffer_id = it->second; + ASSERT(framebuffer_id); + sentenced_framebuffers.Push(std::move(slot_framebuffers[framebuffer_id])); it = framebuffers.erase(it); } else { ++it; -- cgit v1.2.3