mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Merge pull request #9707 from JosJuice/remove-atomic-header
Remove Atomic.h
This commit is contained in:
@ -6,7 +6,6 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/Atomic.h"
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Flag.h"
|
||||
@ -91,21 +90,15 @@ void DoState(PointerWrap& p)
|
||||
p.Do(s_interrupt_waiting);
|
||||
}
|
||||
|
||||
static inline void WriteLow(volatile u32& _reg, u16 lowbits)
|
||||
static inline void WriteLow(std::atomic<u32>& reg, u16 lowbits)
|
||||
{
|
||||
Common::AtomicStore(_reg, (_reg & 0xFFFF0000) | lowbits);
|
||||
reg.store((reg.load(std::memory_order_relaxed) & 0xFFFF0000) | lowbits,
|
||||
std::memory_order_relaxed);
|
||||
}
|
||||
static inline void WriteHigh(volatile u32& _reg, u16 highbits)
|
||||
static inline void WriteHigh(std::atomic<u32>& reg, u16 highbits)
|
||||
{
|
||||
Common::AtomicStore(_reg, (_reg & 0x0000FFFF) | ((u32)highbits << 16));
|
||||
}
|
||||
static inline u16 ReadLow(u32 _reg)
|
||||
{
|
||||
return (u16)(_reg & 0xFFFF);
|
||||
}
|
||||
static inline u16 ReadHigh(u32 _reg)
|
||||
{
|
||||
return (u16)(_reg >> 16);
|
||||
reg.store((reg.load(std::memory_order_relaxed) & 0x0000FFFF) | (static_cast<u32>(highbits) << 16),
|
||||
std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void Init()
|
||||
@ -259,31 +252,50 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||
mmio->Register(base | PERF_SELECT, MMIO::InvalidRead<u16>(), MMIO::Nop<u16>());
|
||||
|
||||
// Some MMIOs have different handlers for single core vs. dual core mode.
|
||||
mmio->Register(base | FIFO_RW_DISTANCE_LO,
|
||||
mmio->Register(
|
||||
base | FIFO_RW_DISTANCE_LO,
|
||||
IsOnThread() ? MMIO::ComplexRead<u16>([](u32) {
|
||||
if (fifo.CPWritePointer.load(std::memory_order_relaxed) >=
|
||||
fifo.SafeCPReadPointer.load(std::memory_order_relaxed))
|
||||
{
|
||||
return static_cast<u16>(fifo.CPWritePointer.load(std::memory_order_relaxed) -
|
||||
fifo.SafeCPReadPointer.load(std::memory_order_relaxed));
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<u16>(fifo.CPEnd.load(std::memory_order_relaxed) -
|
||||
fifo.SafeCPReadPointer.load(std::memory_order_relaxed) +
|
||||
fifo.CPWritePointer.load(std::memory_order_relaxed) -
|
||||
fifo.CPBase.load(std::memory_order_relaxed) + 32);
|
||||
}
|
||||
}) :
|
||||
MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance)),
|
||||
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 ReadLow(fifo.CPWritePointer - fifo.SafeCPReadPointer);
|
||||
Fifo::SyncGPUForRegisterAccess();
|
||||
if (fifo.CPWritePointer.load(std::memory_order_relaxed) >=
|
||||
fifo.SafeCPReadPointer.load(std::memory_order_relaxed))
|
||||
{
|
||||
return (fifo.CPWritePointer.load(std::memory_order_relaxed) -
|
||||
fifo.SafeCPReadPointer.load(std::memory_order_relaxed)) >>
|
||||
16;
|
||||
}
|
||||
else
|
||||
return ReadLow(fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer -
|
||||
fifo.CPBase + 32);
|
||||
{
|
||||
return (fifo.CPEnd.load(std::memory_order_relaxed) -
|
||||
fifo.SafeCPReadPointer.load(std::memory_order_relaxed) +
|
||||
fifo.CPWritePointer.load(std::memory_order_relaxed) -
|
||||
fifo.CPBase.load(std::memory_order_relaxed) + 32) >>
|
||||
16;
|
||||
}
|
||||
}) :
|
||||
MMIO::DirectRead<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance)),
|
||||
MMIO::DirectWrite<u16>(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance),
|
||||
WMASK_LO_ALIGN_32BIT));
|
||||
mmio->Register(base | FIFO_RW_DISTANCE_HI,
|
||||
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::ComplexRead<u16>([](u32) {
|
||||
Fifo::SyncGPUForRegisterAccess();
|
||||
return fifo.CPReadWriteDistance.load(std::memory_order_relaxed) >> 16;
|
||||
}),
|
||||
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
|
||||
Fifo::SyncGPUForRegisterAccess();
|
||||
WriteHigh(fifo.CPReadWriteDistance, val & WMASK_HI_RESTRICT);
|
||||
@ -297,16 +309,17 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||
mmio->Register(base | FIFO_READ_POINTER_HI,
|
||||
IsOnThread() ? MMIO::ComplexRead<u16>([](u32) {
|
||||
Fifo::SyncGPUForRegisterAccess();
|
||||
return ReadHigh(fifo.SafeCPReadPointer);
|
||||
return fifo.SafeCPReadPointer.load(std::memory_order_relaxed) >> 16;
|
||||
}) :
|
||||
MMIO::ComplexRead<u16>([](u32) {
|
||||
Fifo::SyncGPUForRegisterAccess();
|
||||
return ReadHigh(fifo.CPReadPointer);
|
||||
return fifo.CPReadPointer.load(std::memory_order_relaxed) >> 16;
|
||||
}),
|
||||
IsOnThread() ? MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
|
||||
Fifo::SyncGPUForRegisterAccess();
|
||||
WriteHigh(fifo.CPReadPointer, val & WMASK_HI_RESTRICT);
|
||||
fifo.SafeCPReadPointer = fifo.CPReadPointer;
|
||||
fifo.SafeCPReadPointer.store(fifo.CPReadPointer.load(std::memory_order_relaxed),
|
||||
std::memory_order_relaxed);
|
||||
}) :
|
||||
MMIO::ComplexWrite<u16>([WMASK_HI_RESTRICT](u32, u16 val) {
|
||||
Fifo::SyncGPUForRegisterAccess();
|
||||
@ -325,8 +338,9 @@ void GatherPipeBursted()
|
||||
{
|
||||
// In multibuffer mode is not allowed write in the same FIFO attached to the GPU.
|
||||
// Fix Pokemon XD in DC mode.
|
||||
if ((ProcessorInterface::Fifo_CPUEnd == fifo.CPEnd) &&
|
||||
(ProcessorInterface::Fifo_CPUBase == fifo.CPBase) && fifo.CPReadWriteDistance > 0)
|
||||
if ((ProcessorInterface::Fifo_CPUEnd == fifo.CPEnd.load(std::memory_order_relaxed)) &&
|
||||
(ProcessorInterface::Fifo_CPUBase == fifo.CPBase.load(std::memory_order_relaxed)) &&
|
||||
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) > 0)
|
||||
{
|
||||
Fifo::FlushGpu();
|
||||
}
|
||||
@ -336,35 +350,47 @@ void GatherPipeBursted()
|
||||
}
|
||||
|
||||
// update the fifo pointer
|
||||
if (fifo.CPWritePointer == fifo.CPEnd)
|
||||
fifo.CPWritePointer = fifo.CPBase;
|
||||
if (fifo.CPWritePointer.load(std::memory_order_relaxed) ==
|
||||
fifo.CPEnd.load(std::memory_order_relaxed))
|
||||
{
|
||||
fifo.CPWritePointer.store(fifo.CPBase, std::memory_order_relaxed);
|
||||
}
|
||||
else
|
||||
fifo.CPWritePointer += GATHER_PIPE_SIZE;
|
||||
{
|
||||
fifo.CPWritePointer.fetch_add(GATHER_PIPE_SIZE, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
if (m_CPCtrlReg.GPReadEnable && m_CPCtrlReg.GPLinkEnable)
|
||||
{
|
||||
ProcessorInterface::Fifo_CPUWritePointer = fifo.CPWritePointer;
|
||||
ProcessorInterface::Fifo_CPUBase = fifo.CPBase;
|
||||
ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd;
|
||||
ProcessorInterface::Fifo_CPUWritePointer = fifo.CPWritePointer.load(std::memory_order_relaxed);
|
||||
ProcessorInterface::Fifo_CPUBase = fifo.CPBase.load(std::memory_order_relaxed);
|
||||
ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
// If the game is running close to overflowing, make the exception checking more frequent.
|
||||
if (fifo.bFF_HiWatermark)
|
||||
CoreTiming::ForceExceptionCheck(0);
|
||||
|
||||
Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE);
|
||||
fifo.CPReadWriteDistance.fetch_add(GATHER_PIPE_SIZE, std::memory_order_seq_cst);
|
||||
|
||||
Fifo::RunGpu();
|
||||
|
||||
ASSERT_MSG(COMMANDPROCESSOR, fifo.CPReadWriteDistance <= fifo.CPEnd - fifo.CPBase,
|
||||
ASSERT_MSG(COMMANDPROCESSOR,
|
||||
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) <=
|
||||
fifo.CPEnd.load(std::memory_order_relaxed) -
|
||||
fifo.CPBase.load(std::memory_order_relaxed),
|
||||
"FIFO is overflowed by GatherPipe !\nCPU thread is too fast!");
|
||||
|
||||
// check if we are in sync
|
||||
ASSERT_MSG(COMMANDPROCESSOR, fifo.CPWritePointer == ProcessorInterface::Fifo_CPUWritePointer,
|
||||
ASSERT_MSG(COMMANDPROCESSOR,
|
||||
fifo.CPWritePointer.load(std::memory_order_relaxed) ==
|
||||
ProcessorInterface::Fifo_CPUWritePointer,
|
||||
"FIFOs linked but out of sync");
|
||||
ASSERT_MSG(COMMANDPROCESSOR, fifo.CPBase == ProcessorInterface::Fifo_CPUBase,
|
||||
ASSERT_MSG(COMMANDPROCESSOR,
|
||||
fifo.CPBase.load(std::memory_order_relaxed) == ProcessorInterface::Fifo_CPUBase,
|
||||
"FIFOs linked but out of sync");
|
||||
ASSERT_MSG(COMMANDPROCESSOR, fifo.CPEnd == ProcessorInterface::Fifo_CPUEnd,
|
||||
ASSERT_MSG(COMMANDPROCESSOR,
|
||||
fifo.CPEnd.load(std::memory_order_relaxed) == ProcessorInterface::Fifo_CPUEnd,
|
||||
"FIFOs linked but out of sync");
|
||||
}
|
||||
|
||||
@ -403,31 +429,41 @@ void SetCPStatusFromGPU()
|
||||
// breakpoint
|
||||
if (fifo.bFF_BPEnable)
|
||||
{
|
||||
if (fifo.CPBreakpoint == fifo.CPReadPointer)
|
||||
if (fifo.CPBreakpoint.load(std::memory_order_relaxed) ==
|
||||
fifo.CPReadPointer.load(std::memory_order_relaxed))
|
||||
{
|
||||
if (!fifo.bFF_Breakpoint)
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Hit breakpoint at {}", fifo.CPReadPointer);
|
||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Hit breakpoint at {}",
|
||||
fifo.CPReadPointer.load(std::memory_order_relaxed));
|
||||
fifo.bFF_Breakpoint = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fifo.bFF_Breakpoint)
|
||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Cleared breakpoint at {}", fifo.CPReadPointer);
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Cleared breakpoint at {}",
|
||||
fifo.CPReadPointer.load(std::memory_order_relaxed));
|
||||
}
|
||||
fifo.bFF_Breakpoint = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fifo.bFF_Breakpoint)
|
||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Cleared breakpoint at {}", fifo.CPReadPointer);
|
||||
{
|
||||
DEBUG_LOG_FMT(COMMANDPROCESSOR, "Cleared breakpoint at {}",
|
||||
fifo.CPReadPointer.load(std::memory_order_relaxed));
|
||||
}
|
||||
fifo.bFF_Breakpoint = false;
|
||||
}
|
||||
|
||||
// overflow & underflow check
|
||||
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
|
||||
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
|
||||
fifo.bFF_HiWatermark =
|
||||
(fifo.CPReadWriteDistance.load(std::memory_order_relaxed) > fifo.CPHiWatermark);
|
||||
fifo.bFF_LoWatermark =
|
||||
(fifo.CPReadWriteDistance.load(std::memory_order_relaxed) < fifo.CPLoWatermark);
|
||||
|
||||
bool bpInt = fifo.bFF_Breakpoint && fifo.bFF_BPInt;
|
||||
bool ovfInt = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt;
|
||||
@ -457,8 +493,10 @@ void SetCPStatusFromGPU()
|
||||
void SetCPStatusFromCPU()
|
||||
{
|
||||
// overflow & underflow check
|
||||
fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
|
||||
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
|
||||
fifo.bFF_HiWatermark =
|
||||
(fifo.CPReadWriteDistance.load(std::memory_order_relaxed) > fifo.CPHiWatermark);
|
||||
fifo.bFF_LoWatermark =
|
||||
(fifo.CPReadWriteDistance.load(std::memory_order_relaxed) < fifo.CPLoWatermark);
|
||||
|
||||
bool bpInt = fifo.bFF_Breakpoint && fifo.bFF_BPInt;
|
||||
bool ovfInt = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt;
|
||||
@ -489,9 +527,11 @@ void SetCpStatusRegister()
|
||||
{
|
||||
// Here always there is one fifo attached to the GPU
|
||||
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
|
||||
m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance || (fifo.CPReadPointer == fifo.CPWritePointer);
|
||||
m_CPStatusReg.CommandIdle =
|
||||
!fifo.CPReadWriteDistance || Fifo::AtBreakpoint() || !fifo.bFF_GPReadEnable;
|
||||
m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance.load(std::memory_order_relaxed) ||
|
||||
(fifo.CPReadPointer.load(std::memory_order_relaxed) ==
|
||||
fifo.CPWritePointer.load(std::memory_order_relaxed));
|
||||
m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance.load(std::memory_order_relaxed) ||
|
||||
Fifo::AtBreakpoint() || !fifo.bFF_GPReadEnable;
|
||||
m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark;
|
||||
m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark;
|
||||
|
||||
@ -548,29 +588,32 @@ void HandleUnknownOpcode(u8 cmd_byte, void* buffer, bool preprocess)
|
||||
cmd_byte, buffer, preprocess ? "preprocess=true" : "preprocess=false");
|
||||
|
||||
{
|
||||
PanicAlertFmt("Illegal command {:02x}\n"
|
||||
"CPBase: {:#010x}\n"
|
||||
"CPEnd: {:#010x}\n"
|
||||
"CPHiWatermark: {:#010x}\n"
|
||||
"CPLoWatermark: {:#010x}\n"
|
||||
"CPReadWriteDistance: {:#010x}\n"
|
||||
"CPWritePointer: {:#010x}\n"
|
||||
"CPReadPointer: {:#010x}\n"
|
||||
"CPBreakpoint: {:#010x}\n"
|
||||
"bFF_GPReadEnable: {}\n"
|
||||
"bFF_BPEnable: {}\n"
|
||||
"bFF_BPInt: {}\n"
|
||||
"bFF_Breakpoint: {}\n"
|
||||
"bFF_GPLinkEnable: {}\n"
|
||||
"bFF_HiWatermarkInt: {}\n"
|
||||
"bFF_LoWatermarkInt: {}\n",
|
||||
cmd_byte, fifo.CPBase, fifo.CPEnd, fifo.CPHiWatermark, fifo.CPLoWatermark,
|
||||
fifo.CPReadWriteDistance, fifo.CPWritePointer, fifo.CPReadPointer,
|
||||
fifo.CPBreakpoint, fifo.bFF_GPReadEnable ? "true" : "false",
|
||||
fifo.bFF_BPEnable ? "true" : "false", fifo.bFF_BPInt ? "true" : "false",
|
||||
fifo.bFF_Breakpoint ? "true" : "false", fifo.bFF_GPLinkEnable ? "true" : "false",
|
||||
fifo.bFF_HiWatermarkInt ? "true" : "false",
|
||||
fifo.bFF_LoWatermarkInt ? "true" : "false");
|
||||
PanicAlertFmt(
|
||||
"Illegal command {:02x}\n"
|
||||
"CPBase: {:#010x}\n"
|
||||
"CPEnd: {:#010x}\n"
|
||||
"CPHiWatermark: {:#010x}\n"
|
||||
"CPLoWatermark: {:#010x}\n"
|
||||
"CPReadWriteDistance: {:#010x}\n"
|
||||
"CPWritePointer: {:#010x}\n"
|
||||
"CPReadPointer: {:#010x}\n"
|
||||
"CPBreakpoint: {:#010x}\n"
|
||||
"bFF_GPReadEnable: {}\n"
|
||||
"bFF_BPEnable: {}\n"
|
||||
"bFF_BPInt: {}\n"
|
||||
"bFF_Breakpoint: {}\n"
|
||||
"bFF_GPLinkEnable: {}\n"
|
||||
"bFF_HiWatermarkInt: {}\n"
|
||||
"bFF_LoWatermarkInt: {}\n",
|
||||
cmd_byte, fifo.CPBase.load(std::memory_order_relaxed),
|
||||
fifo.CPEnd.load(std::memory_order_relaxed), fifo.CPHiWatermark, fifo.CPLoWatermark,
|
||||
fifo.CPReadWriteDistance.load(std::memory_order_relaxed),
|
||||
fifo.CPWritePointer.load(std::memory_order_relaxed),
|
||||
fifo.CPReadPointer.load(std::memory_order_relaxed),
|
||||
fifo.CPBreakpoint.load(std::memory_order_relaxed), fifo.bFF_GPReadEnable ? "true" : "false",
|
||||
fifo.bFF_BPEnable ? "true" : "false", fifo.bFF_BPInt ? "true" : "false",
|
||||
fifo.bFF_Breakpoint ? "true" : "false", fifo.bFF_GPLinkEnable ? "true" : "false",
|
||||
fifo.bFF_HiWatermarkInt ? "true" : "false", fifo.bFF_LoWatermarkInt ? "true" : "false");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
class PointerWrap;
|
||||
@ -17,15 +19,15 @@ namespace CommandProcessor
|
||||
struct SCPFifoStruct
|
||||
{
|
||||
// fifo registers
|
||||
volatile u32 CPBase;
|
||||
volatile u32 CPEnd;
|
||||
std::atomic<u32> CPBase;
|
||||
std::atomic<u32> CPEnd;
|
||||
u32 CPHiWatermark;
|
||||
u32 CPLoWatermark;
|
||||
volatile u32 CPReadWriteDistance;
|
||||
volatile u32 CPWritePointer;
|
||||
volatile u32 CPReadPointer;
|
||||
volatile u32 CPBreakpoint;
|
||||
volatile u32 SafeCPReadPointer;
|
||||
std::atomic<u32> CPReadWriteDistance;
|
||||
std::atomic<u32> CPWritePointer;
|
||||
std::atomic<u32> CPReadPointer;
|
||||
std::atomic<u32> CPBreakpoint;
|
||||
std::atomic<u32> SafeCPReadPointer;
|
||||
|
||||
volatile u32 bFF_GPLinkEnable;
|
||||
volatile u32 bFF_GPReadEnable;
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/Atomic.h"
|
||||
#include "Common/BlockingLoop.h"
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/Event.h"
|
||||
@ -329,33 +328,37 @@ void RunGpuLoop()
|
||||
|
||||
// check if we are able to run this buffer
|
||||
while (!CommandProcessor::IsInterruptWaiting() && fifo.bFF_GPReadEnable &&
|
||||
fifo.CPReadWriteDistance && !AtBreakpoint())
|
||||
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) && !AtBreakpoint())
|
||||
{
|
||||
if (param.bSyncGPU && s_sync_ticks.load() < param.iSyncGpuMinDistance)
|
||||
break;
|
||||
|
||||
u32 cyclesExecuted = 0;
|
||||
u32 readPtr = fifo.CPReadPointer;
|
||||
u32 readPtr = fifo.CPReadPointer.load(std::memory_order_relaxed);
|
||||
ReadDataFromFifo(readPtr);
|
||||
|
||||
if (readPtr == fifo.CPEnd)
|
||||
readPtr = fifo.CPBase;
|
||||
if (readPtr == fifo.CPEnd.load(std::memory_order_relaxed))
|
||||
readPtr = fifo.CPBase.load(std::memory_order_relaxed);
|
||||
else
|
||||
readPtr += 32;
|
||||
|
||||
ASSERT_MSG(COMMANDPROCESSOR, (s32)fifo.CPReadWriteDistance - 32 >= 0,
|
||||
ASSERT_MSG(COMMANDPROCESSOR,
|
||||
(s32)fifo.CPReadWriteDistance.load(std::memory_order_relaxed) - 32 >= 0,
|
||||
"Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce "
|
||||
"instability in the game. Please report it.",
|
||||
fifo.CPReadWriteDistance - 32);
|
||||
fifo.CPReadWriteDistance.load(std::memory_order_relaxed) - 32);
|
||||
|
||||
u8* write_ptr = s_video_buffer_write_ptr;
|
||||
s_video_buffer_read_ptr = OpcodeDecoder::Run(
|
||||
DataReader(s_video_buffer_read_ptr, write_ptr), &cyclesExecuted, false);
|
||||
|
||||
Common::AtomicStore(fifo.CPReadPointer, readPtr);
|
||||
Common::AtomicAdd(fifo.CPReadWriteDistance, static_cast<u32>(-32));
|
||||
fifo.CPReadPointer.store(readPtr, std::memory_order_relaxed);
|
||||
fifo.CPReadWriteDistance.fetch_sub(32, std::memory_order_seq_cst);
|
||||
if ((write_ptr - s_video_buffer_read_ptr) == 0)
|
||||
Common::AtomicStore(fifo.SafeCPReadPointer, fifo.CPReadPointer);
|
||||
{
|
||||
fifo.SafeCPReadPointer.store(fifo.CPReadPointer.load(std::memory_order_relaxed),
|
||||
std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
CommandProcessor::SetCPStatusFromGPU();
|
||||
|
||||
@ -412,7 +415,8 @@ void GpuMaySleep()
|
||||
bool AtBreakpoint()
|
||||
{
|
||||
CommandProcessor::SCPFifoStruct& fifo = CommandProcessor::fifo;
|
||||
return fifo.bFF_BPEnable && (fifo.CPReadPointer == fifo.CPBreakpoint);
|
||||
return fifo.bFF_BPEnable && (fifo.CPReadPointer.load(std::memory_order_relaxed) ==
|
||||
fifo.CPBreakpoint.load(std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
void RunGpu()
|
||||
@ -442,12 +446,12 @@ static int RunGpuOnCpu(int ticks)
|
||||
CommandProcessor::SCPFifoStruct& fifo = CommandProcessor::fifo;
|
||||
bool reset_simd_state = false;
|
||||
int available_ticks = int(ticks * SConfig::GetInstance().fSyncGpuOverclock) + s_sync_ticks.load();
|
||||
while (fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint() &&
|
||||
available_ticks >= 0)
|
||||
while (fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance.load(std::memory_order_relaxed) &&
|
||||
!AtBreakpoint() && available_ticks >= 0)
|
||||
{
|
||||
if (s_use_deterministic_gpu_thread)
|
||||
{
|
||||
ReadDataFromFifoOnCPU(fifo.CPReadPointer);
|
||||
ReadDataFromFifoOnCPU(fifo.CPReadPointer.load(std::memory_order_relaxed));
|
||||
s_gpu_mainloop.Wakeup();
|
||||
}
|
||||
else
|
||||
@ -458,19 +462,25 @@ static int RunGpuOnCpu(int ticks)
|
||||
FPURoundMode::LoadDefaultSIMDState();
|
||||
reset_simd_state = true;
|
||||
}
|
||||
ReadDataFromFifo(fifo.CPReadPointer);
|
||||
ReadDataFromFifo(fifo.CPReadPointer.load(std::memory_order_relaxed));
|
||||
u32 cycles = 0;
|
||||
s_video_buffer_read_ptr = OpcodeDecoder::Run(
|
||||
DataReader(s_video_buffer_read_ptr, s_video_buffer_write_ptr), &cycles, false);
|
||||
available_ticks -= cycles;
|
||||
}
|
||||
|
||||
if (fifo.CPReadPointer == fifo.CPEnd)
|
||||
fifo.CPReadPointer = fifo.CPBase;
|
||||
if (fifo.CPReadPointer.load(std::memory_order_relaxed) ==
|
||||
fifo.CPEnd.load(std::memory_order_relaxed))
|
||||
{
|
||||
fifo.CPReadPointer.store(fifo.CPBase.load(std::memory_order_relaxed),
|
||||
std::memory_order_relaxed);
|
||||
}
|
||||
else
|
||||
fifo.CPReadPointer += 32;
|
||||
{
|
||||
fifo.CPReadPointer.fetch_add(32, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
fifo.CPReadWriteDistance -= 32;
|
||||
fifo.CPReadWriteDistance.fetch_sub(32, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
CommandProcessor::SetCPStatusFromGPU();
|
||||
|
@ -890,7 +890,9 @@ void Renderer::CheckFifoRecording()
|
||||
RecordVideoMemory();
|
||||
}
|
||||
|
||||
FifoRecorder::GetInstance().EndFrame(CommandProcessor::fifo.CPBase, CommandProcessor::fifo.CPEnd);
|
||||
FifoRecorder::GetInstance().EndFrame(
|
||||
CommandProcessor::fifo.CPBase.load(std::memory_order_relaxed),
|
||||
CommandProcessor::fifo.CPEnd.load(std::memory_order_relaxed));
|
||||
}
|
||||
|
||||
void Renderer::RecordVideoMemory()
|
||||
|
Reference in New Issue
Block a user