diff --git a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc index 3f28dd485..9e55acc35 100644 --- a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc +++ b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc @@ -79,6 +79,17 @@ bool VulkanPipelineCache::Initialize() { } } + // Create Vulkan pipeline cache for faster pipeline creation. + VkPipelineCacheCreateInfo pipeline_cache_create_info = {}; + pipeline_cache_create_info.sType = + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + if (vulkan_device->functions().vkCreatePipelineCache( + vulkan_device->device(), &pipeline_cache_create_info, nullptr, + &vk_pipeline_cache_) != VK_SUCCESS) { + XELOGW("VulkanPipelineCache: Failed to create pipeline cache"); + vk_pipeline_cache_ = VK_NULL_HANDLE; + } + return true; } @@ -97,6 +108,12 @@ void VulkanPipelineCache::Shutdown() { } pipelines_.clear(); + // Destroy the pipeline cache. + if (vk_pipeline_cache_ != VK_NULL_HANDLE) { + dfn.vkDestroyPipelineCache(device, vk_pipeline_cache_, nullptr); + vk_pipeline_cache_ = VK_NULL_HANDLE; + } + // Destroy all internal shaders. ui::vulkan::util::DestroyAndNullHandle(dfn.vkDestroyShaderModule, device, depth_only_fragment_shader_); @@ -2172,7 +2189,7 @@ bool VulkanPipelineCache::EnsurePipelineCreated( const ui::vulkan::VulkanDevice::Functions& dfn = vulkan_device->functions(); const VkDevice device = vulkan_device->device(); VkPipeline pipeline; - if (dfn.vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, + if (dfn.vkCreateGraphicsPipelines(device, vk_pipeline_cache_, 1, &pipeline_create_info, nullptr, &pipeline) != VK_SUCCESS) { // TODO(Triang3l): Move these error messages outside. diff --git a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.h b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.h index 8b97327ec..529e34885 100644 --- a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.h +++ b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.h @@ -318,6 +318,9 @@ class VulkanPipelineCache { // shader interlock when no Xenos pixel shader provided. VkShaderModule depth_only_fragment_shader_ = VK_NULL_HANDLE; + // Vulkan pipeline cache for faster pipeline creation. + VkPipelineCache vk_pipeline_cache_ = VK_NULL_HANDLE; + std::unordered_map pipelines_; diff --git a/src/xenia/ui/vulkan/functions/device_1_0.inc b/src/xenia/ui/vulkan/functions/device_1_0.inc index 4e9eaa83a..bfeebc606 100644 --- a/src/xenia/ui/vulkan/functions/device_1_0.inc +++ b/src/xenia/ui/vulkan/functions/device_1_0.inc @@ -39,6 +39,7 @@ XE_UI_VULKAN_FUNCTION(vkCreateFramebuffer) XE_UI_VULKAN_FUNCTION(vkCreateGraphicsPipelines) XE_UI_VULKAN_FUNCTION(vkCreateImage) XE_UI_VULKAN_FUNCTION(vkCreateImageView) +XE_UI_VULKAN_FUNCTION(vkCreatePipelineCache) XE_UI_VULKAN_FUNCTION(vkCreatePipelineLayout) XE_UI_VULKAN_FUNCTION(vkCreateRenderPass) XE_UI_VULKAN_FUNCTION(vkCreateSampler) @@ -54,6 +55,7 @@ XE_UI_VULKAN_FUNCTION(vkDestroyFramebuffer) XE_UI_VULKAN_FUNCTION(vkDestroyImage) XE_UI_VULKAN_FUNCTION(vkDestroyImageView) XE_UI_VULKAN_FUNCTION(vkDestroyPipeline) +XE_UI_VULKAN_FUNCTION(vkDestroyPipelineCache) XE_UI_VULKAN_FUNCTION(vkDestroyPipelineLayout) XE_UI_VULKAN_FUNCTION(vkDestroyRenderPass) XE_UI_VULKAN_FUNCTION(vkDestroySampler)