Vulkan规范:第九章 9.6

来源:互联网 发布:sql表字段设置默认值 编辑:程序博客网 时间:2024/06/05 11:14

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 是一个指针,指向了一个a VkPipelineCacheCreateInfo,包含着管线缓存的初始参数。

  • pAllocator 控制了CPU端内存分配,如 Memory Allocation 一章所描述。

  • pPipelineCache 是一个指针,指向了一个 VkPipelineCache handle,存放被返回的管线缓存对象。

注意

应用程序可以使用pAllocator来跟踪和管理管线缓存对象的主机端内存大小。 应用程序可以通过vkGetPipelineCacheData来限制从管线缓存对象中获取数据总量的大小。 Vulkan实现不应该在内部限制添加到管线缓存对象的入口点的个数或者是主机端消耗的内存总量。

一旦创建完成,一个管线缓存可以被传递到vkCreateGraphicsPipelines 和 vkCreateComputePipelines命令。 如果传递到这些命令的一个管线缓存对象不是VK_NULL_HANDLE,Vulkan实现将查询是否可重用它并更新。 在这些命令内使用管线缓存对象是内部同步的,同一个管线缓存对象可以在多线程中同时使用。

注意

Vulkan实现应该尽量限制critical sections 代码段对缓存的访问,亦即,最好比 vkCreateGraphicsPipelinesvkCreateComputePipelines命令的执行周期要短很多。

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pCreateInfo must be a pointer to a valid VkPipelineCacheCreateInfo structure

  • If pAllocator is not NULLpAllocator must be a pointer to a valid VkAllocationCallbacks structure

  • pPipelineCache must be a pointer to a VkPipelineCache handle

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

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 将被忽略。

正确使用
  • 若 initialDataSize 不为 0,它必须等于 pInitialData的大小,pInitialData 最初通过调用vkGetPipelineCacheData 返回的。

  • 若 initialDataSize不为 0pInitialData 必须已经通过上一次调用vkGetPipelineCacheData 获取到。

Valid Usage (Implicit)
  • sType must be VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO

  • pNext must be NULL

  • flags must be 0

  • If initialDataSize is not 0pInitialData must be a pointer to an array of initialDataSize bytes

可以使用如下命令来合并管线缓存对象:

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.

正确使用
  • dstCache must not appear in the list of source caches

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • dstCache must be a valid VkPipelineCache handle

  • pSrcCaches must be a pointer to an array of srcCacheCount valid VkPipelineCache handles

  • srcCacheCount must be greater than 0

  • dstCache must have been created, allocated, or retrieved from device

  • Each element of pSrcCaches must have been created, allocated, or retrieved from device

Host Synchronization
  • Host access to dstCache must be externally synchronized

Return Codes
Success
  • VK_SUCCESS

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

可以使用如下命令从管线缓存对象中取出数据:

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字节的数据将被写入pDatavkGetPipelineCacheData将返回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:

Table 7. Layout for pipeline cache header version VK_PIPELINE_CACHE_HEADER_VERSION_ONEOffsetSizeMeaning

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

VkPipelineCacheHeaderVersion value written as a stream of bytes, with the least significant byte first

8

4

a vendor ID equal to VkPhysicalDeviceProperties::vendorID written as a stream of bytes, with the least significant byte first

12

4

a device ID equal to VkPhysicalDeviceProperties::deviceID written as a stream of bytes, with the least significant byte first

16

VK_UUID_SIZE

a pipeline cache ID equal toVkPhysicalDeviceProperties::pipelineCacheUUID

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.

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • pipelineCache must be a valid VkPipelineCache handle

  • pDataSize must be a pointer to a size_t value

  • If the value referenced by pDataSize is not 0, and pData is not NULLpData must be a pointer to an array of pDataSize bytes

  • pipelineCache must have been created, allocated, or retrieved from device

Return Codes
Success
  • VK_SUCCESS

  • VK_INCOMPLETE

Failure
  • VK_ERROR_OUT_OF_HOST_MEMORY

  • VK_ERROR_OUT_OF_DEVICE_MEMORY

可调用如下命令来销毁管线缓存:

void vkDestroyPipelineCache(    VkDevice                                    device,    VkPipelineCache                             pipelineCache,    const VkAllocationCallbacks*                pAllocator);
  • device 是销毁管线缓存的逻辑设备。

  • pipelineCache 是需要被销毁的管线缓存。

  • pAllocator 控制了主机端内存如何分配,如Memory Allocation一章所述。

正确使用
  • If VkAllocationCallbacks were provided when pipelineCache was created, a compatible set of callbacks must be provided here

  • If no VkAllocationCallbacks were provided when pipelineCache was created, pAllocator must be NULL

Valid Usage (Implicit)
  • device must be a valid VkDevice handle

  • If pipelineCache is not VK_NULL_HANDLEpipelineCache must be a valid VkPipelineCache handle

  • If pAllocator is not NULLpAllocator must be a pointer to a valid VkAllocationCallbacks structure

  • If pipelineCache is a valid handle, it must have been created, allocated, or retrieved from device

Host Synchronization
  • Host access to pipelineCache must be externally synchronized

原创粉丝点击