summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2025-05-05 20:20:40 -0400
committerGitHub <noreply@github.com>2025-05-05 20:20:40 -0400
commitc9bdda63dc624995406c37f4e29e3b8c4696e6d0 (patch)
tree869fa7654987318708e5c36d21e073d84d976ee0 /Source
parent210b5cbf66a8c1aa28cf95aff8985ea54138ef8b (diff)
parent6f25e20c6a0c5b4027fffe2bea0116728018e7df (diff)
Merge pull request #13342 from Tilka/fifo_reset
VideoCommon: reset some CP registers during PI_FIFO_RESET
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/HW/MMIO.cpp2
-rw-r--r--Source/Core/Core/HW/ProcessorInterface.cpp7
-rw-r--r--Source/Core/Core/State.cpp2
-rw-r--r--Source/Core/VideoCommon/CommandProcessor.cpp28
-rw-r--r--Source/Core/VideoCommon/CommandProcessor.h7
5 files changed, 37 insertions, 9 deletions
diff --git a/Source/Core/Core/HW/MMIO.cpp b/Source/Core/Core/HW/MMIO.cpp
index fad1105532..af50aae0a0 100644
--- a/Source/Core/Core/HW/MMIO.cpp
+++ b/Source/Core/Core/HW/MMIO.cpp
@@ -175,7 +175,7 @@ ReadHandlingMethod<T>* InvalidRead()
return ComplexRead<T>([](Core::System&, u32 addr) {
ERROR_LOG_FMT(MEMMAP, "Trying to read {} bits from an invalid MMIO (addr={:08x})",
8 * sizeof(T), addr);
- return -1;
+ return 0;
});
}
template <typename T>
diff --git a/Source/Core/Core/HW/ProcessorInterface.cpp b/Source/Core/Core/HW/ProcessorInterface.cpp
index 72c8cb87b2..d805d2fa0e 100644
--- a/Source/Core/Core/HW/ProcessorInterface.cpp
+++ b/Source/Core/Core/HW/ProcessorInterface.cpp
@@ -20,6 +20,7 @@
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
#include "VideoCommon/AsyncRequests.h"
+#include "VideoCommon/CommandProcessor.h"
#include "VideoCommon/Fifo.h"
namespace ProcessorInterface
@@ -96,11 +97,11 @@ void ProcessorInterfaceManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
INFO_LOG_FMT(PROCESSORINTERFACE, "Wrote PI_FIFO_RESET: {:08x}", val);
if ((val & 1) != 0)
{
+ // TODO: Is this still necessary now that we reset the CP registers?
system.GetGPFifo().ResetGatherPipe();
- // Assume that all bytes that made it into the GPU fifo did in fact execute
- // before this MMIO write takes effect.
- system.GetFifo().SyncGPUForRegisterAccess();
+ // Reset some CP registers. This may trigger an ad-hoc GPU time slice.
+ system.GetCommandProcessor().ResetFifo();
// Call Fifo::ResetVideoBuffer() from the video thread. Since that function
// resets various pointers used by the video thread, we can't call it directly
diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
index 052a3ed1ff..556aff170a 100644
--- a/Source/Core/Core/State.cpp
+++ b/Source/Core/Core/State.cpp
@@ -95,7 +95,7 @@ static size_t s_state_writes_in_queue;
static std::condition_variable s_state_write_queue_is_empty;
// Don't forget to increase this after doing changes on the savestate system
-constexpr u32 STATE_VERSION = 173; // Last changed in PR 10084
+constexpr u32 STATE_VERSION = 174; // Last changed in PR 13342
// Increase this if the StateExtendedHeader definition changes
constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217
diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp
index 3a771e1f2a..8342bfb6fb 100644
--- a/Source/Core/VideoCommon/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/CommandProcessor.cpp
@@ -87,6 +87,8 @@ void CommandProcessorManager::DoState(PointerWrap& p)
p.Do(m_cp_status_reg);
p.Do(m_cp_ctrl_reg);
p.Do(m_cp_clear_reg);
+ p.Do(m_perf_select);
+ p.Do(m_unk_0a_reg);
m_fifo.DoState(p);
p.Do(m_interrupt_set);
@@ -200,13 +202,13 @@ void CommandProcessorManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
mmio->Register(base | CTRL_REGISTER, MMIO::DirectRead<u16>(&m_cp_ctrl_reg.Hex),
MMIO::ComplexWrite<u16>([](Core::System& system_, u32, u16 val) {
auto& cp = system_.GetCommandProcessor();
- UCPCtrlReg tmp(val);
+ UCPCtrlReg tmp(val & 0x3F);
cp.m_cp_ctrl_reg.Hex = tmp.Hex;
cp.SetCpControlRegister();
system_.GetFifo().RunGpu();
}));
- mmio->Register(base | CLEAR_REGISTER, MMIO::DirectRead<u16>(&m_cp_clear_reg.Hex),
+ mmio->Register(base | CLEAR_REGISTER, MMIO::Constant<u16>(0),
MMIO::ComplexWrite<u16>([](Core::System& system_, u32, u16 val) {
auto& cp = system_.GetCommandProcessor();
UCPClearReg tmp(val);
@@ -215,7 +217,14 @@ void CommandProcessorManager::RegisterMMIO(MMIO::Mapping* mmio, u32 base)
system_.GetFifo().RunGpu();
}));
- mmio->Register(base | PERF_SELECT, MMIO::InvalidRead<u16>(), MMIO::Nop<u16>());
+ // TODO: Figure out how this works. Written by GXSetGPMetric. Nicktoons MLB has DWARF v2 with enum
+ // names.
+ mmio->Register(base | PERF_SELECT, MMIO::DirectRead<u16>(&m_perf_select),
+ MMIO::DirectWrite<u16>(&m_perf_select, 0x0007));
+
+ // TODO: Figure out what this is.
+ mmio->Register(base | UNK_0A_REGISTER, MMIO::DirectRead<u16>(&m_unk_0a_reg),
+ MMIO::DirectWrite<u16>(&m_unk_0a_reg, 0x00FF));
// Some MMIOs have different handlers for single core vs. dual core mode.
const bool is_on_thread = IsOnThread(m_system);
@@ -565,6 +574,7 @@ void CommandProcessorManager::SetCpStatusRegister()
void CommandProcessorManager::SetCpControlRegister()
{
+ // Just before disabling reads, give the GPU a chance to catch up.
if (m_fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && !m_cp_ctrl_reg.GPReadEnable)
{
m_system.GetFifo().SyncGPUForRegisterAccess();
@@ -591,6 +601,18 @@ void CommandProcessorManager::SetCpClearRegister()
{
}
+void CommandProcessorManager::ResetFifo()
+{
+ // Link fifos, disable interrupts, disable reads.
+ m_cp_ctrl_reg.Hex = 0x0010;
+ SetCpControlRegister();
+ m_perf_select = 0;
+ m_unk_0a_reg = 0;
+ m_fifo.CPLoWatermark = 0;
+ m_fifo.CPHiWatermark = GetPhysicalAddressMask(m_system.IsWii()) & ~31u;
+ SetCpStatusRegister();
+}
+
void CommandProcessorManager::HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess)
{
// Datel software uses 0x01 during startup, and Mario Party 5's Wiggler capsule accidentally uses
diff --git a/Source/Core/VideoCommon/CommandProcessor.h b/Source/Core/VideoCommon/CommandProcessor.h
index fcd81a893e..e4bb4cd136 100644
--- a/Source/Core/VideoCommon/CommandProcessor.h
+++ b/Source/Core/VideoCommon/CommandProcessor.h
@@ -60,6 +60,7 @@ enum
CTRL_REGISTER = 0x02,
CLEAR_REGISTER = 0x04,
PERF_SELECT = 0x06,
+ UNK_0A_REGISTER = 0x0A,
FIFO_BASE_LO = 0x20,
FIFO_BASE_HI = 0x22,
FIFO_END_LO = 0x24,
@@ -142,7 +143,8 @@ union UCPClearReg
{
u16 ClearFifoOverflow : 1;
u16 ClearFifoUnderflow : 1;
- u16 ClearMetrices : 1;
+ // set by GXClearGPMetric
+ u16 ClearMetrics : 1;
u16 : 13;
};
u16 Hex;
@@ -178,6 +180,7 @@ public:
void SetCpClearRegister();
void SetCpControlRegister();
void SetCpStatusRegister();
+ void ResetFifo();
void HandleUnknownOpcode(u8 cmd_byte, const u8* buffer, bool preprocess);
@@ -194,6 +197,8 @@ private:
UCPStatusReg m_cp_status_reg;
UCPCtrlReg m_cp_ctrl_reg;
UCPClearReg m_cp_clear_reg;
+ u16 m_perf_select = 0;
+ u16 m_unk_0a_reg = 0;
u16 m_bbox_left = 0;
u16 m_bbox_top = 0;