mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-26 15:50:00 -06:00
Protect savestates while the threaded software renderer is running (#1864)
* First crack at ensuring the render thread doesn't touch GPU state while it's being serialized * Get rid of the semaphore wait * Add some extra fields into GPU3D's serialization * Oops, TempVertexBuffer is already serialized * Move vertex serialization into its own method * Lock the GPU3D state when rendering on the render thread or serializing it * Revert "Lock the GPU3D state when rendering on the render thread or serializing it" This reverts commit2f49a551c1
. * Add comments that describe the synchronization within GPU3D_Soft - I need to understand it before I can solve my actual problem - Now I do * Revert "Revert "Lock the GPU3D state when rendering on the render thread or serializing it"" This reverts commit1977566a6d
. * Let's try locking the GPU3D state throughout NDS::RunFrame - Just to see what happens * Slim down the lock's scope * Narrow the lock's scope some more * Remove the lock entirely * Try protecting the GPU3D state with just a mutex - I'll clean this up once I know it works * Remove a duplicate method definition * Add a missing `noexcept` specifier * Remove an unused function * Cut some non-hardware state from `GPU3D`'s savestate * Assume that the next frame after loading a savestate won't be identical * Actually, it _is_ worth it * Don't serialize the clip matrix - It's recalculated anyway * Serialize `RenderPolygonRAM` as an array of indexes * Clean up some comments - I liked the dialogue style, but oh well * Try restarting the render thread instead of using the lock - Let's see what happens * Put the lock back * Fix some polygon and vertex indexes being saved incorrectly - Taking the difference between two pointers results in the number of elements, not the number of bytes * Remove `SoftRenderer::StateBusy` since it turns out we don't need it - The real synchronization was the friends we made along the way
This commit is contained in:
@ -42,8 +42,10 @@ public:
|
||||
u32* GetLine(int line) override;
|
||||
|
||||
void SetupRenderThread(GPU& gpu);
|
||||
void EnableRenderThread();
|
||||
void StopRenderThread();
|
||||
private:
|
||||
friend void GPU3D::DoSavestate(Savestate* file) noexcept;
|
||||
// Notes on the interpolator:
|
||||
//
|
||||
// This is a theory on how the DS hardware interpolates values. It matches hardware output
|
||||
@ -506,8 +508,15 @@ private:
|
||||
Platform::Thread* RenderThread;
|
||||
std::atomic_bool RenderThreadRunning;
|
||||
std::atomic_bool RenderThreadRendering;
|
||||
|
||||
// Used by the main thread to tell the render thread to start rendering a frame
|
||||
Platform::Semaphore* Sema_RenderStart;
|
||||
|
||||
// Used by the render thread to tell the main thread that it's done rendering a frame
|
||||
Platform::Semaphore* Sema_RenderDone;
|
||||
|
||||
// Used to allow the main thread to read some scanlines
|
||||
// before (the 3D portion of) the entire frame is rasterized.
|
||||
Platform::Semaphore* Sema_ScanlineCount;
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user