tl;dr don't do it
Just a quick note to save someone else the time of implementing a PSO cache…
I tested three strategies:
- Just call
CreateGraphicsPipelineState
(1st bar in graph) - On first run, call
CreateGraphicsPipelineState
+GetCachedBlob
(4th bar in graph)- on future runs call
CreateGraphicsPipelineState
with aD3D12_CACHED_PIPELINE_STATE
(5th bar in graph)
- on future runs call
- On first run, call
CreateGraphicsPipelineState
+StorePipeline
(2nd bar in graph)- on future runs call
LoadGraphicsPipeline
(3rd bar in graph)
- on future runs call
note the log scale on the Y axis… the bars are from about 20 seconds (1st/2nd/5th) to 1 minute (3rd) to 13 minutes (4th)…
Creating shaders from your own cache (using D3D12_CACHED_PIPELINE_STATE
) is the fastest, but only a few percent faster than no caching.
Populating your own cache in the first place (using GetCachedBlob
) and writing those to disk is super slow.
Populating a ID3D12PipelineLibrary
is pretty fast. Only a few percent slower than no caching.
Loading shaders from a ID3D12PipelineLibrary
is significantly (~3x) slower than no caching.
tl;dr don't bother with a PSO cache!?!?
It may also depend on GPU vendor. For me using the cache was worth it in any case, but compile times on NV were >10 times slower than for AMD, so for NV the cache was really needed.
Though, that was almost 10 years ago and i'm using Vulkan.