From a5d853a9f8a19dedbc6cb77e8ca714f65819ad1d Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 17 Oct 2018 20:44:07 -0400 Subject: GPU: Invalidate destination address of kepler_memory writes. --- src/video_core/engines/kepler_memory.cpp | 11 ++++++++++- src/video_core/engines/kepler_memory.h | 7 ++++++- src/video_core/gpu.cpp | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp index 66ae6332d..585290d9f 100644 --- a/src/video_core/engines/kepler_memory.cpp +++ b/src/video_core/engines/kepler_memory.cpp @@ -5,10 +5,14 @@ #include "common/logging/log.h" #include "core/memory.h" #include "video_core/engines/kepler_memory.h" +#include "video_core/rasterizer_interface.h" namespace Tegra::Engines { -KeplerMemory::KeplerMemory(MemoryManager& memory_manager) : memory_manager(memory_manager) {} +KeplerMemory::KeplerMemory(VideoCore::RasterizerInterface& rasterizer, + MemoryManager& memory_manager) + : memory_manager(memory_manager), rasterizer{rasterizer} {} + KeplerMemory::~KeplerMemory() = default; void KeplerMemory::WriteReg(u32 method, u32 value) { @@ -37,6 +41,11 @@ void KeplerMemory::ProcessData(u32 data) { VAddr dest_address = *memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32)); + // We have to invalidate the destination region to evict any outdated surfaces from the cache. + // We do this before actually writing the new data because the destination address might contain + // a dirty surface that will have to be written back to memory. + rasterizer.InvalidateRegion(dest_address, sizeof(u32)); + Memory::Write32(dest_address, data); state.write_offset++; diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h index b0d0078cf..bf4a13cff 100644 --- a/src/video_core/engines/kepler_memory.h +++ b/src/video_core/engines/kepler_memory.h @@ -11,6 +11,10 @@ #include "common/common_types.h" #include "video_core/memory_manager.h" +namespace VideoCore { +class RasterizerInterface; +} + namespace Tegra::Engines { #define KEPLERMEMORY_REG_INDEX(field_name) \ @@ -18,7 +22,7 @@ namespace Tegra::Engines { class KeplerMemory final { public: - KeplerMemory(MemoryManager& memory_manager); + KeplerMemory(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager); ~KeplerMemory(); /// Write the value to the register identified by method. @@ -72,6 +76,7 @@ public: private: MemoryManager& memory_manager; + VideoCore::RasterizerInterface& rasterizer; void ProcessData(u32 data); }; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 9ba7e3533..2d70a833b 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -28,7 +28,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) { fermi_2d = std::make_unique(rasterizer, *memory_manager); maxwell_compute = std::make_unique(); maxwell_dma = std::make_unique(*memory_manager); - kepler_memory = std::make_unique(*memory_manager); + kepler_memory = std::make_unique(rasterizer, *memory_manager); } GPU::~GPU() = default; -- cgit v1.2.3