diff options
| author | 2022-12-30 14:50:07 +0100 | |
|---|---|---|
| committer | 2023-01-05 21:02:44 +0100 | |
| commit | 16809c1fa7e2b4fb798749030645deaec79a2381 (patch) | |
| tree | e43ef31843da210165c529494652014a660268e6 /src/video_core/vulkan_common | |
| parent | Merge pull request #9557 from FernandoS27/ooops-i-killed-the-shitty-drivers (diff) | |
| download | yuzu-16809c1fa7e2b4fb798749030645deaec79a2381.tar.gz yuzu-16809c1fa7e2b4fb798749030645deaec79a2381.tar.xz yuzu-16809c1fa7e2b4fb798749030645deaec79a2381.zip | |
video_core/vulkan: Added `VkPipelineCache` to store Vulkan pipelines
As an optional feature which can be enabled in the advanced graphics configuration, all pipelines that get built at the initial shader loading are stored in a VkPipelineCache object and are dumped to the disk.
These vendor specific pipeline cache files are located at `/shader/GAME_ID/vulkan_pipelines.bin`. This feature was mainly added because of an issue with the AMD driver (see yuzu-emu#8507) causing invalidation of the cache files the driver builds automatically.
Diffstat (limited to 'src/video_core/vulkan_common')
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.cpp | 27 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.h | 24 |
2 files changed, 45 insertions, 6 deletions
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index 861767c13..61be1fce1 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp | |||
| @@ -152,6 +152,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 152 | X(vkCreateGraphicsPipelines); | 152 | X(vkCreateGraphicsPipelines); |
| 153 | X(vkCreateImage); | 153 | X(vkCreateImage); |
| 154 | X(vkCreateImageView); | 154 | X(vkCreateImageView); |
| 155 | X(vkCreatePipelineCache); | ||
| 155 | X(vkCreatePipelineLayout); | 156 | X(vkCreatePipelineLayout); |
| 156 | X(vkCreateQueryPool); | 157 | X(vkCreateQueryPool); |
| 157 | X(vkCreateRenderPass); | 158 | X(vkCreateRenderPass); |
| @@ -171,6 +172,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 171 | X(vkDestroyImage); | 172 | X(vkDestroyImage); |
| 172 | X(vkDestroyImageView); | 173 | X(vkDestroyImageView); |
| 173 | X(vkDestroyPipeline); | 174 | X(vkDestroyPipeline); |
| 175 | X(vkDestroyPipelineCache); | ||
| 174 | X(vkDestroyPipelineLayout); | 176 | X(vkDestroyPipelineLayout); |
| 175 | X(vkDestroyQueryPool); | 177 | X(vkDestroyQueryPool); |
| 176 | X(vkDestroyRenderPass); | 178 | X(vkDestroyRenderPass); |
| @@ -188,6 +190,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 188 | X(vkGetEventStatus); | 190 | X(vkGetEventStatus); |
| 189 | X(vkGetFenceStatus); | 191 | X(vkGetFenceStatus); |
| 190 | X(vkGetImageMemoryRequirements); | 192 | X(vkGetImageMemoryRequirements); |
| 193 | X(vkGetPipelineCacheData); | ||
| 191 | X(vkGetMemoryFdKHR); | 194 | X(vkGetMemoryFdKHR); |
| 192 | #ifdef _WIN32 | 195 | #ifdef _WIN32 |
| 193 | X(vkGetMemoryWin32HandleKHR); | 196 | X(vkGetMemoryWin32HandleKHR); |
| @@ -431,6 +434,10 @@ void Destroy(VkDevice device, VkPipeline handle, const DeviceDispatch& dld) noex | |||
| 431 | dld.vkDestroyPipeline(device, handle, nullptr); | 434 | dld.vkDestroyPipeline(device, handle, nullptr); |
| 432 | } | 435 | } |
| 433 | 436 | ||
| 437 | void Destroy(VkDevice device, VkPipelineCache handle, const DeviceDispatch& dld) noexcept { | ||
| 438 | dld.vkDestroyPipelineCache(device, handle, nullptr); | ||
| 439 | } | ||
| 440 | |||
| 434 | void Destroy(VkDevice device, VkPipelineLayout handle, const DeviceDispatch& dld) noexcept { | 441 | void Destroy(VkDevice device, VkPipelineLayout handle, const DeviceDispatch& dld) noexcept { |
| 435 | dld.vkDestroyPipelineLayout(device, handle, nullptr); | 442 | dld.vkDestroyPipelineLayout(device, handle, nullptr); |
| 436 | } | 443 | } |
| @@ -651,6 +658,10 @@ void ShaderModule::SetObjectNameEXT(const char* name) const { | |||
| 651 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_SHADER_MODULE, name); | 658 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_SHADER_MODULE, name); |
| 652 | } | 659 | } |
| 653 | 660 | ||
| 661 | void PipelineCache::SetObjectNameEXT(const char* name) const { | ||
| 662 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_PIPELINE_CACHE, name); | ||
| 663 | } | ||
| 664 | |||
| 654 | void Semaphore::SetObjectNameEXT(const char* name) const { | 665 | void Semaphore::SetObjectNameEXT(const char* name) const { |
| 655 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_SEMAPHORE, name); | 666 | SetObjectName(dld, owner, handle, VK_OBJECT_TYPE_SEMAPHORE, name); |
| 656 | } | 667 | } |
| @@ -746,21 +757,29 @@ DescriptorSetLayout Device::CreateDescriptorSetLayout( | |||
| 746 | return DescriptorSetLayout(object, handle, *dld); | 757 | return DescriptorSetLayout(object, handle, *dld); |
| 747 | } | 758 | } |
| 748 | 759 | ||
| 760 | PipelineCache Device::CreatePipelineCache(const VkPipelineCacheCreateInfo& ci) const { | ||
| 761 | VkPipelineCache cache; | ||
| 762 | Check(dld->vkCreatePipelineCache(handle, &ci, nullptr, &cache)); | ||
| 763 | return PipelineCache(cache, handle, *dld); | ||
| 764 | } | ||
| 765 | |||
| 749 | PipelineLayout Device::CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const { | 766 | PipelineLayout Device::CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const { |
| 750 | VkPipelineLayout object; | 767 | VkPipelineLayout object; |
| 751 | Check(dld->vkCreatePipelineLayout(handle, &ci, nullptr, &object)); | 768 | Check(dld->vkCreatePipelineLayout(handle, &ci, nullptr, &object)); |
| 752 | return PipelineLayout(object, handle, *dld); | 769 | return PipelineLayout(object, handle, *dld); |
| 753 | } | 770 | } |
| 754 | 771 | ||
| 755 | Pipeline Device::CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci) const { | 772 | Pipeline Device::CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci, |
| 773 | VkPipelineCache cache) const { | ||
| 756 | VkPipeline object; | 774 | VkPipeline object; |
| 757 | Check(dld->vkCreateGraphicsPipelines(handle, nullptr, 1, &ci, nullptr, &object)); | 775 | Check(dld->vkCreateGraphicsPipelines(handle, cache, 1, &ci, nullptr, &object)); |
| 758 | return Pipeline(object, handle, *dld); | 776 | return Pipeline(object, handle, *dld); |
| 759 | } | 777 | } |
| 760 | 778 | ||
| 761 | Pipeline Device::CreateComputePipeline(const VkComputePipelineCreateInfo& ci) const { | 779 | Pipeline Device::CreateComputePipeline(const VkComputePipelineCreateInfo& ci, |
| 780 | VkPipelineCache cache) const { | ||
| 762 | VkPipeline object; | 781 | VkPipeline object; |
| 763 | Check(dld->vkCreateComputePipelines(handle, nullptr, 1, &ci, nullptr, &object)); | 782 | Check(dld->vkCreateComputePipelines(handle, cache, 1, &ci, nullptr, &object)); |
| 764 | return Pipeline(object, handle, *dld); | 783 | return Pipeline(object, handle, *dld); |
| 765 | } | 784 | } |
| 766 | 785 | ||
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index accfad8c1..412779b51 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h | |||
| @@ -270,6 +270,7 @@ struct DeviceDispatch : InstanceDispatch { | |||
| 270 | PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines{}; | 270 | PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines{}; |
| 271 | PFN_vkCreateImage vkCreateImage{}; | 271 | PFN_vkCreateImage vkCreateImage{}; |
| 272 | PFN_vkCreateImageView vkCreateImageView{}; | 272 | PFN_vkCreateImageView vkCreateImageView{}; |
| 273 | PFN_vkCreatePipelineCache vkCreatePipelineCache{}; | ||
| 273 | PFN_vkCreatePipelineLayout vkCreatePipelineLayout{}; | 274 | PFN_vkCreatePipelineLayout vkCreatePipelineLayout{}; |
| 274 | PFN_vkCreateQueryPool vkCreateQueryPool{}; | 275 | PFN_vkCreateQueryPool vkCreateQueryPool{}; |
| 275 | PFN_vkCreateRenderPass vkCreateRenderPass{}; | 276 | PFN_vkCreateRenderPass vkCreateRenderPass{}; |
| @@ -289,6 +290,7 @@ struct DeviceDispatch : InstanceDispatch { | |||
| 289 | PFN_vkDestroyImage vkDestroyImage{}; | 290 | PFN_vkDestroyImage vkDestroyImage{}; |
| 290 | PFN_vkDestroyImageView vkDestroyImageView{}; | 291 | PFN_vkDestroyImageView vkDestroyImageView{}; |
| 291 | PFN_vkDestroyPipeline vkDestroyPipeline{}; | 292 | PFN_vkDestroyPipeline vkDestroyPipeline{}; |
| 293 | PFN_vkDestroyPipelineCache vkDestroyPipelineCache{}; | ||
| 292 | PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout{}; | 294 | PFN_vkDestroyPipelineLayout vkDestroyPipelineLayout{}; |
| 293 | PFN_vkDestroyQueryPool vkDestroyQueryPool{}; | 295 | PFN_vkDestroyQueryPool vkDestroyQueryPool{}; |
| 294 | PFN_vkDestroyRenderPass vkDestroyRenderPass{}; | 296 | PFN_vkDestroyRenderPass vkDestroyRenderPass{}; |
| @@ -306,6 +308,7 @@ struct DeviceDispatch : InstanceDispatch { | |||
| 306 | PFN_vkGetEventStatus vkGetEventStatus{}; | 308 | PFN_vkGetEventStatus vkGetEventStatus{}; |
| 307 | PFN_vkGetFenceStatus vkGetFenceStatus{}; | 309 | PFN_vkGetFenceStatus vkGetFenceStatus{}; |
| 308 | PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements{}; | 310 | PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements{}; |
| 311 | PFN_vkGetPipelineCacheData vkGetPipelineCacheData{}; | ||
| 309 | PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR{}; | 312 | PFN_vkGetMemoryFdKHR vkGetMemoryFdKHR{}; |
| 310 | #ifdef _WIN32 | 313 | #ifdef _WIN32 |
| 311 | PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR{}; | 314 | PFN_vkGetMemoryWin32HandleKHR vkGetMemoryWin32HandleKHR{}; |
| @@ -351,6 +354,7 @@ void Destroy(VkDevice, VkFramebuffer, const DeviceDispatch&) noexcept; | |||
| 351 | void Destroy(VkDevice, VkImage, const DeviceDispatch&) noexcept; | 354 | void Destroy(VkDevice, VkImage, const DeviceDispatch&) noexcept; |
| 352 | void Destroy(VkDevice, VkImageView, const DeviceDispatch&) noexcept; | 355 | void Destroy(VkDevice, VkImageView, const DeviceDispatch&) noexcept; |
| 353 | void Destroy(VkDevice, VkPipeline, const DeviceDispatch&) noexcept; | 356 | void Destroy(VkDevice, VkPipeline, const DeviceDispatch&) noexcept; |
| 357 | void Destroy(VkDevice, VkPipelineCache, const DeviceDispatch&) noexcept; | ||
| 354 | void Destroy(VkDevice, VkPipelineLayout, const DeviceDispatch&) noexcept; | 358 | void Destroy(VkDevice, VkPipelineLayout, const DeviceDispatch&) noexcept; |
| 355 | void Destroy(VkDevice, VkQueryPool, const DeviceDispatch&) noexcept; | 359 | void Destroy(VkDevice, VkQueryPool, const DeviceDispatch&) noexcept; |
| 356 | void Destroy(VkDevice, VkRenderPass, const DeviceDispatch&) noexcept; | 360 | void Destroy(VkDevice, VkRenderPass, const DeviceDispatch&) noexcept; |
| @@ -773,6 +777,18 @@ public: | |||
| 773 | void SetObjectNameEXT(const char* name) const; | 777 | void SetObjectNameEXT(const char* name) const; |
| 774 | }; | 778 | }; |
| 775 | 779 | ||
| 780 | class PipelineCache : public Handle<VkPipelineCache, VkDevice, DeviceDispatch> { | ||
| 781 | using Handle<VkPipelineCache, VkDevice, DeviceDispatch>::Handle; | ||
| 782 | |||
| 783 | public: | ||
| 784 | /// Set object name. | ||
| 785 | void SetObjectNameEXT(const char* name) const; | ||
| 786 | |||
| 787 | VkResult Read(size_t* size, void* data) const noexcept { | ||
| 788 | return dld->vkGetPipelineCacheData(owner, handle, size, data); | ||
| 789 | } | ||
| 790 | }; | ||
| 791 | |||
| 776 | class Semaphore : public Handle<VkSemaphore, VkDevice, DeviceDispatch> { | 792 | class Semaphore : public Handle<VkSemaphore, VkDevice, DeviceDispatch> { |
| 777 | using Handle<VkSemaphore, VkDevice, DeviceDispatch>::Handle; | 793 | using Handle<VkSemaphore, VkDevice, DeviceDispatch>::Handle; |
| 778 | 794 | ||
| @@ -844,11 +860,15 @@ public: | |||
| 844 | 860 | ||
| 845 | DescriptorSetLayout CreateDescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo& ci) const; | 861 | DescriptorSetLayout CreateDescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo& ci) const; |
| 846 | 862 | ||
| 863 | PipelineCache CreatePipelineCache(const VkPipelineCacheCreateInfo& ci) const; | ||
| 864 | |||
| 847 | PipelineLayout CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const; | 865 | PipelineLayout CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const; |
| 848 | 866 | ||
| 849 | Pipeline CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci) const; | 867 | Pipeline CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci, |
| 868 | VkPipelineCache cache = nullptr) const; | ||
| 850 | 869 | ||
| 851 | Pipeline CreateComputePipeline(const VkComputePipelineCreateInfo& ci) const; | 870 | Pipeline CreateComputePipeline(const VkComputePipelineCreateInfo& ci, |
| 871 | VkPipelineCache cache = nullptr) const; | ||
| 852 | 872 | ||
| 853 | Sampler CreateSampler(const VkSamplerCreateInfo& ci) const; | 873 | Sampler CreateSampler(const VkSamplerCreateInfo& ci) const; |
| 854 | 874 | ||