video_core: Reintroduce dirty flags infrastructure

This commit is contained in:
ReinUsesLisp 2019-12-26 22:14:10 -03:00
parent b92dfcd7f2
commit eed789d0d1
10 changed files with 72 additions and 1 deletions

View file

@ -174,6 +174,7 @@ struct System::Impl {
} }
interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system); interrupt_manager = std::make_unique<Core::Hardware::InterruptManager>(system);
gpu_core = VideoCore::CreateGPU(system); gpu_core = VideoCore::CreateGPU(system);
renderer->Rasterizer().SetupDirtyFlags();
is_powered_on = true; is_powered_on = true;
exit_lock = false; exit_lock = false;

View file

@ -2,6 +2,7 @@ add_library(video_core STATIC
buffer_cache/buffer_block.h buffer_cache/buffer_block.h
buffer_cache/buffer_cache.h buffer_cache/buffer_cache.h
buffer_cache/map_interval.h buffer_cache/map_interval.h
dirty_flags.h
dma_pusher.cpp dma_pusher.cpp
dma_pusher.h dma_pusher.h
engines/const_buffer_engine_interface.h engines/const_buffer_engine_interface.h

View file

@ -0,0 +1,28 @@
// Copyright 2019 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "common/common_types.h"
namespace VideoCommon::Dirty {
enum : u8 {
NullEntry = 0,
RenderTargets,
ColorBuffer0,
ColorBuffer1,
ColorBuffer2,
ColorBuffer3,
ColorBuffer4,
ColorBuffer5,
ColorBuffer6,
ColorBuffer7,
ZetaBuffer,
LastCommonEntry,
};
} // namespace VideoCommon::Dirty

View file

@ -21,6 +21,9 @@ MICROPROFILE_DEFINE(DispatchCalls, "GPU", "Execute command buffer", MP_RGB(128,
void DmaPusher::DispatchCalls() { void DmaPusher::DispatchCalls() {
MICROPROFILE_SCOPE(DispatchCalls); MICROPROFILE_SCOPE(DispatchCalls);
// On entering GPU code, assume all memory may be touched by the ARM core.
gpu.Maxwell3D().OnMemoryWrite();
dma_pushbuffer_subindex = 0; dma_pushbuffer_subindex = 0;
while (Core::System::GetInstance().IsPoweredOn()) { while (Core::System::GetInstance().IsPoweredOn()) {

View file

@ -38,6 +38,9 @@ void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) {
case KEPLER_COMPUTE_REG_INDEX(data_upload): { case KEPLER_COMPUTE_REG_INDEX(data_upload): {
const bool is_last_call = method_call.IsLastCall(); const bool is_last_call = method_call.IsLastCall();
upload_state.ProcessData(method_call.argument, is_last_call); upload_state.ProcessData(method_call.argument, is_last_call);
if (is_last_call) {
system.GPU().Maxwell3D().OnMemoryWrite();
}
break; break;
} }
case KEPLER_COMPUTE_REG_INDEX(launch): case KEPLER_COMPUTE_REG_INDEX(launch):

View file

@ -33,6 +33,9 @@ void KeplerMemory::CallMethod(const GPU::MethodCall& method_call) {
case KEPLERMEMORY_REG_INDEX(data): { case KEPLERMEMORY_REG_INDEX(data): {
const bool is_last_call = method_call.IsLastCall(); const bool is_last_call = method_call.IsLastCall();
upload_state.ProcessData(method_call.argument, is_last_call); upload_state.ProcessData(method_call.argument, is_last_call);
if (is_last_call) {
system.GPU().Maxwell3D().OnMemoryWrite();
}
break; break;
} }
} }

View file

@ -26,6 +26,8 @@ Maxwell3D::Maxwell3D(Core::System& system, VideoCore::RasterizerInterface& raste
MemoryManager& memory_manager) MemoryManager& memory_manager)
: system{system}, rasterizer{rasterizer}, memory_manager{memory_manager}, : system{system}, rasterizer{rasterizer}, memory_manager{memory_manager},
macro_interpreter{*this}, upload_state{memory_manager, regs.upload} { macro_interpreter{*this}, upload_state{memory_manager, regs.upload} {
dirty.flags.flip();
InitializeRegisterDefaults(); InitializeRegisterDefaults();
} }
@ -158,7 +160,13 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
ASSERT_MSG(method < Regs::NUM_REGS, ASSERT_MSG(method < Regs::NUM_REGS,
"Invalid Maxwell3D register, increase the size of the Regs structure"); "Invalid Maxwell3D register, increase the size of the Regs structure");
regs.reg_array[method] = method_call.argument; if (regs.reg_array[method] != method_call.argument) {
regs.reg_array[method] = method_call.argument;
for (const auto& table : dirty.tables) {
dirty.flags[table[method]] = true;
}
}
switch (method) { switch (method) {
case MAXWELL3D_REG_INDEX(macros.data): { case MAXWELL3D_REG_INDEX(macros.data): {
@ -243,6 +251,9 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
case MAXWELL3D_REG_INDEX(data_upload): { case MAXWELL3D_REG_INDEX(data_upload): {
const bool is_last_call = method_call.IsLastCall(); const bool is_last_call = method_call.IsLastCall();
upload_state.ProcessData(method_call.argument, is_last_call); upload_state.ProcessData(method_call.argument, is_last_call);
if (is_last_call) {
OnMemoryWrite();
}
break; break;
} }
default: default:
@ -549,6 +560,7 @@ void Maxwell3D::FinishCBData() {
const u32 id = cb_data_state.id; const u32 id = cb_data_state.id;
memory_manager.WriteBlock(address, cb_data_state.buffer[id].data(), size); memory_manager.WriteBlock(address, cb_data_state.buffer[id].data(), size);
OnMemoryWrite();
cb_data_state.id = null_cb_data; cb_data_state.id = null_cb_data;
cb_data_state.current = null_cb_data; cb_data_state.current = null_cb_data;

View file

@ -6,6 +6,7 @@
#include <array> #include <array>
#include <bitset> #include <bitset>
#include <limits>
#include <optional> #include <optional>
#include <type_traits> #include <type_traits>
#include <unordered_map> #include <unordered_map>
@ -1274,6 +1275,13 @@ public:
return execute_on; return execute_on;
} }
/// Notify a memory write has happened.
void OnMemoryWrite() {
for (const u8 store : dirty.on_write_stores) {
dirty.flags[store] = true;
}
}
enum class MMEDrawMode : u32 { enum class MMEDrawMode : u32 {
Undefined, Undefined,
Array, Array,
@ -1289,6 +1297,12 @@ public:
u32 gl_end_count{}; u32 gl_end_count{};
} mme_draw; } mme_draw;
struct {
std::bitset<std::numeric_limits<u8>::max()> flags;
std::array<std::array<u8, Regs::NUM_REGS>, 3> tables{};
std::array<u8, 32> on_write_stores{};
} dirty;
private: private:
void InitializeRegisterDefaults(); void InitializeRegisterDefaults();

View file

@ -56,6 +56,9 @@ void MaxwellDMA::HandleCopy() {
return; return;
} }
// All copies here update the main memory, so mark all rasterizer states as invalid.
system.GPU().Maxwell3D().OnMemoryWrite();
if (regs.exec.is_dst_linear && regs.exec.is_src_linear) { if (regs.exec.is_dst_linear && regs.exec.is_src_linear) {
// When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D // When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D
// buffer of length `x_count`, otherwise we copy a 2D image of dimensions (x_count, // buffer of length `x_count`, otherwise we copy a 2D image of dimensions (x_count,

View file

@ -89,6 +89,9 @@ public:
virtual void LoadDiskResources(const std::atomic_bool& stop_loading = false, virtual void LoadDiskResources(const std::atomic_bool& stop_loading = false,
const DiskResourceLoadCallback& callback = {}) {} const DiskResourceLoadCallback& callback = {}) {}
/// Initializes renderer dirty flags
virtual void SetupDirtyFlags() {}
/// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver. /// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver.
GuestDriverProfile& AccessGuestDriverProfile() { GuestDriverProfile& AccessGuestDriverProfile() {
return guest_driver_profile; return guest_driver_profile;