9.6. 管线缓存
管线缓存对象允许管线构造的结果可以在不同的管线之间,应用程序多次运行之间重用。 在不同管线之间重用是在创建多个关联管线时通过传递相同的管线缓存对象来实现的。 在应用程序多次运行之间重用是通过获取管线缓存内容、保存内容,在下一次运行时初始化管线之前使用它们。 管线缓存对象的内容是由Vulkan实现来管理的。 应用程序可以管理管线缓存对象消耗的主机端内存,控制从管线缓存对象中获取的数据的量的大小。
管线缓存对象通过VkPipelineCache handles来表示:
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache)
可调用如下命令来创建管线缓存对象:
VkResult vkCreatePipelineCache(
VkDevice device,
const VkPipelineCacheCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkPipelineCache* pPipelineCache);
-
device是创建管线缓存的连接设备。 -
pCreateInfo是一个指针,指向了一个aVkPipelineCacheCreateInfo,包含着管线缓存的初始参数。 -
pAllocator控制了CPU端内存分配,如 Memory Allocation 一章所描述。 -
pPipelineCache是一个指针,指向了一个VkPipelineCachehandle,存放被返回的管线缓存对象。
|
注意
应用程序可以使用 |
一旦创建完成,一个管线缓存可以被传递到vkCreateGraphicsPipelines 和 vkCreateComputePipelines命令。 如果传递到这些命令的一个管线缓存对象不是VK_NULL_HANDLE,Vulkan实现将查询是否可重用它并更新。 在这些命令内使用管线缓存对象是内部同步的,同一个管线缓存对象可以在多线程中同时使用。
|
注意
Vulkan实现应该尽量限制critical sections 代码段对缓存的访问,亦即,最好比 |
VkPipelineCacheCreateInfo 数据结构定义如下:
typedef struct VkPipelineCacheCreateInfo {
VkStructureType sType;
const void* pNext;
VkPipelineCacheCreateFlags flags;
size_t initialDataSize;
const void* pInitialData;
} VkPipelineCacheCreateInfo;
-
sType是数据结构的类型。 -
pNext是NULL或者一个指向拓展特定的数据结构的指针。 -
flags被保留。 -
initialDataSize是pInitialData的字节大小。如果initialDataSize为0,管线缓存将被初始为空。 -
pInitialData是一个指针,指向了之前获取到的管线缓存数据。如果管线缓存数据和设备是不兼容的(如下有解释), 管线缓存将被初始化为空。如果initialDataSize为0,pInitialData将被忽略。
可以使用如下命令来合并管线缓存对象:
VkResult vkMergePipelineCaches(
VkDevice device,
VkPipelineCache dstCache,
uint32_t srcCacheCount,
const VkPipelineCache* pSrcCaches);
-
device是拥有该管线缓存对象的逻辑设备。 -
dstCache是存放合并产生的管线缓存的handle。 -
srcCacheCount是 数组pSrcCaches的大小。 -
pSrcCaches是一个管线缓存handle的数组,将被合并到dstCache。dstCache之前的内容仍包含在合并之后的缓存中。
|
注意
The details of the merge operation are implementation dependent, but implementations should merge the contents of the specified pipelines and prune duplicate entries. |
可以使用如下命令从管线缓存对象中取出数据:
VkResult vkGetPipelineCacheData(
VkDevice device,
VkPipelineCache pipelineCache,
size_t* pDataSize,
void* pData);
-
device是拥有该管线缓存对象的逻辑设备。 -
pipelineCache是获取数据的目标管线缓存对象。 -
pDataSize是一个指针,指向存放从管线缓存中获取的数据大小的变量,下面有描述。 -
pData要么是NULL,要么指向一个缓冲区。
若pData 是 NULL,那么可以从管线缓存中取出的数据的最大大小通过 pDataSize返回,以字节为单位。 否则,pDataSize 必须指向一个变量,由用户设置为 pData所指向的buffer的大小(字节为单位), 函数返回时,变量将被覆盖为写入到pData的数据量的大小。
若 pDataSize 比可以从管线缓存中取出的数据的最大大小要小,那么最多只有pDataSize字节的数据将被写入pData,vkGetPipelineCacheData将返回VK_INCOMPLETE。
写入pData的任何数据都是有效的,可以用作VkPipelineCacheCreateInfo数据结构的pInitialData 成员,从而传递给vkCreatePipelineCache。
用相同的参数两次调用vkGetPipelineCacheData 必须要获取到完全相同的数据,除非在两次调用期间,其他的命令改变了缓存的内容。
Applications can store the data retrieved from the pipeline cache, and use these data, possibly in a future run of the application, to populate new pipeline cache objects. The results of pipeline compiles, however, may depend on the vendor ID, device ID, driver version, and other details of the device. To enable applications to detect when previously retrieved data is incompatible with the device, the initial bytes written to pData must be a header consisting of the following members:
| Offset | Size | Meaning |
|---|---|---|
| 0 | 4 | length in bytes of the entire pipeline cache header written as a stream of bytes, with the least significant byte first |
| 4 | 4 | a |
| 8 | 4 | a vendor ID equal to |
| 12 | 4 | a device ID equal to |
| 16 | | a pipeline cache ID equal to |
The first four bytes encode the length of the entire pipeline header, in bytes. This value includes all fields in the header including the pipeline cache version field and the size of the length field.
The next four bytes encode the pipeline cache version. This field is interpreted as a VkPipelineCacheHeaderVersionvalue, and must have one of the following values:
typedef enum VkPipelineCacheHeaderVersion {
VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1,
} VkPipelineCacheHeaderVersion;
A consumer of the pipeline cache should use the cache version to interpret the remainder of the cache header.
If pDataSize is less than what is necessary to store this header, nothing will be written to pData and zero will be written to pDataSize.
可调用如下命令来销毁管线缓存:
void vkDestroyPipelineCache(
VkDevice device,
VkPipelineCache pipelineCache,
const VkAllocationCallbacks* pAllocator);
-
device是销毁管线缓存的逻辑设备。 -
pipelineCache是需要被销毁的管线缓存。 -
pAllocator控制了主机端内存如何分配,如Memory Allocation一章所述。
本文介绍Vulkan管线缓存的创建、使用及管理方法,包括管线缓存对象的创建、合并、数据提取与销毁等操作,帮助开发者提高管线创建效率。
423

被折叠的 条评论
为什么被折叠?



