## 9.6. Pipeline Cache

Pipeline cache objects allow the result of pipeline construction to be reused between pipelines and between runs of an application. Reuse between pipelines is achieved by passing the same pipeline cache object when creating multiple related pipelines. Reuse across runs of an application is achieved by retrieving pipeline cache contents in one run of an application, saving the contents, and using them to preinitialize a pipeline cache on a subsequent run. The contents of the pipeline cache objects are managed by the implementation. Applications can manage the host memory consumed by a pipeline cache object and control the amount of data retrieved from a pipeline cache object.

Pipeline cache objects are represented by `VkPipelineCache` handles:

    VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache)

To create pipeline cache objects, call:

    VkResult vkCreatePipelineCache(
        VkDevice                                    device,
        const VkPipelineCacheCreateInfo*            pCreateInfo,
        const VkAllocationCallbacks*                pAllocator,
        VkPipelineCache*                            pPipelineCache);

- `device` is the logical device that creates the pipeline cache object.
- `pCreateInfo` is a pointer to a `VkPipelineCacheCreateInfo` structure that contains the initial parameters for the pipeline cache object.
- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.
- `pPipelineCache` is a pointer to a `VkPipelineCache` handle in which the resulting pipeline cache object is returned.

| Note
Applications can track and manage the total host memory size of a pipeline cache object using the `pAllocator`. Applications can limit the amount of data retrieved from a pipeline cache object in `vkGetPipelineCacheData`. Implementations should not internally limit the total number of entries added to a pipeline cache object or the total host memory consumed.

Once created, a pipeline cache can be passed to the `vkCreateGraphicsPipelines` and `vkCreateComputePipelines` commands. If the pipeline cache passed into these commands is not `VK_NULL_HANDLE`, the implementation will query it for possible reuse opportunities and update it with new content. The use of the pipeline cache object in these commands is internally synchronized, and the same pipeline cache object can be used in multiple threads simultaneously.

| Note
Implementations should make every effort to limit any critical sections to the actual accesses to the cache, which is expected to be significantly shorter than the duration of the `vkCreateGraphicsPipelines` and `vkCreateComputePipelines` commands.

The `VkPipelineCacheCreateInfo` structure is defined as:

    typedef struct VkPipelineCacheCreateInfo {
        VkStructureType               sType;
        const void*                   pNext;
        VkPipelineCacheCreateFlags    flags;
        size_t                        initialDataSize;
        const void*                   pInitialData;
    } VkPipelineCacheCreateInfo;

- `sType` is the type of this structure.
- `pNext` is `NULL` or a pointer to an extension-specific structure.
- `flags` is reserved for future use.
- `initialDataSize` is the number of bytes in `pInitialData`. If `initialDataSize` is zero, the pipeline cache will initially be empty.
- `pInitialData` is a pointer to previously retrieved pipeline cache data. If the pipeline cache data is incompatible (as defined below) with the device, the pipeline cache will be initially empty. If `initialDataSize` is zero, `pInitialData` is ignored.

Pipeline cache objects can be merged using the command:

    VkResult vkMergePipelineCaches(
        VkDevice                                    device,
        VkPipelineCache                             dstCache,
        uint32_t                                    srcCacheCount,
        const VkPipelineCache*                      pSrcCaches);

- `device` is the logical device that owns the pipeline cache objects.
- `dstCache` is the handle of the pipeline cache to merge results into.
- `srcCacheCount` is the length of the `pSrcCaches` array.
- `pSrcCaches` is an array of pipeline cache handles, which will be merged into `dstCache`. The previous contents of `dstCache` are included after the merge.

| Note
The details of the merge operation are implementation dependent, but implementations should merge the contents of the specified pipelines and prune duplicate entries.

Data can be retrieved from a pipeline cache object using the command:

    VkResult vkGetPipelineCacheData(
        VkDevice                                    device,
        VkPipelineCache                             pipelineCache,
        size_t*                                     pDataSize,
        void*                                       pData);

- `device` is the logical device that owns the pipeline cache.
- `pipelineCache` is the pipeline cache to retrieve data from.
- `pDataSize` is a pointer to a value related to the amount of data in the pipeline cache, as described below.
- `pData` is either `NULL` or a pointer to a buffer.

If `pData` is `NULL`, then the maximum size of the data that can be retrieved from the pipeline cache, in bytes, is returned in `pDataSize`. Otherwise, `pDataSize` must point to a variable set by the user to the size of the buffer, in bytes, pointed to by `pData`, and on return the variable is overwritten with the amount of data actually written to `pData`.

If `pDataSize` is less than the maximum size that can be retrieved by the pipeline cache, at most `pDataSize` bytes will be written to `pData`, and `vkGetPipelineCacheData` will return `VK_INCOMPLETE`. Any data written to `pData` is valid and can be provided as the `pInitialData` member of the `VkPipelineCacheCreateInfo` structure passed to `vkCreatePipelineCache`.

Two calls to `vkGetPipelineCacheData` with the same parameters must retrieve the same data unless a command that modifies the contents of the cache is called between them.

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 9.1. Layout for pipeline cache header version `VK_PIPELINE_CACHE_HEADER_VERSION_ONE`

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 `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 to `VkPhysicalDeviceProperties`::`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 `VkPipelineCacheHeaderVersion` value, 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`.

To destroy a pipeline cache, call:

    void vkDestroyPipelineCache(
        VkDevice                                    device,
        VkPipelineCache                             pipelineCache,
        const VkAllocationCallbacks*                pAllocator);

- `device` is the logical device that destroys the pipeline cache object.
- `pipelineCache` is the handle of the pipeline cache to destroy.
- `pAllocator` controls host memory allocation as described in the Memory Allocation chapter.