video_core: Move UpdatePagesCachedCount to RasterizerAccelerated
This commit is contained in:
@@ -13,6 +13,8 @@ add_library(video_core STATIC
|
|||||||
precompiled_headers.h
|
precompiled_headers.h
|
||||||
primitive_assembly.cpp
|
primitive_assembly.cpp
|
||||||
primitive_assembly.h
|
primitive_assembly.h
|
||||||
|
rasterizer_accelerated.cpp
|
||||||
|
rasterizer_accelerated.h
|
||||||
rasterizer_interface.h
|
rasterizer_interface.h
|
||||||
regs.cpp
|
regs.cpp
|
||||||
regs.h
|
regs.h
|
||||||
|
74
src/video_core/rasterizer_accelerated.cpp
Normal file
74
src/video_core/rasterizer_accelerated.cpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
// Copyright 2022 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#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<u16>::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
|
19
src/video_core/rasterizer_accelerated.h
Normal file
19
src/video_core/rasterizer_accelerated.h
Normal file
@@ -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<u16, 0x30000> cached_pages;
|
||||||
|
};
|
||||||
|
} // namespace VideoCore
|
@@ -8,6 +8,7 @@
|
|||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "video_core/pica_state.h"
|
#include "video_core/pica_state.h"
|
||||||
|
#include "video_core/rasterizer_accelerated.h"
|
||||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||||
#include "video_core/renderer_opengl/gl_format_reinterpreter.h"
|
#include "video_core/renderer_opengl/gl_format_reinterpreter.h"
|
||||||
#include "video_core/renderer_opengl/texture_downloader_es.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;
|
return match_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterizerCacheOpenGL::RasterizerCacheOpenGL() {
|
RasterizerCacheOpenGL::RasterizerCacheOpenGL(VideoCore::RasterizerAccelerated& rasterizer)
|
||||||
|
: rasterizer(rasterizer) {
|
||||||
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
|
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
|
||||||
texture_filterer = std::make_unique<TextureFilterer>(
|
texture_filterer = std::make_unique<TextureFilterer>(
|
||||||
Settings::values.texture_filter_name.GetValue(), resolution_scale_factor);
|
Settings::values.texture_filter_name.GetValue(), resolution_scale_factor);
|
||||||
@@ -1055,7 +1057,7 @@ void RasterizerCacheOpenGL::RegisterSurface(const Surface& surface) {
|
|||||||
}
|
}
|
||||||
surface->registered = true;
|
surface->registered = true;
|
||||||
surface_cache.add({surface->GetInterval(), SurfaceSet{surface}});
|
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) {
|
void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) {
|
||||||
@@ -1065,42 +1067,8 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
surface->registered = false;
|
surface->registered = false;
|
||||||
UpdatePagesCachedCount(surface->addr, surface->size, -1);
|
rasterizer.UpdatePagesCachedCount(surface->addr, surface->size, -1);
|
||||||
surface_cache.subtract({surface->GetInterval(), SurfaceSet{surface}});
|
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
|
} // namespace OpenGL
|
||||||
|
@@ -9,6 +9,10 @@
|
|||||||
#include "video_core/rasterizer_cache/surface_params.h"
|
#include "video_core/rasterizer_cache/surface_params.h"
|
||||||
#include "video_core/texture/texture_decode.h"
|
#include "video_core/texture/texture_decode.h"
|
||||||
|
|
||||||
|
namespace VideoCore {
|
||||||
|
class RasterizerAccelerated;
|
||||||
|
}
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
enum class ScaleMatch {
|
enum class ScaleMatch {
|
||||||
@@ -23,7 +27,7 @@ class FormatReinterpreterOpenGL;
|
|||||||
|
|
||||||
class RasterizerCacheOpenGL : NonCopyable {
|
class RasterizerCacheOpenGL : NonCopyable {
|
||||||
public:
|
public:
|
||||||
RasterizerCacheOpenGL();
|
RasterizerCacheOpenGL(VideoCore::RasterizerAccelerated& rasterizer);
|
||||||
~RasterizerCacheOpenGL();
|
~RasterizerCacheOpenGL();
|
||||||
|
|
||||||
/// Blit one surface's texture to another
|
/// Blit one surface's texture to another
|
||||||
@@ -105,9 +109,7 @@ private:
|
|||||||
/// Remove surface from the cache
|
/// Remove surface from the cache
|
||||||
void UnregisterSurface(const Surface& surface);
|
void UnregisterSurface(const Surface& surface);
|
||||||
|
|
||||||
/// Increase/decrease the number of surface in pages touching the specified region
|
VideoCore::RasterizerAccelerated& rasterizer;
|
||||||
void UpdatePagesCachedCount(PAddr addr, u32 size, int delta);
|
|
||||||
|
|
||||||
TextureRuntime runtime;
|
TextureRuntime runtime;
|
||||||
SurfaceCache surface_cache;
|
SurfaceCache surface_cache;
|
||||||
PageMap cached_pages;
|
PageMap cached_pages;
|
||||||
|
@@ -29,7 +29,7 @@ using DiskResourceLoadCallback = std::function<void(LoadCallbackStage, std::size
|
|||||||
|
|
||||||
class RasterizerInterface {
|
class RasterizerInterface {
|
||||||
public:
|
public:
|
||||||
virtual ~RasterizerInterface() {}
|
virtual ~RasterizerInterface() = default;
|
||||||
|
|
||||||
/// Queues the primitive formed by the given vertices for rendering
|
/// Queues the primitive formed by the given vertices for rendering
|
||||||
virtual void AddTriangle(const Pica::Shader::OutputVertex& v0,
|
virtual void AddTriangle(const Pica::Shader::OutputVertex& v0,
|
||||||
@@ -85,9 +85,14 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Increase/decrease the number of surface in pages touching the specified region
|
||||||
|
virtual void UpdatePagesCachedCount(PAddr addr, u32 size, int delta) {}
|
||||||
|
|
||||||
|
/// Loads disk cached rasterizer data before rendering
|
||||||
virtual void LoadDiskResources(const std::atomic_bool& stop_loading,
|
virtual void LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||||
const DiskResourceLoadCallback& callback) {}
|
const DiskResourceLoadCallback& callback) {}
|
||||||
|
|
||||||
|
/// Synchronizes the graphics API state with the PICA state
|
||||||
virtual void SyncEntireState() {}
|
virtual void SyncEntireState() {}
|
||||||
};
|
};
|
||||||
} // namespace VideoCore
|
} // namespace VideoCore
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
#include "video_core/pica_types.h"
|
#include "video_core/pica_types.h"
|
||||||
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
#include "video_core/rasterizer_cache/rasterizer_cache.h"
|
||||||
#include "video_core/rasterizer_interface.h"
|
#include "video_core/rasterizer_accelerated.h"
|
||||||
#include "video_core/regs_lighting.h"
|
#include "video_core/regs_lighting.h"
|
||||||
#include "video_core/regs_texturing.h"
|
#include "video_core/regs_texturing.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||||
@@ -22,7 +22,7 @@ class EmuWindow;
|
|||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
class ShaderProgramManager;
|
class ShaderProgramManager;
|
||||||
|
|
||||||
class RasterizerOpenGL : public VideoCore::RasterizerInterface {
|
class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
|
||||||
public:
|
public:
|
||||||
explicit RasterizerOpenGL(Frontend::EmuWindow& emu_window);
|
explicit RasterizerOpenGL(Frontend::EmuWindow& emu_window);
|
||||||
~RasterizerOpenGL() override;
|
~RasterizerOpenGL() override;
|
||||||
|
Reference in New Issue
Block a user