Add ClearAll to rasterizer cache for fully wiping the cache on save/load

This commit is contained in:
James Rowe 2020-01-16 23:17:55 -07:00 committed by zhupengfei
parent 3e34ad6890
commit 55c75b5e3e
9 changed files with 57 additions and 4 deletions

View file

@ -437,7 +437,9 @@ void System::Reset() {
template <class Archive> template <class Archive>
void System::serialize(Archive& ar, const unsigned int file_version) { 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&* timing.get();
ar&* cpu_core.get(); ar&* cpu_core.get();
ar&* service_manager.get(); ar&* service_manager.get();

View file

@ -556,6 +556,16 @@ void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size) {
VideoCore::g_renderer->Rasterizer()->FlushAndInvalidateRegion(start, 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) { void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) {
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
// null here // null here

View file

@ -283,6 +283,12 @@ enum class FlushMode {
FlushAndInvalidate, 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 * Flushes and invalidates any externally cached rasterizer resources touching the given virtual
* address region. * address region.

View file

@ -55,6 +55,9 @@ public:
/// and invalidated /// and invalidated
virtual void FlushAndInvalidateRegion(PAddr addr, u32 size) = 0; 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 /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0
virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
return false; return false;

View file

@ -1367,6 +1367,10 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(PAddr addr, u32 size) {
res_cache.InvalidateRegion(addr, size, nullptr); res_cache.InvalidateRegion(addr, size, nullptr);
} }
void RasterizerOpenGL::ClearAll(bool flush) {
res_cache.ClearAll(flush);
}
bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
MICROPROFILE_SCOPE(OpenGL_Blits); MICROPROFILE_SCOPE(OpenGL_Blits);

View file

@ -53,6 +53,7 @@ public:
void FlushRegion(PAddr addr, u32 size) override; void FlushRegion(PAddr addr, u32 size) override;
void InvalidateRegion(PAddr addr, u32 size) override; void InvalidateRegion(PAddr addr, u32 size) override;
void FlushAndInvalidateRegion(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 AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override;
bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override; bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override; bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;

View file

@ -1276,9 +1276,7 @@ void main() {
} }
RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { RasterizerCacheOpenGL::~RasterizerCacheOpenGL() {
FlushAll(); ClearAll(false);
while (!surface_cache.empty())
UnregisterSurface(*surface_cache.begin()->second.begin());
} }
MICROPROFILE_DEFINE(OpenGL_BlitSurface, "OpenGL", "BlitSurface", MP_RGB(128, 192, 64)); 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) { void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, Surface flush_surface) {
if (size == 0) if (size == 0)
return; return;

View file

@ -482,6 +482,9 @@ public:
/// Flush all cached resources tracked by this cache manager /// Flush all cached resources tracked by this cache manager
void FlushAll(); void FlushAll();
/// Clear all cached resources tracked by this cache manager
void ClearAll(bool flush);
private: private:
void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface); void DuplicateSurface(const Surface& src_surface, const Surface& dest_surface);

View file

@ -22,6 +22,7 @@ class SWRasterizer : public RasterizerInterface {
void FlushRegion(PAddr addr, u32 size) override {} void FlushRegion(PAddr addr, u32 size) override {}
void InvalidateRegion(PAddr addr, u32 size) override {} void InvalidateRegion(PAddr addr, u32 size) override {}
void FlushAndInvalidateRegion(PAddr addr, u32 size) override {} void FlushAndInvalidateRegion(PAddr addr, u32 size) override {}
void ClearAll(bool flush) override {}
}; };
} // namespace VideoCore } // namespace VideoCore