From ceb4395b773925f35318208a3a1352cffbf564d7 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Thu, 5 Nov 2020 14:02:35 +0800 Subject: [PATCH] add PipelineCache save/load --- CMCore | 2 +- inc/hgl/graph/VK.h | 11 +++ src/RenderDevice/CMakeLists.txt | 1 + src/RenderDevice/VKDeviceAttribute.cpp | 17 ++--- src/RenderDevice/VKDeviceCreater.cpp | 28 ++----- src/RenderDevice/VKPipelineCache.cpp | 101 +++++++++++++++++++++++++ 6 files changed, 128 insertions(+), 32 deletions(-) create mode 100644 src/RenderDevice/VKPipelineCache.cpp diff --git a/CMCore b/CMCore index 5d75e138..ad4b2cd4 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit 5d75e138b58826b635db09f0dd325b4e6f2d2052 +Subproject commit ad4b2cd48c9744c3a5e2fed29a15a79d7a5d35b3 diff --git a/inc/hgl/graph/VK.h b/inc/hgl/graph/VK.h index 4794a42d..46eea86f 100644 --- a/inc/hgl/graph/VK.h +++ b/inc/hgl/graph/VK.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -160,6 +161,16 @@ inline void debug_out_vk_version(const uint32_t version) < +inline hgl::String VkUUID2String(const uint8_t *pipelineCacheUUID) +{ + T *hstr=new T[VK_UUID_SIZE*2+1]; + + DataToLowerHexStr(hstr,pipelineCacheUUID,VK_UUID_SIZE); + + return hgl::String::newOf(hstr,VK_UUID_SIZE*2); +} + inline void debug_out(const char *front,const hgl::List &layer_properties) { const int property_count=layer_properties.GetCount(); diff --git a/src/RenderDevice/CMakeLists.txt b/src/RenderDevice/CMakeLists.txt index d95e665b..359b8a18 100644 --- a/src/RenderDevice/CMakeLists.txt +++ b/src/RenderDevice/CMakeLists.txt @@ -82,6 +82,7 @@ SET(VK_RENDER_PASS_SOURCE ${VK_INCLUDE_PATH}/VKFramebuffer.h VKFence.cpp VKFramebuffer.cpp VKPipeline.cpp + VKPipelineCache.cpp VKRenderPass.cpp VKRenderTarget.cpp VKRenderTargetPipeline.cpp diff --git a/src/RenderDevice/VKDeviceAttribute.cpp b/src/RenderDevice/VKDeviceAttribute.cpp index 9ecc2e61..bda388ab 100644 --- a/src/RenderDevice/VKDeviceAttribute.cpp +++ b/src/RenderDevice/VKDeviceAttribute.cpp @@ -5,6 +5,8 @@ #include VK_NAMESPACE_BEGIN +void SavePipelineCacheData(VkDevice device,VkPipelineCache cache,const VkPhysicalDeviceProperties &pdp); + GPUDeviceAttribute::GPUDeviceAttribute(VkInstance inst,const GPUPhysicalDevice *pd,VkSurfaceKHR s) { instance=inst; @@ -17,7 +19,10 @@ GPUDeviceAttribute::GPUDeviceAttribute(VkInstance inst,const GPUPhysicalDevice * GPUDeviceAttribute::~GPUDeviceAttribute() { if(pipeline_cache) + { + SavePipelineCacheData(device,pipeline_cache,physical_device->GetProperties()); vkDestroyPipelineCache(device,pipeline_cache,nullptr); + } if(desc_pool) vkDestroyDescriptorPool(device,desc_pool,nullptr); @@ -45,13 +50,9 @@ void GPUDeviceAttribute::Refresh() { if (surface_caps.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) - { preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; - } else - { preTransform = surface_caps.currentTransform; - } } { @@ -60,14 +61,12 @@ void GPUDeviceAttribute::Refresh() VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR, VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR }; - for (uint32_t i = 0; i < sizeof(compositeAlphaFlags); i++) - { - if (surface_caps.supportedCompositeAlpha & compositeAlphaFlags[i]) + for(auto flags:compositeAlphaFlags) + if (surface_caps.supportedCompositeAlpha & flags) { - compositeAlpha = compositeAlphaFlags[i]; + compositeAlpha = flags; break; } - } } { diff --git a/src/RenderDevice/VKDeviceCreater.cpp b/src/RenderDevice/VKDeviceCreater.cpp index dd115b79..89cf0ab9 100644 --- a/src/RenderDevice/VKDeviceCreater.cpp +++ b/src/RenderDevice/VKDeviceCreater.cpp @@ -11,6 +11,7 @@ #include VK_NAMESPACE_BEGIN +VkPipelineCache CreatePipelineCache(VkDevice device,const VkPhysicalDeviceProperties &); Swapchain *CreateSwapchain(const GPUDeviceAttribute *attr,const VkExtent2D &acquire_extent); namespace @@ -70,7 +71,7 @@ namespace cmd_pool_info.sType=VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; cmd_pool_info.pNext=nullptr; cmd_pool_info.queueFamilyIndex=graphics_family; - cmd_pool_info.flags=VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; //允许COMMAND被重复begin,如果没有此标记也可以正常用,但是会频繁报错 + cmd_pool_info.flags=VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; VkCommandPool cmd_pool; @@ -123,23 +124,6 @@ namespace return desc_pool; } - VkPipelineCache CreatePipelineCache(VkDevice device) - { - VkPipelineCacheCreateInfo pipelineCache; - pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - pipelineCache.pNext = nullptr; - pipelineCache.flags = 0; - pipelineCache.initialDataSize = 0; - pipelineCache.pInitialData = nullptr; - - VkPipelineCache cache; - - if(vkCreatePipelineCache(device, &pipelineCache, nullptr, &cache)!=VK_SUCCESS) - return(VK_NULL_HANDLE); - - return cache; - } - void DebugOut(const VkPhysicalDeviceFeatures &features) { #define OUTPUT_PHYSICAL_DEVICE_FEATURE(name) std::cout<(pdp.vendorID).c_str()<(pdp.deviceID).c_str()<(pdp.pipelineCacheUUID); + AnsiString uuid=VkUUID2String(pdp.pipelineCacheUUID); std::cout<<"pipelineCahceUUID: "<desc_pool) return(nullptr); - device_attr->pipeline_cache=CreatePipelineCache(device_attr->device); + device_attr->pipeline_cache=CreatePipelineCache(device_attr->device,physical_device->GetProperties()); if(!device_attr->pipeline_cache) return(nullptr); diff --git a/src/RenderDevice/VKPipelineCache.cpp b/src/RenderDevice/VKPipelineCache.cpp new file mode 100644 index 00000000..2ced7ff4 --- /dev/null +++ b/src/RenderDevice/VKPipelineCache.cpp @@ -0,0 +1,101 @@ +#include +#include + +VK_NAMESPACE_BEGIN +namespace +{ + using namespace hgl::filesystem; + + const OSString GetUUIDCachePath(const VkPhysicalDeviceProperties &pdp) + { + OSString app_data; + OSString pathname; + + if(!GetLocalAppdataPath(app_data))return OS_TEXT(""); + + pathname=app_data+HGL_DIRECTORY_SEPARATOR + +OSString(OS_TEXT("VkPipelineCache.com"))+HGL_DIRECTORY_SEPARATOR + +OSString::valueOf(VK_PIPELINE_CACHE_HEADER_VERSION_ONE)+HGL_DIRECTORY_SEPARATOR + +OSString::valueOf(pdp.vendorID)+HGL_DIRECTORY_SEPARATOR + +OSString::valueOf(pdp.deviceID)+HGL_DIRECTORY_SEPARATOR; + + return pathname; + } + + void LoadPipelineCacheFile(VkPipelineCacheCreateInfo *pcci,const VkPhysicalDeviceProperties &pdp) + { + if(!pcci)return; + + const OSString pathname=GetUUIDCachePath(pdp); + const OSString filename=VkUUID2String(pdp.pipelineCacheUUID); + const OSString fullname=MergeFilename(pathname,filename); + + if(!FileExist(fullname)) + { + pcci->initialDataSize=0; + pcci->pInitialData=nullptr; + + if(!IsDirectory(pathname)) + { + MakePath(pathname); + return; + } + } + else + { + int64 size; + pcci->pInitialData=LoadFileToMemory(fullname,size); + pcci->initialDataSize=size; + } + } +}//namespace + +VkPipelineCache CreatePipelineCache(VkDevice device,const VkPhysicalDeviceProperties &pdp) +{ + VkPipelineCacheCreateInfo pipelineCache; + + pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; + pipelineCache.pNext = nullptr; + pipelineCache.flags = 0; + pipelineCache.initialDataSize = 0; + pipelineCache.pInitialData = nullptr; + + LoadPipelineCacheFile(&pipelineCache,pdp); + + VkPipelineCache cache; + + VkResult result=vkCreatePipelineCache(device, &pipelineCache, nullptr, &cache); + + if(pipelineCache.pInitialData) + delete[] (char *)pipelineCache.pInitialData; + + if(result==VK_SUCCESS) + return cache; + else + return(VK_NULL_HANDLE); +} + +void SavePipelineCacheData(VkDevice device,VkPipelineCache cache,const VkPhysicalDeviceProperties &pdp) +{ + size_t size = 0; + AutoDeleteArray data; + + if(vkGetPipelineCacheData(device, cache, &size, nullptr)!=VK_SUCCESS) + return; + + data.alloc(size); + + if(!vkGetPipelineCacheData(device, cache, &size, data)==VK_SUCCESS) + return; + + const OSString pathname=GetUUIDCachePath(pdp); + const OSString filename=VkUUID2String(pdp.pipelineCacheUUID); + const OSString fullname=MergeFilename(pathname,filename); + + if(!IsDirectory(pathname)) + if(!MakePath(pathname)) + return; + + SaveMemoryToFile(fullname,data,size); +} +VK_NAMESPACE_END \ No newline at end of file