-
Couldn't load subscription status.
- Fork 536
Description
Goal
It would be neat and useful to have an implementation of get_pipeline_cache_data on all modern platforms (Vulkan, DX12, Metal). Along with the corresponding code in create_pipeline_cache, this would allow for being able to cache the pipelines to disk on all backends, giving a good performance boost when a lot of pipelines are used.
Status
Vulkan
The Vulkan API has this get_pipeline_cache_data function built in.
Metal
Edit: disregard this whole section, see #3716 (comment).
The Metal backend has a pipeline cache:
gfx/src/backend/metal/src/native.rs
Lines 207 to 211 in 2a93d52
| pub struct PipelineCache { | |
| #[cfg(feature = "cross")] //TODO: Naga path | |
| pub(crate) modules: | |
| FastStorageMap<spirv_cross::msl::CompilerOptions, FastStorageMap<Vec<u32>, ModuleInfo>>, | |
| } |
However there is no way to serialize or deserialize it at present.
The key blocker for this is that the ModuleInfo struct stores a metal::Library:
gfx/src/backend/metal/src/native.rs
Lines 200 to 205 in 2a93d52
| #[derive(Clone, Debug)] | |
| pub struct ModuleInfo { | |
| pub library: metal::Library, | |
| pub entry_point_map: EntryPointMap, | |
| pub rasterization_enabled: bool, | |
| } |
While there is no way in the Metal API to serialize a MTLLibrary (the underlying type), there is a serialize function for MTLDynamicLibrary which I believe we could convert into. It serializes directly into a file though, which is pretty gross. Presumably we'd then have to read back from this file.
The other option would be to just store the metal source code for the shader that has been converted from spir-v. This would not give as big a performance improvement though.
MoltenVK
MoltenVK implements a pipeline cache with MVKPipelineCache. Similar to what we do with metal, this stores MVKShaderLibraryCaches which in turn store MVKShaderLibrarys. When implementing getPipelineCacheData, it writes the metal source code, similar to what I suggest as an option above.
As an example of this, here's some of the output of a pipeline cache I generated:
&Y'v�˺GC�^\��@ mainzzzzzmain0>#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
float4 uFragColor [[color(0)]];
};
struct main0_in
{
float4 o_color [[user(locn0)]];
};
fragment main0_out main0(main0_in in [[stage_in]])
{
main0_out out = {};
out.uFragColor = in.o_color;
return out;
}
TxC@�@mainzzzzzmain0�#include <metal_stdlib>
#include <simd/simd.h>
<...>
DX12
The DirectX 12 backend doesn't have a pipeline cache. However, there is an issue that lays out how one could be created: #2877, similar to what the Metal backend does.