diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp index ead6241fde..7a0c77b6a0 100644 --- a/Source/Core/VideoCommon/Fifo.cpp +++ b/Source/Core/VideoCommon/Fifo.cpp @@ -41,10 +41,10 @@ bool g_use_deterministic_gpu_thread; static std::mutex s_video_buffer_lock; static std::condition_variable s_video_buffer_cond; static u8* s_video_buffer; -u8* g_video_buffer_read_ptr; +static u8* s_video_buffer_read_ptr; static std::atomic s_video_buffer_write_ptr; static std::atomic s_video_buffer_seen_ptr; -u8* g_video_buffer_pp_read_ptr; +static u8* s_video_buffer_pp_read_ptr; // The read_ptr is always owned by the GPU thread. In normal mode, so is the // write_ptr, despite it being atomic. In g_use_deterministic_gpu_thread mode, // things get a bit more complicated: @@ -63,11 +63,11 @@ void Fifo_DoState(PointerWrap &p) u8* write_ptr = s_video_buffer_write_ptr; p.DoPointer(write_ptr, s_video_buffer); s_video_buffer_write_ptr = write_ptr; - p.DoPointer(g_video_buffer_read_ptr, s_video_buffer); + p.DoPointer(s_video_buffer_read_ptr, s_video_buffer); if (p.mode == PointerWrap::MODE_READ && g_use_deterministic_gpu_thread) { // We're good and paused, right? - s_video_buffer_seen_ptr = g_video_buffer_pp_read_ptr = g_video_buffer_read_ptr; + s_video_buffer_seen_ptr = s_video_buffer_pp_read_ptr = s_video_buffer_read_ptr; } p.Do(g_bSkipCurrentFrame); } @@ -106,8 +106,8 @@ void Fifo_Shutdown() FreeMemoryPages(s_video_buffer, FIFO_SIZE); s_video_buffer = nullptr; s_video_buffer_write_ptr = nullptr; - g_video_buffer_pp_read_ptr = nullptr; - g_video_buffer_read_ptr = nullptr; + s_video_buffer_pp_read_ptr = nullptr; + s_video_buffer_read_ptr = nullptr; s_video_buffer_seen_ptr = nullptr; s_fifo_aux_write_ptr = nullptr; s_fifo_aux_read_ptr = nullptr; @@ -169,15 +169,15 @@ void SyncGPU(SyncGPUReason reason, bool may_move_read_ptr) if (may_move_read_ptr) { // what's left over in the buffer - size_t size = write_ptr - g_video_buffer_pp_read_ptr; + size_t size = write_ptr - s_video_buffer_pp_read_ptr; - memmove(s_video_buffer, g_video_buffer_pp_read_ptr, size); + memmove(s_video_buffer, s_video_buffer_pp_read_ptr, size); // This change always decreases the pointers. We write seen_ptr // after write_ptr here, and read it before in RunGpuLoop, so // 'write_ptr > seen_ptr' there cannot become spuriously true. s_video_buffer_write_ptr = write_ptr = s_video_buffer + size; - g_video_buffer_pp_read_ptr = s_video_buffer; - g_video_buffer_read_ptr = s_video_buffer; + s_video_buffer_pp_read_ptr = s_video_buffer; + s_video_buffer_read_ptr = s_video_buffer; s_video_buffer_seen_ptr = write_ptr; } } @@ -213,15 +213,15 @@ static void ReadDataFromFifo(u32 readPtr) size_t len = 32; if (len > (size_t)(s_video_buffer + FIFO_SIZE - s_video_buffer_write_ptr)) { - size_t existing_len = s_video_buffer_write_ptr - g_video_buffer_read_ptr; + size_t existing_len = s_video_buffer_write_ptr - s_video_buffer_read_ptr; if (len > (size_t)(FIFO_SIZE - existing_len)) { PanicAlert("FIFO out of bounds (existing %lu + new %lu > %lu)", (unsigned long) existing_len, (unsigned long) len, (unsigned long) FIFO_SIZE); return; } - memmove(s_video_buffer, g_video_buffer_read_ptr, existing_len); + memmove(s_video_buffer, s_video_buffer_read_ptr, existing_len); s_video_buffer_write_ptr = s_video_buffer + existing_len; - g_video_buffer_read_ptr = s_video_buffer; + s_video_buffer_read_ptr = s_video_buffer; } // Copy new video instructions to s_video_buffer for future use in rendering the new picture Memory::CopyFromEmu(s_video_buffer_write_ptr, readPtr, len); @@ -238,13 +238,13 @@ static void ReadDataFromFifoOnCPU(u32 readPtr) // We can't wrap around while the GPU is working on the data. // This should be very rare due to the reset in SyncGPU. SyncGPU(SYNC_GPU_WRAPAROUND); - if (g_video_buffer_pp_read_ptr != g_video_buffer_read_ptr) + if (s_video_buffer_pp_read_ptr != s_video_buffer_read_ptr) { PanicAlert("desynced read pointers"); return; } write_ptr = s_video_buffer_write_ptr; - size_t existing_len = write_ptr - g_video_buffer_pp_read_ptr; + size_t existing_len = write_ptr - s_video_buffer_pp_read_ptr; if (len > (size_t)(FIFO_SIZE - existing_len)) { PanicAlert("FIFO out of bounds (existing %lu + new %lu > %lu)", (unsigned long) existing_len, (unsigned long) len, (unsigned long) FIFO_SIZE); @@ -252,17 +252,17 @@ static void ReadDataFromFifoOnCPU(u32 readPtr) } } Memory::CopyFromEmu(s_video_buffer_write_ptr, readPtr, len); - OpcodeDecoder_Preprocess(write_ptr + len, false); + s_video_buffer_pp_read_ptr = OpcodeDecoder_Preprocess(s_video_buffer_pp_read_ptr, write_ptr + len, false); // This would have to be locked if the GPU thread didn't spin. s_video_buffer_write_ptr = write_ptr + len; } void ResetVideoBuffer() { - g_video_buffer_read_ptr = s_video_buffer; + s_video_buffer_read_ptr = s_video_buffer; s_video_buffer_write_ptr = s_video_buffer; s_video_buffer_seen_ptr = s_video_buffer; - g_video_buffer_pp_read_ptr = s_video_buffer; + s_video_buffer_pp_read_ptr = s_video_buffer; s_fifo_aux_write_ptr = s_fifo_aux_data; s_fifo_aux_read_ptr = s_fifo_aux_data; } @@ -294,7 +294,7 @@ void RunGpuLoop() // See comment in SyncGPU if (write_ptr > seen_ptr) { - OpcodeDecoder_Run(write_ptr, false); + s_video_buffer_read_ptr = OpcodeDecoder_Run(s_video_buffer_read_ptr, write_ptr, nullptr, false); { std::lock_guard vblk(s_video_buffer_lock); @@ -330,7 +330,7 @@ void RunGpuLoop() u8* write_ptr = s_video_buffer_write_ptr; - cyclesExecuted = OpcodeDecoder_Run(write_ptr, false); + s_video_buffer_read_ptr = OpcodeDecoder_Run(s_video_buffer_read_ptr, write_ptr, &cyclesExecuted, false); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU && Common::AtomicLoad(CommandProcessor::VITicks) >= cyclesExecuted) @@ -338,7 +338,7 @@ void RunGpuLoop() Common::AtomicStore(fifo.CPReadPointer, readPtr); Common::AtomicAdd(fifo.CPReadWriteDistance, -32); - if ((write_ptr - g_video_buffer_read_ptr) == 0) + if ((write_ptr - s_video_buffer_read_ptr) == 0) Common::AtomicStore(fifo.SafeCPReadPointer, fifo.CPReadPointer); } @@ -403,7 +403,7 @@ void RunGpu() FPURoundMode::SaveSIMDState(); FPURoundMode::LoadDefaultSIMDState(); ReadDataFromFifo(fifo.CPReadPointer); - OpcodeDecoder_Run(s_video_buffer_write_ptr, false); + s_video_buffer_read_ptr = OpcodeDecoder_Run(s_video_buffer_read_ptr, s_video_buffer_write_ptr, nullptr, false); FPURoundMode::LoadSIMDState(); } @@ -454,7 +454,7 @@ void Fifo_UpdateWantDeterminism(bool want) if (gpu_thread) { // These haven't been updated in non-deterministic mode. - s_video_buffer_seen_ptr = g_video_buffer_pp_read_ptr = g_video_buffer_read_ptr; + s_video_buffer_seen_ptr = s_video_buffer_pp_read_ptr = s_video_buffer_read_ptr; CopyPreprocessCPStateFromMain(); VertexLoaderManager::MarkAllDirty(); } diff --git a/Source/Core/VideoCommon/Fifo.h b/Source/Core/VideoCommon/Fifo.h index 3a441c187c..d0b3c07015 100644 --- a/Source/Core/VideoCommon/Fifo.h +++ b/Source/Core/VideoCommon/Fifo.h @@ -17,7 +17,6 @@ extern bool g_bSkipCurrentFrame; // and can change at runtime. extern bool g_use_deterministic_gpu_thread; extern std::atomic g_video_buffer_write_ptr_xthread; -extern u8* g_video_buffer_pp_read_ptr; void Fifo_Init(); void Fifo_Shutdown(); diff --git a/Source/Core/VideoCommon/OpcodeDecoding.cpp b/Source/Core/VideoCommon/OpcodeDecoding.cpp index a7dd5b6a85..c5b1a09099 100644 --- a/Source/Core/VideoCommon/OpcodeDecoding.cpp +++ b/Source/Core/VideoCommon/OpcodeDecoding.cpp @@ -34,6 +34,9 @@ bool g_bRecordFifoData = false; +u8* g_video_buffer_read_ptr; +static u8* s_video_buffer_pp_read_ptr; + static u32 InterpretDisplayList(u32 address, u32 size) { u8* old_pVideoData = g_video_buffer_read_ptr; @@ -49,13 +52,10 @@ static u32 InterpretDisplayList(u32 address, u32 size) // Avoid the crash if Memory::GetPointer failed .. if (startAddress != nullptr) { - g_video_buffer_read_ptr = startAddress; - // temporarily swap dl and non-dl (small "hack" for the stats) Statistics::SwapDL(); - u8 *end = g_video_buffer_read_ptr + size; - cycles = OpcodeDecoder_Run(end, true); + OpcodeDecoder_Run(startAddress, startAddress + size, &cycles, true); INCSTAT(stats.thisFrame.numDListsCalled); // un-swap @@ -70,20 +70,17 @@ static u32 InterpretDisplayList(u32 address, u32 size) static void InterpretDisplayListPreprocess(u32 address, u32 size) { - u8* old_read_ptr = g_video_buffer_pp_read_ptr; + u8* old_read_ptr = s_video_buffer_pp_read_ptr; u8* startAddress = Memory::GetPointer(address); PushFifoAuxBuffer(startAddress, size); if (startAddress != nullptr) { - g_video_buffer_pp_read_ptr = startAddress; - - u8 *end = startAddress + size; - OpcodeDecoder_Preprocess(end, true); + OpcodeDecoder_Preprocess(startAddress, startAddress + size, true); } - g_video_buffer_pp_read_ptr = old_read_ptr; + s_video_buffer_pp_read_ptr = old_read_ptr; } static void UnknownOpcode(u8 cmd_byte, void *buffer, bool preprocess) @@ -315,33 +312,40 @@ void OpcodeDecoder_Shutdown() { } -u32 OpcodeDecoder_Run(u8* end, bool in_display_list) +u8* OpcodeDecoder_Run(u8* start, u8* end, u32* cycles, bool in_display_list) { + g_video_buffer_read_ptr = start; u32 totalCycles = 0; while (true) { u8* old = g_video_buffer_read_ptr; - u32 cycles = Decode(end, in_display_list); - if (cycles == 0) + u32 cycles_op = Decode(end, in_display_list); + if (cycles_op == 0) { g_video_buffer_read_ptr = old; break; } - totalCycles += cycles; + totalCycles += cycles_op; } - return totalCycles; + if (cycles) + { + *cycles = totalCycles; + } + return g_video_buffer_read_ptr; } -void OpcodeDecoder_Preprocess(u8 *end, bool in_display_list) +u8* OpcodeDecoder_Preprocess(u8* start, u8 *end, bool in_display_list) { + s_video_buffer_pp_read_ptr = start; while (true) { - u8* old = g_video_buffer_pp_read_ptr; - u32 cycles = Decode(end, in_display_list); + u8* old = s_video_buffer_pp_read_ptr; + u32 cycles = Decode(end, in_display_list); if (cycles == 0) { - g_video_buffer_pp_read_ptr = old; + s_video_buffer_pp_read_ptr = old; break; } } + return s_video_buffer_pp_read_ptr; } diff --git a/Source/Core/VideoCommon/OpcodeDecoding.h b/Source/Core/VideoCommon/OpcodeDecoding.h index a217da556e..96a79f35c7 100644 --- a/Source/Core/VideoCommon/OpcodeDecoding.h +++ b/Source/Core/VideoCommon/OpcodeDecoding.h @@ -40,5 +40,5 @@ extern bool g_bRecordFifoData; void OpcodeDecoder_Init(); void OpcodeDecoder_Shutdown(); -u32 OpcodeDecoder_Run(u8* end, bool in_display_list); -void OpcodeDecoder_Preprocess(u8* end, bool in_display_list); +u8* OpcodeDecoder_Run(u8* start, u8* end, u32* cycles, bool in_display_list); +u8* OpcodeDecoder_Preprocess(u8* start, u8* end, bool in_display_list);