add PipelineCache save/load

This commit is contained in:
hyzboy 2020-11-05 14:02:35 +08:00
parent f6cf9dc1b8
commit ceb4395b77
6 changed files with 128 additions and 32 deletions

2
CMCore

@ -1 +1 @@
Subproject commit 5d75e138b58826b635db09f0dd325b4e6f2d2052
Subproject commit ad4b2cd48c9744c3a5e2fed29a15a79d7a5d35b3

View File

@ -3,6 +3,7 @@
#include<hgl/type/List.h>
#include<hgl/math/Math.h>
#include<hgl/type/String.h>
#include<iostream>
#include<hgl/graph/VKNamespace.h>
#include<hgl/graph/VKFormat.h>
@ -160,6 +161,16 @@ inline void debug_out_vk_version(const uint32_t version)
<<VK_VERSION_PATCH(version);
}
template<typename T>
inline hgl::String<T> VkUUID2String(const uint8_t *pipelineCacheUUID)
{
T *hstr=new T[VK_UUID_SIZE*2+1];
DataToLowerHexStr(hstr,pipelineCacheUUID,VK_UUID_SIZE);
return hgl::String<T>::newOf(hstr,VK_UUID_SIZE*2);
}
inline void debug_out(const char *front,const hgl::List<VkLayerProperties> &layer_properties)
{
const int property_count=layer_properties.GetCount();

View File

@ -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

View File

@ -5,6 +5,8 @@
#include<iostream>
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;
}
}
}
{

View File

@ -11,6 +11,7 @@
#include<iomanip>
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<<std::setw(40)<<std::right<<#name<<": "<<(features.name?"true":"false")<<std::endl;
@ -351,12 +335,12 @@ namespace
std::cout<<" apiVersion: ";DebugOutVersion(pdp.apiVersion);
std::cout<<" driverVersion: ";DebugOutVersion(pdp.driverVersion);
std::cout<<" vendorID: "<<pdp.vendorID<<std::endl;
std::cout<<" deviceID: "<<pdp.deviceID<<std::endl;
std::cout<<" vendorID: 0x"<<HexToString<char>(pdp.vendorID).c_str()<<std::endl;
std::cout<<" deviceID: 0x"<<HexToString<char>(pdp.deviceID).c_str()<<std::endl;
std::cout<<" deviceType: "<<DeviceTypeString[pdp.deviceType]<<std::endl;
std::cout<<" deviceName: "<<pdp.deviceName<<std::endl;
AnsiString uuid=HexToString<char>(pdp.pipelineCacheUUID);
AnsiString uuid=VkUUID2String<char>(pdp.pipelineCacheUUID);
std::cout<<"pipelineCahceUUID: "<<uuid.c_str()<<std::endl;
@ -409,7 +393,7 @@ GPUDevice *CreateRenderDevice(VkInstance inst,const GPUPhysicalDevice *physical_
if(!device_attr->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);

View File

@ -0,0 +1,101 @@
#include<hgl/graph/VK.h>
#include<hgl/filesystem/FileSystem.h>
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<os_char>(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<char> 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<os_char>(pdp.pipelineCacheUUID);
const OSString fullname=MergeFilename(pathname,filename);
if(!IsDirectory(pathname))
if(!MakePath(pathname))
return;
SaveMemoryToFile(fullname,data,size);
}
VK_NAMESPACE_END