yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

Merge pull request #3542 from namkazt/patch-10

Implement MME shadow RAM
This commit is contained in:
Fernando Sahmkow 2020-03-23 12:00:01 -04:00 committed by GitHub
commit 7981910746
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 7 deletions

View File

@ -98,6 +98,8 @@ void Maxwell3D::InitializeRegisterDefaults() {
regs.framebuffer_srgb = 1; regs.framebuffer_srgb = 1;
regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise; regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise;
shadow_state = regs;
mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true; mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true;
mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true; mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true;
mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true; mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true;
@ -160,8 +162,17 @@ 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");
if (regs.reg_array[method] != method_call.argument) { u32 arg = method_call.argument;
regs.reg_array[method] = method_call.argument; // Keep track of the register value in shadow_state when requested.
if (shadow_state.shadow_ram_control == Regs::ShadowRamControl::Track ||
shadow_state.shadow_ram_control == Regs::ShadowRamControl::TrackWithFilter) {
shadow_state.reg_array[method] = arg;
} else if (shadow_state.shadow_ram_control == Regs::ShadowRamControl::Replay) {
arg = shadow_state.reg_array[method];
}
if (regs.reg_array[method] != arg) {
regs.reg_array[method] = arg;
for (const auto& table : dirty.tables) { for (const auto& table : dirty.tables) {
dirty.flags[table[method]] = true; dirty.flags[table[method]] = true;
@ -169,12 +180,16 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
} }
switch (method) { switch (method) {
case MAXWELL3D_REG_INDEX(shadow_ram_control): {
shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(method_call.argument);
break;
}
case MAXWELL3D_REG_INDEX(macros.data): { case MAXWELL3D_REG_INDEX(macros.data): {
ProcessMacroUpload(method_call.argument); ProcessMacroUpload(arg);
break; break;
} }
case MAXWELL3D_REG_INDEX(macros.bind): { case MAXWELL3D_REG_INDEX(macros.bind): {
ProcessMacroBind(method_call.argument); ProcessMacroBind(arg);
break; break;
} }
case MAXWELL3D_REG_INDEX(firmware[4]): { case MAXWELL3D_REG_INDEX(firmware[4]): {
@ -250,7 +265,7 @@ 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(arg, is_last_call);
if (is_last_call) { if (is_last_call) {
OnMemoryWrite(); OnMemoryWrite();
} }

View File

@ -531,6 +531,17 @@ public:
Fill = 0x1b02, Fill = 0x1b02,
}; };
enum class ShadowRamControl : u32 {
// write value to shadow ram
Track = 0,
// write value to shadow ram ( with validation ??? )
TrackWithFilter = 1,
// only write to real hw register
Passthrough = 2,
// write value from shadow ram to real hw register
Replay = 3,
};
struct RenderTargetConfig { struct RenderTargetConfig {
u32 address_high; u32 address_high;
u32 address_low; u32 address_low;
@ -674,7 +685,9 @@ public:
u32 bind; u32 bind;
} macros; } macros;
INSERT_UNION_PADDING_WORDS(0x17); ShadowRamControl shadow_ram_control;
INSERT_UNION_PADDING_WORDS(0x16);
Upload::Registers upload; Upload::Registers upload;
struct { struct {
@ -1263,7 +1276,12 @@ public:
}; };
std::array<u32, NUM_REGS> reg_array; std::array<u32, NUM_REGS> reg_array;
}; };
} regs{}; };
Regs regs{};
/// Store temporary hw register values, used by some calls to restore state after a operation
Regs shadow_state;
static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size"); static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size");
static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable"); static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable");
@ -1458,6 +1476,7 @@ private:
"Field " #field_name " has invalid position") "Field " #field_name " has invalid position")
ASSERT_REG_POSITION(macros, 0x45); ASSERT_REG_POSITION(macros, 0x45);
ASSERT_REG_POSITION(shadow_ram_control, 0x49);
ASSERT_REG_POSITION(upload, 0x60); ASSERT_REG_POSITION(upload, 0x60);
ASSERT_REG_POSITION(exec_upload, 0x6C); ASSERT_REG_POSITION(exec_upload, 0x6C);
ASSERT_REG_POSITION(data_upload, 0x6D); ASSERT_REG_POSITION(data_upload, 0x6D);