Gfx: Pipeline caches on DX12

Created on 27 Jun 2019  路  4Comments  路  Source: gfx-rs/gfx

We have the API for pipeline caches, but the backends don't yet fully implement it. See create_graphics_pipeline signature and other use of PipelineCache.

D3D12 could store the pipeline blobs in the cache: https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_cached_pipeline_state

We'd need to be able to save/load that cache from disk, as well as properly select one (of those saved in the PipelineCache implementation) when a new pipeline is created:

This structure is intended to be filled with the data retrieved from ID3D12PipelineState::GetCachedBlob. This cached PSO contains data specific to the hardware, driver, and machine that it was retrieved from. Compilation using this data should be faster than compilation without. The rest of the data in the PSO needs to still be valid, and needs to match the cached PSO, otherwise E_INVALIDARG might be returned.

The logic of the backend, when creating a pipeline with the cache provided, would need to be the following:

  1. Lookup the given pipeline state in a HashMap<PipelineState, D3D12_CACHED_PIPELINE_STATE> owned by the pipeline cache.
  2. If there is a cached state, try to create a pipeline with it.
  3. If succeeded, that's good! No need to do anything else.
  4. If failed with D3D12_ERROR_DRIVER_VERSION_MISMATCH or D3D12_ERROR_ADAPTER_NOT_FOUND, issue a warn! message accordingly and proceed again but without using the D3D12_CACHED_PIPELINE_STATE.
  5. Obtain the new blob and store it in the pipeline cache. It may be overwriting the old value if it failed to work (due to driver/gpu/os incompatibility), which is fine.

Note: pipeline caches are internally synchronized, so any mutation of them should be done behind a sync structure, such as RwLock or Mutex. Alternatively, if you feel courageous, may try Kudzu like explained in #2860

Marking as high priority because it is requested by the Szeged team in order to speed up WebRender startup when running on DX12. cc @zakorgy

DirectX-12 request contributor-friendly average hal Windows ready for work feature high

Most helpful comment

Howdy, I would like to work on this if it is not being worked on currently.

All 4 comments

Howdy, I would like to work on this if it is not being worked on currently.

It's not being worked on, but still very much needed. Your help is much welcome!

Regarding the _data_ parameter in the create_pipeline_cache.

As the cache needs to be loaded from disk, I was thinking of passing the file path via the _data_ parameter. This provides two scenarios that I could think of:

  1. When creating a cache, the PipelineStatemust be passed as _data_ in order to create the blob and provide the key in the HashMap<PipelineState, D3D12_CACHED_PIPELINE_STATE>. Meaning the _data_ parameter would provide two different types of information: File path or Pipeline State. (Not ideal)

  2. Create an empty PipelineCache when _data_ is None. Pass this empty PipelineCache to create_graphics_pipeline and fill the PipelineCache once it has created the PipelineState in the function.

I am in favor of option 2, but that would mean that a PipelineCache can not be created from an already existing pipeline. It can only be created during the create_graphics_pipline
function, as the _data_ parameter would only store the file path to load from disk.

Is option 2 one way of doing it and having the _data_ parameter be used as a file path or is there another option that I am completely unaware of?

A thought just occurred to me: will having _data_ be used for the file path break code compatibility across backends?

(I am fairly new to Pipeline Caches, so there could be some things I may be missing. If there are any documents or articles that you recommend I read, please feel free to share)

@Cartogy we don't want to change the API for this. The current API follows Vulkan (you can also check the VkPipelineCache documentation there), and we need to keep it this way. Maybe this will help?

Was this page helpful?
0 / 5 - 0 ratings