From 7ec62a32b461f65c70aa63ddff6fb6c27990c7fb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 23 Aug 2022 20:15:30 -0700 Subject: [PATCH] GPU: More consistently clear ptrs on DeviceLost(). Rather get a null pointer crash than confusing buggy use-after-free excitement. --- GPU/Common/FramebufferManagerCommon.cpp | 2 +- GPU/Common/PresentationCommon.cpp | 1 + GPU/Common/TextureShaderCommon.cpp | 1 + GPU/GLES/DrawEngineGLES.cpp | 2 ++ GPU/GLES/FragmentTestCacheGLES.h | 1 + GPU/GLES/ShaderManagerGLES.cpp | 2 ++ GPU/Vulkan/GPU_Vulkan.cpp | 2 +- GPU/Vulkan/PipelineManagerVulkan.cpp | 2 ++ GPU/Vulkan/ShaderManagerVulkan.cpp | 4 ++++ GPU/Vulkan/ShaderManagerVulkan.h | 1 + GPU/Vulkan/TextureCacheVulkan.cpp | 1 + 11 files changed, 17 insertions(+), 2 deletions(-) diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index ffc4777aa2..8cddd8e782 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -2437,7 +2437,7 @@ void FramebufferManagerCommon::DeviceLost() { void FramebufferManagerCommon::DeviceRestore(Draw::DrawContext *draw) { draw_ = draw; draw2D_.DeviceRestore(draw_); - presentation_->DeviceRestore(draw); + presentation_->DeviceRestore(draw_); } void FramebufferManagerCommon::DrawActiveTexture(float x, float y, float w, float h, float destW, float destH, float u0, float v0, float u1, float v1, int uvRotation, int flags) { diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index ccfa4cdd88..5f79861fd7 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -393,6 +393,7 @@ void PresentationCommon::ShowPostShaderError(const std::string &errorString) { void PresentationCommon::DeviceLost() { DestroyDeviceObjects(); + draw_ = nullptr; } void PresentationCommon::DeviceRestore(Draw::DrawContext *draw) { diff --git a/GPU/Common/TextureShaderCommon.cpp b/GPU/Common/TextureShaderCommon.cpp index 694a646131..b1c38c4f2d 100644 --- a/GPU/Common/TextureShaderCommon.cpp +++ b/GPU/Common/TextureShaderCommon.cpp @@ -50,6 +50,7 @@ void TextureShaderCache::DeviceRestore(Draw::DrawContext *draw) { void TextureShaderCache::DeviceLost() { Clear(); + draw_ = nullptr; } ClutTexture TextureShaderCache::GetClutTexture(GEPaletteFormat clutFormat, const u32 clutHash, u32 *rawClut) { diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index 96dc11ea22..9a1e6aa1ea 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -91,6 +91,8 @@ DrawEngineGLES::~DrawEngineGLES() { void DrawEngineGLES::DeviceLost() { DestroyDeviceObjects(); + draw_ = nullptr; + render_ = nullptr; } void DrawEngineGLES::DeviceRestore(Draw::DrawContext *draw) { diff --git a/GPU/GLES/FragmentTestCacheGLES.h b/GPU/GLES/FragmentTestCacheGLES.h index da7f1c78b8..c1c434698f 100644 --- a/GPU/GLES/FragmentTestCacheGLES.h +++ b/GPU/GLES/FragmentTestCacheGLES.h @@ -69,6 +69,7 @@ public: void DeviceLost() { Clear(false); + render_ = nullptr; } void DeviceRestore(Draw::DrawContext *draw); void Clear(bool deleteThem = true); diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 858052f43e..ee708edad1 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -620,6 +620,8 @@ void ShaderManagerGLES::ClearCache(bool deleteThem) { void ShaderManagerGLES::DeviceLost() { Clear(); + render_ = nullptr; + draw_ = nullptr; } void ShaderManagerGLES::DeviceRestore(Draw::DrawContext *draw) { diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index cab0ccf3cd..a21ca2559e 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -534,7 +534,7 @@ void GPU_Vulkan::DeviceLost() { drawEngine_.DeviceLost(); pipelineManager_->DeviceLost(); textureCacheVulkan_->DeviceLost(); - shaderManagerVulkan_->ClearShaders(); + shaderManagerVulkan_->DeviceLost(); GPUCommon::DeviceLost(); } diff --git a/GPU/Vulkan/PipelineManagerVulkan.cpp b/GPU/Vulkan/PipelineManagerVulkan.cpp index 3d79c9173c..86fa279b9c 100644 --- a/GPU/Vulkan/PipelineManagerVulkan.cpp +++ b/GPU/Vulkan/PipelineManagerVulkan.cpp @@ -26,6 +26,7 @@ PipelineManagerVulkan::~PipelineManagerVulkan() { Clear(); if (pipelineCache_ != VK_NULL_HANDLE) vulkan_->Delete().QueueDeletePipelineCache(pipelineCache_); + vulkan_ = nullptr; } void PipelineManagerVulkan::Clear() { @@ -55,6 +56,7 @@ void PipelineManagerVulkan::DeviceLost() { Clear(); if (pipelineCache_ != VK_NULL_HANDLE) vulkan_->Delete().QueueDeletePipelineCache(pipelineCache_); + vulkan_ = nullptr; } void PipelineManagerVulkan::DeviceRestore(VulkanContext *vulkan) { diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index 9e2c36a949..26057328cf 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -160,6 +160,10 @@ ShaderManagerVulkan::~ShaderManagerVulkan() { delete[] codeBuffer_; } +void ShaderManagerVulkan::DeviceLost() { + draw_ = nullptr; +} + void ShaderManagerVulkan::DeviceRestore(Draw::DrawContext *draw) { VulkanContext *vulkan = (VulkanContext *)draw->GetNativeObject(Draw::NativeObject::CONTEXT); draw_ = draw; diff --git a/GPU/Vulkan/ShaderManagerVulkan.h b/GPU/Vulkan/ShaderManagerVulkan.h index e3fbfd9395..4b167e002b 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.h +++ b/GPU/Vulkan/ShaderManagerVulkan.h @@ -86,6 +86,7 @@ public: ShaderManagerVulkan(Draw::DrawContext *draw); ~ShaderManagerVulkan(); + void DeviceLost(); void DeviceRestore(Draw::DrawContext *draw); void GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform, bool useHWTessellation, bool weightsAsFloat); diff --git a/GPU/Vulkan/TextureCacheVulkan.cpp b/GPU/Vulkan/TextureCacheVulkan.cpp index 555e23b1fd..22bfd74d08 100644 --- a/GPU/Vulkan/TextureCacheVulkan.cpp +++ b/GPU/Vulkan/TextureCacheVulkan.cpp @@ -168,6 +168,7 @@ void SamplerCache::DeviceLost() { vulkan_->Delete().QueueDeleteSampler(sampler); }); cache_.Clear(); + vulkan_ = nullptr; } void SamplerCache::DeviceRestore(VulkanContext *vulkan) {