mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-17 07:31:01 +00:00
GPU: Cancel shader preload on shutdown/lost.
Otherwise, we could've ended up with shaders loading after or during the lost event, and dense hash map corruption.
This commit is contained in:
parent
dcf71fc43f
commit
40ca49d0e3
@ -312,6 +312,10 @@ bool GPU_GLES::IsReady() {
|
||||
return shaderManagerGL_->ContinuePrecompile();
|
||||
}
|
||||
|
||||
void GPU_GLES::CancelReady() {
|
||||
shaderManagerGL_->CancelPrecompile();
|
||||
}
|
||||
|
||||
void GPU_GLES::BuildReportingInfo() {
|
||||
GLRenderManager *render = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
|
||||
|
||||
@ -341,6 +345,7 @@ void GPU_GLES::DeviceLost() {
|
||||
// Simply drop all caches and textures.
|
||||
// FBOs appear to survive? Or no?
|
||||
// TransformDraw has registered as a GfxResourceHolder.
|
||||
CancelReady();
|
||||
shaderManagerGL_->DeviceLost();
|
||||
textureCacheGL_->DeviceLost();
|
||||
fragmentTestCache_.DeviceLost();
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
void CheckGPUFeatures() override;
|
||||
|
||||
bool IsReady() override;
|
||||
void CancelReady() override;
|
||||
|
||||
void PreExecuteOp(u32 op, u32 diff) override;
|
||||
void ExecuteOp(u32 op, u32 diff) override;
|
||||
|
@ -990,6 +990,10 @@ bool ShaderManagerGLES::ContinuePrecompile(float sliceTime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShaderManagerGLES::CancelPrecompile() {
|
||||
diskCachePending_.Clear();
|
||||
}
|
||||
|
||||
void ShaderManagerGLES::Save(const std::string &filename) {
|
||||
if (!diskCacheDirty_) {
|
||||
return;
|
||||
|
@ -179,6 +179,7 @@ public:
|
||||
|
||||
void Load(const std::string &filename);
|
||||
bool ContinuePrecompile(float sliceTime = 1.0f / 60.0f);
|
||||
void CancelPrecompile();
|
||||
void Save(const std::string &filename);
|
||||
|
||||
private:
|
||||
|
@ -107,9 +107,11 @@ bool GPU_Init(GraphicsContext *ctx, Draw::DrawContext *draw) {
|
||||
|
||||
void GPU_Shutdown() {
|
||||
// Wait for IsReady, since it might be running on a thread.
|
||||
// Potentially we could set a flag to try to early quit.
|
||||
while (gpu && !gpu->IsReady()) {
|
||||
sleep_ms(10);
|
||||
if (gpu) {
|
||||
gpu->CancelReady();
|
||||
while (!gpu->IsReady()) {
|
||||
sleep_ms(10);
|
||||
}
|
||||
}
|
||||
delete gpu;
|
||||
gpu = nullptr;
|
||||
|
@ -77,6 +77,8 @@ public:
|
||||
bool IsReady() override {
|
||||
return true;
|
||||
}
|
||||
void CancelReady() override {
|
||||
}
|
||||
void Reinitialize() override;
|
||||
|
||||
void BeginHostFrame() override;
|
||||
|
@ -169,6 +169,7 @@ public:
|
||||
|
||||
// Initialization
|
||||
virtual bool IsReady() = 0;
|
||||
virtual void CancelReady() = 0;
|
||||
virtual void InitClear() = 0;
|
||||
virtual void Reinitialize() = 0;
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <thread>
|
||||
#include "base/logging.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "profiler/profiler.h"
|
||||
|
||||
#include "Common/ChunkFile.h"
|
||||
@ -119,6 +120,10 @@ bool GPU_Vulkan::IsReady() {
|
||||
return shaderCacheLoaded_;
|
||||
}
|
||||
|
||||
void GPU_Vulkan::CancelReady() {
|
||||
pipelineManager_->CancelCache();
|
||||
}
|
||||
|
||||
void GPU_Vulkan::LoadCache(std::string filename) {
|
||||
PSP_SetLoading("Loading shader cache...");
|
||||
// Actually precompiled by IsReady() since we're single-threaded.
|
||||
@ -492,6 +497,10 @@ void GPU_Vulkan::DestroyDeviceObjects() {
|
||||
}
|
||||
|
||||
void GPU_Vulkan::DeviceLost() {
|
||||
CancelReady();
|
||||
while (!IsReady()) {
|
||||
sleep_ms(10);
|
||||
}
|
||||
if (!shaderCachePath_.empty()) {
|
||||
SaveCache(shaderCachePath_);
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
void CheckGPUFeatures() override;
|
||||
|
||||
bool IsReady() override;
|
||||
void CancelReady() override;
|
||||
|
||||
// These are where we can reset command buffers etc.
|
||||
void BeginHostFrame() override;
|
||||
|
@ -709,7 +709,7 @@ bool PipelineManagerVulkan::LoadCache(FILE *file, bool loadRawPipelineCache, Sha
|
||||
|
||||
NOTICE_LOG(G3D, "Creating %d pipelines...", size);
|
||||
for (uint32_t i = 0; i < size; i++) {
|
||||
if (failed) {
|
||||
if (failed || cancelCache_) {
|
||||
break;
|
||||
}
|
||||
StoredVulkanPipelineKey key;
|
||||
@ -742,3 +742,7 @@ bool PipelineManagerVulkan::LoadCache(FILE *file, bool loadRawPipelineCache, Sha
|
||||
NOTICE_LOG(G3D, "Recreated Vulkan pipeline cache (%d pipelines).", (int)size);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PipelineManagerVulkan::CancelCache() {
|
||||
cancelCache_ = true;
|
||||
}
|
||||
|
@ -98,10 +98,12 @@ public:
|
||||
// Saves data for faster creation next time.
|
||||
void SaveCache(FILE *file, bool saveRawPipelineCache, ShaderManagerVulkan *shaderManager, Draw::DrawContext *drawContext);
|
||||
bool LoadCache(FILE *file, bool loadRawPipelineCache, ShaderManagerVulkan *shaderManager, Draw::DrawContext *drawContext, VkPipelineLayout layout);
|
||||
void CancelCache();
|
||||
|
||||
private:
|
||||
DenseHashMap<VulkanPipelineKey, VulkanPipeline *, nullptr> pipelines_;
|
||||
VkPipelineCache pipelineCache_ = VK_NULL_HANDLE;
|
||||
VulkanContext *vulkan_;
|
||||
float lineWidth_ = 1.0f;
|
||||
bool cancelCache_ = false;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user