mirror of
https://github.com/citra-emu/citra-canary.git
synced 2024-12-23 17:35:30 +00:00
Add ClearAll to rasterizer cache for fully wiping the cache on save/load
This commit is contained in:
parent
3e34ad6890
commit
55c75b5e3e
|
@ -437,7 +437,9 @@ void System::Reset() {
|
|||
|
||||
template <class Archive>
|
||||
void System::serialize(Archive& ar, const unsigned int file_version) {
|
||||
Memory::RasterizerFlushAndInvalidateRegion(0, 0xFFFFFFFF);
|
||||
// flush on save, don't flush on load
|
||||
bool should_flush = !Archive::is_loading::value;
|
||||
Memory::RasterizerClearAll(should_flush);
|
||||
ar&* timing.get();
|
||||
ar&* cpu_core.get();
|
||||
ar&* service_manager.get();
|
||||
|
|
|
@ -556,6 +556,16 @@ void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) {
|
|||
VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, size);
|
||||
}
|
||||
|
||||
void RasterizerClearAll(bool flush) {
|
||||
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
|
||||
// null here
|
||||
if (VideoCore::g_renderer == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
VideoCore::g_renderer->Rasterizer()->ClearAll(flush);
|
||||
}
|
||||
|
||||
void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) {
|
||||
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
|
||||
// null here
|
||||
|
|
|
@ -283,6 +283,12 @@ enum class FlushMode {
|
|||
FlushAndInvalidate,
|
||||
};
|
||||
|
||||
/**
|
||||
* Flushes and invalidates all memory in the rasterizer cache and removes any leftover state
|
||||
* If flush is true, the rasterizer should flush any cached resources to RAM before clearing
|
||||
*/
|
||||
void RasterizerClearAll(bool flush);
|
||||
|
||||
/**
|
||||
* Flushes and invalidates any externally cached rasterizer resources touching the given virtual
|
||||
* address region.
|
||||
|
|
|
@ -55,6 +55,9 @@ public:
|
|||
/// and invalidated
|
||||
virtual void FlushAndInvalidateRegion(PAddr addr, u32 size) = 0;
|
||||
|
||||
/// Removes as much state as possible from the rasterizer in preparation for a save/load state
|
||||
virtual void ClearAll(bool flush) = 0;
|
||||
|
||||
/// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0
|
||||
virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
|
||||
return false;
|
||||
|
|
|
@ -1367,6 +1367,10 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(PAddr addr, u32 size) {
|
|||
res_cache.InvalidateRegion(addr, size, nullptr);
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::ClearAll(bool flush) {
|
||||
res_cache.ClearAll(flush);
|
||||
}
|
||||
|
||||
bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
|
||||
MICROPROFILE_SCOPE(OpenGL_Blits);
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
void FlushRegion(PAddr addr, u32 size) override;
|
||||
void InvalidateRegion(PAddr addr, u32 size) override;
|
||||
void FlushAndInvalidateRegion(PAddr addr, u32 size) override;
|
||||
void ClearAll(bool flush) override;
|
||||
bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override;
|
||||
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
|
||||
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;
|
||||
|
|
|
@ -1276,9 +1276,7 @@ void main() {
|
|||
}
|
||||
|
||||
RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
|
||||
FlushAll();
|
||||
while (!surface_cache.empty())
|
||||
UnregisterSurface(*surface_cache.begin()->second.begin());
|
||||
ClearAll(false);
|
||||
}
|
||||
|
||||
MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64));
|
||||
|
@ -1927,6 +1925,31 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, PAddr addr,
|
|||
}
|
||||
}
|
||||
|
||||
void RasterizerCacheOpenGL::ClearAll(bool flush) {
|
||||
const SurfaceInterval flush_interval(0x0, 0xFFFFFFFF);
|
||||
// Force flush all surfaces from the cache
|
||||
if (flush) {
|
||||
FlushRegion(0x0, 0xFFFFFFFF);
|
||||
}
|
||||
// Unmark all of the marked pages
|
||||
for (auto& pair : RangeFromInterval(cached_pages, flush_interval)) {
|
||||
const auto interval = pair.first & flush_interval;
|
||||
const int count = pair.second;
|
||||
|
||||
const PAddr interval_start_addr = boost::icl::first(interval) << Memory::PAGE_BITS;
|
||||
const PAddr interval_end_addr = boost::icl::last_next(interval) << Memory::PAGE_BITS;
|
||||
const u32 interval_size = interval_end_addr - interval_start_addr;
|
||||
|
||||
VideoCore::g_memory->RasterizerMarkRegionCached(interval_start_addr, interval_size, false);
|
||||
}
|
||||
|
||||
// Remove the whole cache without really looking at it.
|
||||
cached_pages -= flush_interval;
|
||||
dirty_regions -= flush_interval;
|
||||
surface_cache -= flush_interval;
|
||||
remove_surfaces.clear();
|
||||
}
|
||||
|
||||
void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, Surface flush_surface) {
|
||||
if (size == 0)
|
||||
return;
|
||||
|
|
|
@ -482,6 +482,9 @@ public:
|
|||
/// Flush all cached resources tracked by this cache manager
|
||||
void FlushAll();
|
||||
|
||||
/// Clear all cached resources tracked by this cache manager
|
||||
void ClearAll(bool flush);
|
||||
|
||||
private:
|
||||
void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ class SWRasterizer : public RasterizerInterface {
|
|||
void FlushRegion(PAddr addr, u32 size) override {}
|
||||
void InvalidateRegion(PAddr addr, u32 size) override {}
|
||||
void FlushAndInvalidateRegion(PAddr addr, u32 size) override {}
|
||||
void ClearAll(bool flush) override {}
|
||||
};
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
Loading…
Reference in a new issue