From 5b52849f901fbdfbdbb8a81728b3233307445d0c Mon Sep 17 00:00:00 2001 From: GPUCode <47210458+GPUCode@users.noreply.github.com> Date: Sun, 6 Aug 2023 22:59:54 +0300 Subject: [PATCH] rasterizer_cache: Allow custom recycle (#6851) * surface_params: Allow custom surface recycling * rasterizer_cache: Cleanup --- .../rasterizer_cache/rasterizer_cache.h | 85 ++++++------------- .../rasterizer_cache/rasterizer_cache_base.h | 5 +- .../rasterizer_cache/surface_base.h | 4 - .../rasterizer_cache/surface_params.cpp | 8 +- 4 files changed, 34 insertions(+), 68 deletions(-) diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.h b/src/video_core/rasterizer_cache/rasterizer_cache.h index e4c4fb86e..37abcae14 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache.h @@ -127,6 +127,29 @@ void RasterizerCache::RemoveFramebuffers(SurfaceId surface_id) { } } +template +void RasterizerCache::RemoveTextureCubeFace(SurfaceId surface_id) { + if (False(slot_surfaces[surface_id].flags & SurfaceFlagBits::Tracked)) { + return; + } + + for (auto it = texture_cube_cache.begin(); it != texture_cube_cache.end();) { + TextureCube& cube = it->second; + for (SurfaceId& face_id : cube.face_ids) { + if (face_id == surface_id) { + face_id = SurfaceId{}; + } + } + if (std::none_of(cube.face_ids.begin(), cube.face_ids.end(), + [](SurfaceId id) { return id; })) { + sentenced.emplace_back(cube.surface_id, frame_tick); + it = texture_cube_cache.erase(it); + } else { + it++; + } + } +} + template bool RasterizerCache::AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) { const DebugScope scope{runtime, Common::Vec4f{0.f, 0.f, 1.f, 1.f}, @@ -866,39 +889,6 @@ SurfaceId RasterizerCache::FindMatch(const SurfaceParams& params, ScaleMatch return match_id; } -template -void RasterizerCache::DuplicateSurface(SurfaceId src_id, SurfaceId dst_id) { - Surface& src_surface = slot_surfaces[src_id]; - Surface& dst_surface = slot_surfaces[dst_id]; - ASSERT(dst_surface.addr <= src_surface.addr && dst_surface.end >= src_surface.end); - - const auto src_rect = src_surface.GetScaledRect(); - const auto dst_rect = dst_surface.GetScaledSubRect(src_surface); - ASSERT(src_rect.GetWidth() == dst_rect.GetWidth()); - - const TextureCopy copy = { - .src_level = 0, - .dst_level = 0, - .src_offset = {src_rect.left, src_rect.bottom}, - .dst_offset = {dst_rect.left, dst_rect.bottom}, - .extent = {src_rect.GetWidth(), src_rect.GetHeight()}, - }; - runtime.CopyTextures(src_surface, dst_surface, copy); - - dst_surface.invalid_regions -= src_surface.GetInterval(); - dst_surface.invalid_regions += src_surface.invalid_regions; - - SurfaceRegions regions; - for (const auto& pair : RangeFromInterval(dirty_regions, src_surface.GetInterval())) { - if (pair.second == src_id) { - regions += pair.first; - } - } - for (const auto& interval : regions) { - dirty_regions.set({interval, dst_id}); - } -} - template void RasterizerCache::ValidateSurface(SurfaceId surface_id, PAddr addr, u32 size) { if (size == 0) [[unlikely]] { @@ -1057,6 +1047,7 @@ bool RasterizerCache::UploadCustomSurface(SurfaceId surface_id, SurfaceInterv const SurfaceBase old_surface{slot_surfaces[surface_id]}; const SurfaceId old_id = slot_surfaces.swap_and_insert(surface_id, runtime, old_surface, material); + slot_surfaces[old_id].flags &= ~SurfaceFlagBits::Registered; sentenced.emplace_back(old_id, frame_tick); } Surface& surface = slot_surfaces[surface_id]; @@ -1203,7 +1194,6 @@ void RasterizerCache::ClearAll(bool flush) { cached_pages -= flush_interval; dirty_regions.clear(); page_table.clear(); - remove_surfaces.clear(); } template @@ -1232,7 +1222,7 @@ void RasterizerCache::FlushRegion(PAddr addr, u32 size, SurfaceId flush_surfa interval.lower(), interval.upper()}; SCOPE_EXIT({ flushed_intervals += interval; }); - if (surface.IsFill()) { + if (surface.type == SurfaceType::Fill) { DownloadFillSurface(surface, interval); continue; } @@ -1274,6 +1264,7 @@ void RasterizerCache::InvalidateRegion(PAddr addr, u32 size, SurfaceId region region_owner.MarkValid(invalid_interval); } + boost::container::small_vector remove_surfaces; ForEachSurfaceInRegion(addr, size, [&](SurfaceId surface_id, Surface& surface) { if (surface_id == region_owner_id) { return; @@ -1301,13 +1292,12 @@ void RasterizerCache::InvalidateRegion(PAddr addr, u32 size, SurfaceId region for (const SurfaceId surface_id : remove_surfaces) { UnregisterSurface(surface_id); - if (!slot_surfaces[surface_id].IsFill()) { + if (slot_surfaces[surface_id].type != SurfaceType::Fill) { sentenced.emplace_back(surface_id, frame_tick); } else { slot_surfaces.erase(surface_id); } } - remove_surfaces.clear(); } template @@ -1367,25 +1357,7 @@ void RasterizerCache::UnregisterSurface(SurfaceId surface_id) { surfaces.erase(vector_it); }); - if (False(surface.flags & SurfaceFlagBits::Tracked)) { - return; - } - - for (auto it = texture_cube_cache.begin(); it != texture_cube_cache.end();) { - TextureCube& cube = it->second; - for (SurfaceId& face_id : cube.face_ids) { - if (face_id == surface_id) { - face_id = SurfaceId{}; - } - } - if (std::none_of(cube.face_ids.begin(), cube.face_ids.end(), - [](SurfaceId id) { return id; })) { - sentenced.emplace_back(cube.surface_id, frame_tick); - it = texture_cube_cache.erase(it); - } else { - it++; - } - } + RemoveTextureCubeFace(surface_id); } template @@ -1397,7 +1369,6 @@ void RasterizerCache::UnregisterAll() { } } texture_cube_cache.clear(); - remove_surfaces.clear(); } template diff --git a/src/video_core/rasterizer_cache/rasterizer_cache_base.h b/src/video_core/rasterizer_cache/rasterizer_cache_base.h index daed5f253..c8553e270 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache_base.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache_base.h @@ -165,8 +165,8 @@ private: /// Removes any framebuffers that reference the provided surface_id. void RemoveFramebuffers(SurfaceId surface_id); - /// Transfers ownership of a memory region from src_surface to dest_surface - void DuplicateSurface(SurfaceId src_id, SurfaceId dst_id); + /// Removes any references of the provided surface id from cached texture cubes. + void RemoveTextureCubeFace(SurfaceId surface_id); /// Computes the hash of the provided texture data. u64 ComputeHash(const SurfaceParams& load_info, std::span upload_data); @@ -224,7 +224,6 @@ private: Common::SlotVector slot_framebuffers; SurfaceMap dirty_regions; PageMap cached_pages; - std::vector remove_surfaces; u32 resolution_scale_factor; u64 frame_tick{}; FramebufferParams fb_params; diff --git a/src/video_core/rasterizer_cache/surface_base.h b/src/video_core/rasterizer_cache/surface_base.h index c3bd7b432..19c0959da 100644 --- a/src/video_core/rasterizer_cache/surface_base.h +++ b/src/video_core/rasterizer_cache/surface_base.h @@ -46,10 +46,6 @@ public: /// Returns true if the surface contains a custom material with a normal map. bool HasNormalMap() const noexcept; - bool IsFill() const noexcept { - return type == SurfaceType::Fill; - } - bool Overlaps(PAddr overlap_addr, size_t overlap_size) const noexcept { const PAddr overlap_end = overlap_addr + static_cast(overlap_size); return addr < overlap_end && overlap_addr < end; diff --git a/src/video_core/rasterizer_cache/surface_params.cpp b/src/video_core/rasterizer_cache/surface_params.cpp index 74ae8205c..fc7f43263 100644 --- a/src/video_core/rasterizer_cache/surface_params.cpp +++ b/src/video_core/rasterizer_cache/surface_params.cpp @@ -228,10 +228,10 @@ std::string SurfaceParams::DebugName(bool scaled, bool custom) const noexcept { } bool SurfaceParams::operator==(const SurfaceParams& other) const noexcept { - return std::tie(addr, end, width, height, stride, levels, is_tiled, texture_type, pixel_format, - custom_format) == - std::tie(other.addr, other.end, other.width, other.height, other.stride, other.levels, - other.is_tiled, other.texture_type, other.pixel_format, other.custom_format); + return std::tie(addr, end, width, height, stride, levels, is_tiled, texture_type, + pixel_format) == std::tie(other.addr, other.end, other.width, other.height, + other.stride, other.levels, other.is_tiled, + other.texture_type, other.pixel_format); } } // namespace VideoCore