summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2021-04-17 15:54:50 +1000
committerStenzek <stenzek@gmail.com>2021-04-18 03:24:01 +1000
commite3ac5dca3218e62636659624b65a9ff599fee150 (patch)
tree9e51bbba699f26e4d3ef189a3c23a3b3a2e7ba3c /Source/Core/VideoCommon
parent53222560650e4a99eceafcd537d4e04d1c50b3a6 (diff)
Fifo: Run/sync with the GPU on command processor register access
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/CommandProcessor.cpp52
-rw-r--r--Source/Core/VideoCommon/Fifo.cpp10
-rw-r--r--Source/Core/VideoCommon/Fifo.h4
3 files changed, 46 insertions, 20 deletions
diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp
index 4694860787..0ad2bf2cea 100644
--- a/Source/Core/VideoCommon/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/CommandProcessor.cpp
@@ -234,6 +234,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
}
mmio->Register(base | STATUS_REGISTER, MMIO::ComplexRead<u16>([](u32) {
+ Fifo::SyncGPUForRegisterAccess();
SetCpStatusRegister();
return m_CPStatusReg.Hex;
}),
@@ -271,18 +272,21 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance),
WMASK_LO_ALIGN_32BIT));
mmio->Register(base | FIFO_RW_DISTANCE_HI,
- IsOnThread() ?
- MMIO::ComplexRead<u16>([](u32) {
- if (fifo.CPWritePointer >= fifo.SafeCPReadPointer)
- return ReadHigh(fifo.CPWritePointer - fifo.SafeCPReadPointer);
- else
- return ReadHigh(fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer -
- fifo.CPBase + 32);
- }) :
- MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPReadWriteDistance)),
+ IsOnThread() ? MMIO::ComplexRead<u16>([](u32) {
+ Fifo::SyncGPUForRegisterAccess();
+ if (fifo.CPWritePointer >= fifo.SafeCPReadPointer)
+ return ReadHigh(fifo.CPWritePointer - fifo.SafeCPReadPointer);
+ else
+ return ReadHigh(fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer -
+ fifo.CPBase + 32);
+ }) :
+ MMIO::ComplexRead<u16>([](u32) {
+ Fifo::SyncGPUForRegisterAccess();
+ return ReadHigh(fifo.CPReadWriteDistance);
+ }),
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
+ Fifo::SyncGPUForRegisterAccess();
WriteHigh(fifo.CPReadWriteDistance, val & WMASK_HI_RESTRICT);
- Fifo::SyncGPU(Fifo::SyncGPUReason::Other);
Fifo::RunGpu();
}));
mmio->Register(
@@ -290,16 +294,24 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
IsOnThread() ? MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.SafeCPReadPointer)) :
MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadPointer)),
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadPointer), WMASK_LO_ALIGN_32BIT));
- mmio->Register(
- base | FIFO_READ_POINTER_HI,
- IsOnThread() ? MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.SafeCPReadPointer)) :
- MMIO::DirectRead<u16>(MMIO::Utils::HighPart(&fifo.CPReadPointer)),
- IsOnThread() ?
- MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
- WriteHigh(fifo.CPReadPointer, val & WMASK_HI_RESTRICT);
- fifo.SafeCPReadPointer = fifo.CPReadPointer;
- }) :
- MMIO::DirectWrite<u16>(MMIO::Utils::HighPart(&fifo.CPReadPointer), WMASK_HI_RESTRICT));
+ mmio->Register(base | FIFO_READ_POINTER_HI,
+ IsOnThread() ? MMIO::ComplexRead<u16>([](u32) {
+ Fifo::SyncGPUForRegisterAccess();
+ return ReadHigh(fifo.SafeCPReadPointer);
+ }) :
+ MMIO::ComplexRead<u16>([](u32) {
+ Fifo::SyncGPUForRegisterAccess();
+ return ReadHigh(fifo.CPReadPointer);
+ }),
+ IsOnThread() ? MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
+ Fifo::SyncGPUForRegisterAccess();
+ WriteHigh(fifo.CPReadPointer, val & WMASK_HI_RESTRICT);
+ fifo.SafeCPReadPointer = fifo.CPReadPointer;
+ }) :
+ MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
+ Fifo::SyncGPUForRegisterAccess();
+ WriteHigh(fifo.CPReadPointer, val & WMASK_HI_RESTRICT);
+ }));
}
void GatherPipeBursted()
diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp
index 57dcb07c85..5aede12b96 100644
--- a/Source/Core/VideoCommon/Fifo.cpp
+++ b/Source/Core/VideoCommon/Fifo.cpp
@@ -580,6 +580,16 @@ static void SyncGPUCallback(u64 ticks, s64 cyclesLate)
CoreTiming::ScheduleEvent(next, s_event_sync_gpu, next);
}
+void SyncGPUForRegisterAccess()
+{
+ SyncGPU(SyncGPUReason::Other);
+
+ if (!SConfig::GetInstance().bCPUThread || s_use_deterministic_gpu_thread)
+ RunGpuOnCpu(GPU_TIME_SLOT_SIZE);
+ else if (SConfig::GetInstance().bSyncGPU)
+ WaitForGpuThread(GPU_TIME_SLOT_SIZE);
+}
+
// Initialize GPU - CPU thread syncing, this gives us a deterministic way to start the GPU thread.
void Prepare()
{
diff --git a/Source/Core/VideoCommon/Fifo.h b/Source/Core/VideoCommon/Fifo.h
index dfdf43a157..9b454a6849 100644
--- a/Source/Core/VideoCommon/Fifo.h
+++ b/Source/Core/VideoCommon/Fifo.h
@@ -33,6 +33,10 @@ enum class SyncGPUReason
// In deterministic GPU thread mode this waits for the GPU to be done with pending work.
void SyncGPU(SyncGPUReason reason, bool may_move_read_ptr = true);
+// In single core mode, this runs the GPU for a single slice.
+// In dual core mode, this synchronizes with the GPU thread.
+void SyncGPUForRegisterAccess();
+
void PushFifoAuxBuffer(const void* ptr, size_t size);
void* PopFifoAuxBuffer(size_t size);