Permalink
Browse files

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.
  • Loading branch information...
unknownbrackets committed Oct 31, 2018
1 parent dcf71fc commit 40ca49d0e3840e67dfdd10f39991f146557d33c8
@@ -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 @@ class GPU_GLES : public GPUCommon {
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 @@ class ShaderManagerGLES : public ShaderManagerCommon {
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 @@ class GPUCommon : public GPUInterface, public GPUDebugInterface {
bool IsReady() override {
return true;
}
void CancelReady() override {
}
void Reinitialize() override;
void BeginHostFrame() override;
@@ -169,6 +169,7 @@ class GPUInterface {
// 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 @@ class GPU_Vulkan : public GPUCommon {
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 @@ class PipelineManagerVulkan {
// 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;
};

0 comments on commit 40ca49d

Please sign in to comment.