mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
GetRenderPass() looks up and inserts into renderPasses_ from the main thread (EndCurRenderStep, CreateGraphicsPipeline) and from the render thread (PerformBindFramebufferAsRenderTarget), unsynchronized. The render thread really does insert rather than only hit: PreprocessSteps rewrites the load actions to CLEAR when it merges a clear-only pass into a later one, after the main thread already looked up the pre-merge key. DenseHashMap::Insert can Grow(), which reallocates the buckets out from under a concurrent Get(). VKRRenderPass::Get() has the same problem one level down - it creates the passes lazily and is called from both threads on the same object, so two threads hitting an empty slot each create a pass and one gets overwritten and leaked, while the sample-count branch can queue a pass for deletion that the other thread is about to hand to vkCreateGraphicsPipelines. A mutex each. Handing the VKRRenderPass pointer out from under the map lock is fine, entries are only ever erased all at once in DestroyDeviceObjects. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Vd8ntC2brCUtCrDJMqLbs8