From db7cdb741c5ded6c09037fe7f664489288f19478 Mon Sep 17 00:00:00 2001 From: emufan4568 Date: Tue, 6 Sep 2022 21:01:15 +0300 Subject: [PATCH] video_core: Move UpdatePagesCachedCount to RasterizerAccelerated --- src/video_core/CMakeLists.txt | 2 + src/video_core/rasterizer_accelerated.cpp | 74 +++++++++++++++++++ src/video_core/rasterizer_accelerated.h | 19 +++++ .../rasterizer_cache/rasterizer_cache.cpp | 42 ++--------- .../rasterizer_cache/rasterizer_cache.h | 10 ++- src/video_core/rasterizer_interface.h | 7 +- .../renderer_opengl/gl_rasterizer.h | 4 +- 7 files changed, 114 insertions(+), 44 deletions(-) create mode 100644 src/video_core/rasterizer_accelerated.cpp create mode 100644 src/video_core/rasterizer_accelerated.h diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 6685e26d3..25e5613be 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -13,6 +13,8 @@ add_library(video_core STATIC precompiled_headers.h primitive_assembly.cpp primitive_assembly.h + rasterizer_accelerated.cpp + rasterizer_accelerated.h rasterizer_interface.h regs.cpp regs.h diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp new file mode 100644 index 000000000..e0d25cca5 --- /dev/null +++ b/src/video_core/rasterizer_accelerated.cpp @@ -0,0 +1,74 @@ +// Copyright 2022 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "core/memory.h" +#include "video_core/video_core.h" +#include "video_core/rasterizer_accelerated.h" + +namespace VideoCore { + +void RasterizerAccelerated::UpdatePagesCachedCount(PAddr addr, u32 size, int delta) { + const u32 page_start = addr >> Memory::CITRA_PAGE_BITS; + const u32 page_end = ((addr + size - 1) >> Memory::CITRA_PAGE_BITS); + + u32 uncache_start_addr = 0; + u32 cache_start_addr = 0; + u32 uncache_bytes = 0; + u32 cache_bytes = 0; + + for (u32 page = page_start; page != page_end; page++) { + auto& count = cached_pages.at(page); + + // Ensure no overflow happens + if (delta > 0) { + ASSERT_MSG(count < std::numeric_limits::max(), "Count will overflow!"); + } else if (delta < 0) { + ASSERT_MSG(count > 0, "Count will underflow!"); + } else { + ASSERT_MSG(false, "Delta must be non-zero!"); + } + + // Adds or subtracts 1, as count is a unsigned 8-bit value + count += delta; + + // Assume delta is either -1 or 1 + if (count == 0) { + if (uncache_bytes == 0) { + uncache_start_addr = page << Memory::CITRA_PAGE_BITS; + } + + uncache_bytes += Memory::CITRA_PAGE_SIZE; + } else if (uncache_bytes > 0) { + VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes, + false); + uncache_bytes = 0; + } + + if (count == 1 && delta > 0) { + if (cache_bytes == 0) { + cache_start_addr = page << Memory::CITRA_PAGE_BITS; + } + + cache_bytes += Memory::CITRA_PAGE_SIZE; + } else if (cache_bytes > 0) { + VideoCore::g_memory->RasterizerMarkRegionCached(cache_start_addr, cache_bytes, + true); + + cache_bytes = 0; + } + } + + if (uncache_bytes > 0) { + VideoCore::g_memory->RasterizerMarkRegionCached(uncache_start_addr, uncache_bytes, + false); + } + + if (cache_bytes > 0) { + VideoCore::g_memory->RasterizerMarkRegionCached(cache_start_addr, cache_bytes, + true); + } +} + +} // namespace VideoCore diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h new file mode 100644 index 000000000..4f3860966 --- /dev/null +++ b/src/video_core/rasterizer_accelerated.h @@ -0,0 +1,19 @@ +// Copyright 2022 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once +#include "video_core/rasterizer_interface.h" + +namespace VideoCore { + +class RasterizerAccelerated : public RasterizerInterface { +public: + virtual ~RasterizerAccelerated() = default; + + void UpdatePagesCachedCount(PAddr addr, u32 size, int delta) override; + +private: + std::array cached_pages; +}; +} // namespace VideoCore diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.cpp b/src/video_core/rasterizer_cache/rasterizer_cache.cpp index 394bcca00..b92184503 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.cpp +++ b/src/video_core/rasterizer_cache/rasterizer_cache.cpp @@ -8,6 +8,7 @@ #include "common/logging/log.h" #include "common/microprofile.h" #include "video_core/pica_state.h" +#include "video_core/rasterizer_accelerated.h" #include "video_core/rasterizer_cache/rasterizer_cache.h" #include "video_core/renderer_opengl/gl_format_reinterpreter.h" #include "video_core/renderer_opengl/texture_downloader_es.h" @@ -239,7 +240,8 @@ static Surface FindMatch(const SurfaceCache& surface_cache, const SurfaceParams& return match_surface; } -RasterizerCacheOpenGL::RasterizerCacheOpenGL() { +RasterizerCacheOpenGL::RasterizerCacheOpenGL(VideoCore::RasterizerAccelerated& rasterizer) + : rasterizer(rasterizer) { resolution_scale_factor = VideoCore::GetResolutionScaleFactor(); texture_filterer = std::make_unique( Settings::values.texture_filter_name.GetValue(), resolution_scale_factor); @@ -1055,7 +1057,7 @@ void RasterizerCacheOpenGL::RegisterSurface(const Surface& surface) { } surface->registered = true; surface_cache.add({surface->GetInterval(), SurfaceSet{surface}}); - UpdatePagesCachedCount(surface->addr, surface->size, 1); + rasterizer.UpdatePagesCachedCount(surface->addr, surface->size, 1); } void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { @@ -1065,42 +1067,8 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { return; } surface->registered = false; - UpdatePagesCachedCount(surface->addr, surface->size, -1); + rasterizer.UpdatePagesCachedCount(surface->addr, surface->size, -1); surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}}); } -void RasterizerCacheOpenGL::UpdatePagesCachedCount(PAddr addr, u32 size, int delta) { - const u32 num_pages = - ((addr + size - 1) >> Memory::CITRA_PAGE_BITS) - (addr >> Memory::CITRA_PAGE_BITS) + 1; - const u32 page_start = addr >> Memory::CITRA_PAGE_BITS; - const u32 page_end = page_start + num_pages; - - // Interval maps will erase segments if count reaches 0, so if delta is negative we have to - // subtract after iterating - const auto pages_interval = PageMap::interval_type::right_open(page_start, page_end); - if (delta > 0) - cached_pages.add({pages_interval, delta}); - - for (const auto& pair : RangeFromInterval(cached_pages, pages_interval)) { - const auto interval = pair.first & pages_interval; - const int count = pair.second; - - const PAddr interval_start_addr = boost::icl::first(interval) << Memory::CITRA_PAGE_BITS; - const PAddr interval_end_addr = boost::icl::last_next(interval) << Memory::CITRA_PAGE_BITS; - const u32 interval_size = interval_end_addr - interval_start_addr; - - if (delta > 0 && count == delta) - VideoCore::g_memory->RasterizerMarkRegionCached(interval_start_addr, interval_size, - true); - else if (delta < 0 && count == -delta) - VideoCore::g_memory->RasterizerMarkRegionCached(interval_start_addr, interval_size, - false); - else - ASSERT(count >= 0); - } - - if (delta < 0) - cached_pages.add({pages_interval, delta}); -} - } // namespace OpenGL diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.h b/src/video_core/rasterizer_cache/rasterizer_cache.h index 2305dff86..7274a3521 100644 --- a/src/video_core/rasterizer_cache/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache/rasterizer_cache.h @@ -9,6 +9,10 @@ #include "video_core/rasterizer_cache/surface_params.h" #include "video_core/texture/texture_decode.h" +namespace VideoCore { +class RasterizerAccelerated; +} + namespace OpenGL { enum class ScaleMatch { @@ -23,7 +27,7 @@ class FormatReinterpreterOpenGL; class RasterizerCacheOpenGL : NonCopyable { public: - RasterizerCacheOpenGL(); + RasterizerCacheOpenGL(VideoCore::RasterizerAccelerated& rasterizer); ~RasterizerCacheOpenGL(); /// Blit one surface's texture to another @@ -105,9 +109,7 @@ private: /// Remove surface from the cache void UnregisterSurface(const Surface& surface); - /// Increase/decrease the number of surface in pages touching the specified region - void UpdatePagesCachedCount(PAddr addr, u32 size, int delta); - + VideoCore::RasterizerAccelerated& rasterizer; TextureRuntime runtime; SurfaceCache surface_cache; PageMap cached_pages; diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 873e4273e..a17024a50 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -29,7 +29,7 @@ using DiskResourceLoadCallback = std::function