From a8343cc19a3728d4a44c279dff167503a6eaecfc Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 24 Jun 2017 19:43:58 +1000 Subject: [PATCH] Vulkan: Don't save pipeline cache if shader cache is disabled We still create a pipeline cache object, since that speeds up driver's creation of pipelines at runtime. However, we should not save it. --- .../Core/VideoBackends/Vulkan/ObjectCache.cpp | 87 ++++++++++++------- .../Core/VideoBackends/Vulkan/ObjectCache.h | 3 +- Source/Core/VideoBackends/Vulkan/main.cpp | 3 +- 3 files changed, 58 insertions(+), 35 deletions(-) diff --git a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp index 4fadbfcfc4..ad138cc754 100644 --- a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp @@ -49,9 +49,17 @@ bool ObjectCache::Initialize() if (!CreatePipelineLayouts()) return false; - LoadShaderCaches(); - if (!CreatePipelineCache(true)) - return false; + if (g_ActiveConfig.bShaderCache) + { + LoadShaderCaches(); + if (!LoadPipelineCache()) + return false; + } + else + { + if (!CreatePipelineCache()) + return false; + } if (!CreateUtilityShaderVertexFormat()) return false; @@ -465,26 +473,44 @@ public: void Read(const u32& key, const u8* value, u32 value_size) override {} }; -bool ObjectCache::CreatePipelineCache(bool load_from_disk) +bool ObjectCache::CreatePipelineCache() +{ + m_pipeline_cache_filename = GetDiskCacheFileName("pipeline"); + + VkPipelineCacheCreateInfo info = { + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType + nullptr, // const void* pNext + 0, // VkPipelineCacheCreateFlags flags + 0, // size_t initialDataSize + nullptr // const void* pInitialData + }; + + VkResult res = + vkCreatePipelineCache(g_vulkan_context->GetDevice(), &info, nullptr, &m_pipeline_cache); + if (res == VK_SUCCESS) + return true; + + LOG_VULKAN_ERROR(res, "vkCreatePipelineCache failed: "); + return false; +} + +bool ObjectCache::LoadPipelineCache() { // We have to keep the pipeline cache file name around since when we save it // we delete the old one, by which time the game's unique ID is already cleared. m_pipeline_cache_filename = GetDiskCacheFileName("pipeline"); std::vector disk_data; - if (load_from_disk) - { - LinearDiskCache disk_cache; - PipelineCacheReadCallback read_callback(&disk_data); - if (disk_cache.OpenAndRead(m_pipeline_cache_filename, read_callback) != 1) - disk_data.clear(); - } + LinearDiskCache disk_cache; + PipelineCacheReadCallback read_callback(&disk_data); + if (disk_cache.OpenAndRead(m_pipeline_cache_filename, read_callback) != 1) + disk_data.clear(); if (!disk_data.empty() && !ValidatePipelineCache(disk_data.data(), disk_data.size())) { // Don't use this data. In fact, we should delete it to prevent it from being used next time. File::Delete(m_pipeline_cache_filename); - disk_data.clear(); + return CreatePipelineCache(); } VkPipelineCacheCreateInfo info = { @@ -492,7 +518,7 @@ bool ObjectCache::CreatePipelineCache(bool load_from_disk) nullptr, // const void* pNext 0, // VkPipelineCacheCreateFlags flags disk_data.size(), // size_t initialDataSize - !disk_data.empty() ? disk_data.data() : nullptr, // const void* pInitialData + disk_data.data() // const void* pInitialData }; VkResult res = @@ -502,14 +528,7 @@ bool ObjectCache::CreatePipelineCache(bool load_from_disk) // Failed to create pipeline cache, try with it empty. LOG_VULKAN_ERROR(res, "vkCreatePipelineCache failed, trying empty cache: "); - info.initialDataSize = 0; - info.pInitialData = nullptr; - res = vkCreatePipelineCache(g_vulkan_context->GetDevice(), &info, nullptr, &m_pipeline_cache); - if (res == VK_SUCCESS) - return true; - - LOG_VULKAN_ERROR(res, "vkCreatePipelineCache failed: "); - return false; + return CreatePipelineCache(); } // Based on Vulkan 1.0 specification, @@ -644,19 +663,16 @@ struct ShaderCacheReader : public LinearDiskCacheReader void ObjectCache::LoadShaderCaches() { - if (g_ActiveConfig.bShaderCache) + ShaderCacheReader vs_reader(m_vs_cache.shader_map); + m_vs_cache.disk_cache.OpenAndRead(GetDiskCacheFileName("vs"), vs_reader); + + ShaderCacheReader ps_reader(m_ps_cache.shader_map); + m_ps_cache.disk_cache.OpenAndRead(GetDiskCacheFileName("ps"), ps_reader); + + if (g_vulkan_context->SupportsGeometryShaders()) { - ShaderCacheReader vs_reader(m_vs_cache.shader_map); - m_vs_cache.disk_cache.OpenAndRead(GetDiskCacheFileName("vs"), vs_reader); - - ShaderCacheReader ps_reader(m_ps_cache.shader_map); - m_ps_cache.disk_cache.OpenAndRead(GetDiskCacheFileName("ps"), ps_reader); - - if (g_vulkan_context->SupportsGeometryShaders()) - { - ShaderCacheReader gs_reader(m_gs_cache.shader_map); - m_gs_cache.disk_cache.OpenAndRead(GetDiskCacheFileName("gs"), gs_reader); - } + ShaderCacheReader gs_reader(m_gs_cache.shader_map); + m_gs_cache.disk_cache.OpenAndRead(GetDiskCacheFileName("gs"), gs_reader); } SETSTAT(stats.numPixelShadersCreated, static_cast(m_ps_cache.shader_map.size())); @@ -684,6 +700,11 @@ void ObjectCache::DestroyShaderCaches() if (g_vulkan_context->SupportsGeometryShaders()) DestroyShaderCache(m_gs_cache); + + SETSTAT(stats.numPixelShadersCreated, 0); + SETSTAT(stats.numPixelShadersAlive, 0); + SETSTAT(stats.numVertexShadersCreated, 0); + SETSTAT(stats.numVertexShadersAlive, 0); } VkShaderModule ObjectCache::GetVertexShaderForUid(const VertexShaderUid& uid) diff --git a/Source/Core/VideoBackends/Vulkan/ObjectCache.h b/Source/Core/VideoBackends/Vulkan/ObjectCache.h index 97c457a7f8..8d7f4f6cc7 100644 --- a/Source/Core/VideoBackends/Vulkan/ObjectCache.h +++ b/Source/Core/VideoBackends/Vulkan/ObjectCache.h @@ -163,7 +163,8 @@ public: std::string GetDiskCacheFileName(const char* type); private: - bool CreatePipelineCache(bool load_from_disk); + bool CreatePipelineCache(); + bool LoadPipelineCache(); bool ValidatePipelineCache(const u8* data, size_t data_length); void DestroyPipelineCache(); void LoadShaderCaches(); diff --git a/Source/Core/VideoBackends/Vulkan/main.cpp b/Source/Core/VideoBackends/Vulkan/main.cpp index 6eaaa09b4c..2fdcae7e98 100644 --- a/Source/Core/VideoBackends/Vulkan/main.cpp +++ b/Source/Core/VideoBackends/Vulkan/main.cpp @@ -290,7 +290,8 @@ void VideoBackend::Video_Cleanup() g_command_buffer_mgr->WaitForGPUIdle(); // Save all cached pipelines out to disk for next time. - g_object_cache->SavePipelineCache(); + if (g_ActiveConfig.bShaderCache) + g_object_cache->SavePipelineCache(); g_perf_query.reset(); g_texture_cache.reset();