From 1a2d599942479e53611c87a69b67bb8385e32838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 2 May 2023 21:52:43 +0200 Subject: [PATCH 1/2] JIT: Consider the block cache full a few block before it is, to allow space for proxy blocks. Should fix the following crash: Core/MIPS/JitCommon/JitBlockCache.cpp:190 JitBlock &b = blocks_[num_blocks_]; --- Core/MIPS/JitCommon/JitBlockCache.cpp | 5 +++-- Core/MIPS/JitCommon/JitBlockCache.h | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index a08f430ed4..1f0e2e0e29 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -76,7 +76,7 @@ static uint64_t HashJitBlock(const JitBlock &b) { } JitBlockCache::JitBlockCache(MIPSState *mipsState, CodeBlockCommon *codeBlock) : - codeBlock_(codeBlock), blocks_(nullptr), num_blocks_(0) { + codeBlock_(codeBlock) { } JitBlockCache::~JitBlockCache() { @@ -90,7 +90,8 @@ bool JitBlock::ContainsAddress(u32 em_address) { } bool JitBlockCache::IsFull() const { - return num_blocks_ >= MAX_NUM_BLOCKS - 1; + // -10 to safely leave space for some proxy blocks, which we don't check before we allocate (not ideal, but should work). + return num_blocks_ >= MAX_NUM_BLOCKS - 10; } void JitBlockCache::Init() { diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 6fde09d915..71b7df9660 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -184,10 +184,10 @@ private: MIPSOpcode GetEmuHackOpForBlock(int block_num) const; CodeBlockCommon *codeBlock_; - JitBlock *blocks_; + JitBlock *blocks_ = nullptr; std::unordered_multimap proxyBlockMap_; - int num_blocks_; + int num_blocks_ = 0; std::unordered_multimap links_to_; std::map, u32> block_map_; // (end_addr, start_addr) -> number From 97488c0a79f49063d802fb295c11934f2f59db82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 2 May 2023 22:04:14 +0200 Subject: [PATCH 2/2] Vulkan: Before cleaning the shader managers, drain the shader compile queue. Mainly paranoia, but might help with the mutex crash from #17364 --- Common/GPU/Vulkan/VulkanRenderManager.h | 2 +- GPU/Vulkan/GPU_Vulkan.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Common/GPU/Vulkan/VulkanRenderManager.h b/Common/GPU/Vulkan/VulkanRenderManager.h index 3cad859e8d..b0ca50d4bf 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.h +++ b/Common/GPU/Vulkan/VulkanRenderManager.h @@ -456,13 +456,13 @@ public: void Invalidate(InvalidationFlags flags); void ResetStats(); + void DrainCompileQueue(); private: void EndCurRenderStep(); void ThreadFunc(); void CompileThreadFunc(); - void DrainCompileQueue(); void Run(VKRRenderThreadTask &task); diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 30fec133c4..ee68954fd3 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -182,6 +182,9 @@ void GPU_Vulkan::SaveCache(const Path &filename) { } GPU_Vulkan::~GPU_Vulkan() { + VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + rm->DrainCompileQueue(); + SaveCache(shaderCachePath_); // Note: We save the cache in DeviceLost DestroyDeviceObjects();