GPU: Invalidate destination address of kepler_memory writes.

master
bunnei 2018-10-17 20:44:07 +07:00
parent 6b333d862b
commit a5d853a9f8
3 changed files with 17 additions and 3 deletions

@ -5,10 +5,14 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/memory.h" #include "core/memory.h"
#include "video_core/engines/kepler_memory.h" #include "video_core/engines/kepler_memory.h"
#include "video_core/rasterizer_interface.h"
namespace Tegra::Engines { 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; KeplerMemory::~KeplerMemory() = default;
void KeplerMemory::WriteReg(u32 method, u32 value) { void KeplerMemory::WriteReg(u32 method, u32 value) {
@ -37,6 +41,11 @@ void KeplerMemory::ProcessData(u32 data) {
VAddr dest_address = VAddr dest_address =
*memory_manager.GpuToCpuAddress(address + state.write_offset * sizeof(u32)); *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); Memory::Write32(dest_address, data);
state.write_offset++; state.write_offset++;

@ -11,6 +11,10 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "video_core/memory_manager.h" #include "video_core/memory_manager.h"
namespace VideoCore {
class RasterizerInterface;
}
namespace Tegra::Engines { namespace Tegra::Engines {
#define KEPLERMEMORY_REG_INDEX(field_name) \ #define KEPLERMEMORY_REG_INDEX(field_name) \
@ -18,7 +22,7 @@ namespace Tegra::Engines {
class KeplerMemory final { class KeplerMemory final {
public: public:
KeplerMemory(MemoryManager& memory_manager); KeplerMemory(VideoCore::RasterizerInterface& rasterizer, MemoryManager& memory_manager);
~KeplerMemory(); ~KeplerMemory();
/// Write the value to the register identified by method. /// Write the value to the register identified by method.
@ -72,6 +76,7 @@ public:
private: private:
MemoryManager& memory_manager; MemoryManager& memory_manager;
VideoCore::RasterizerInterface& rasterizer;
void ProcessData(u32 data); void ProcessData(u32 data);
}; };

@ -28,7 +28,7 @@ GPU::GPU(VideoCore::RasterizerInterface& rasterizer) {
fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager); fermi_2d = std::make_unique<Engines::Fermi2D>(rasterizer, *memory_manager);
maxwell_compute = std::make_unique<Engines::MaxwellCompute>(); maxwell_compute = std::make_unique<Engines::MaxwellCompute>();
maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager); maxwell_dma = std::make_unique<Engines::MaxwellDMA>(*memory_manager);
kepler_memory = std::make_unique<Engines::KeplerMemory>(*memory_manager); kepler_memory = std::make_unique<Engines::KeplerMemory>(rasterizer, *memory_manager);
} }
GPU::~GPU() = default; GPU::~GPU() = default;