perf(pipeline): shared, disk-persisted VkPipelineCache (#69) #97

Merged
catbot merged 2 commits from claude/issue-69 into master 2026-06-16 20:24:03 +02:00
Member

Summary

vkCreateComputePipelines and vkCreateRayTracingPipelinesKHR were both passed VK_NULL_HANDLE for their VkPipelineCache, so the driver couldn't reuse compiled shader binaries — neither across the several pipelines built at startup (4 UI compute shaders + user/RT pipelines) nor across runs. One-time cold-start cost, not a per-frame one (issue #69).

Changes

  • One process-wide Device::pipelineCache, fed to both pipeline-creation sites. A null handle stays valid ("no cache"), so the create sites need no null check.
  • Device::LoadPipelineCache (called once from Initialize) seeds the cache from pipeline_cache.bin when the file's VkPipelineCacheHeaderVersionOne header matches this device's vendorID / deviceID / pipelineCacheUUID. A stale or foreign blob (different GPU, driver update, corruption) is discarded so the driver never ignores or rejects it — worst case is a one-time cold compile.
  • Device::SavePipelineCache is registered with std::atexit, serialising the driver's current cache blob at process shutdown without needing an explicit teardown hook (there is none today). The device handle is a never-destroyed static, so it's still valid in the handler; the save is best-effort and never throws.
  • Device::deviceProperties is now captured from the VkPhysicalDeviceProperties2 query for the identity check.

Testing

  • crafter-build test14 passed (--jobs=1; the default parallel run hit an unrelated crafter-build infra race where 13 concurrent test builds git pull the shared Vulkan-Headers cache dir simultaneously and corrupt its FETCH_HEAD).
  • New PipelineCacheValidation test drives Device::PipelineCacheDataCompatible directly (no GPU), mirroring MemoryTypeFallback / UploadStrategy: a matching header is accepted; foreign vendor/device, a bumped UUID, unknown version, undersized headerSize, and short/empty blobs are all rejected.
  • The full load→create→atexit-save path is exercised on real hardware by the existing FrameLoopSync device test, which now drops a pipeline_cache.bin at exit (gitignored).

Resolves #69

🤖 Generated with Claude Code

## Summary `vkCreateComputePipelines` and `vkCreateRayTracingPipelinesKHR` were both passed `VK_NULL_HANDLE` for their `VkPipelineCache`, so the driver couldn't reuse compiled shader binaries — neither across the several pipelines built at startup (4 UI compute shaders + user/RT pipelines) nor across runs. One-time cold-start cost, not a per-frame one (issue #69). ## Changes - **One process-wide `Device::pipelineCache`**, fed to both pipeline-creation sites. A null handle stays valid ("no cache"), so the create sites need no null check. - **`Device::LoadPipelineCache`** (called once from `Initialize`) seeds the cache from `pipeline_cache.bin` when the file's `VkPipelineCacheHeaderVersionOne` header matches this device's `vendorID` / `deviceID` / `pipelineCacheUUID`. A stale or foreign blob (different GPU, driver update, corruption) is discarded so the driver never ignores or rejects it — worst case is a one-time cold compile. - **`Device::SavePipelineCache`** is registered with `std::atexit`, serialising the driver's current cache blob at process shutdown without needing an explicit teardown hook (there is none today). The device handle is a never-destroyed static, so it's still valid in the handler; the save is best-effort and never throws. - **`Device::deviceProperties`** is now captured from the `VkPhysicalDeviceProperties2` query for the identity check. ## Testing - `crafter-build test` — **14 passed** (`--jobs=1`; the default parallel run hit an unrelated crafter-build infra race where 13 concurrent test builds `git pull` the shared Vulkan-Headers cache dir simultaneously and corrupt its `FETCH_HEAD`). - New **`PipelineCacheValidation`** test drives `Device::PipelineCacheDataCompatible` directly (no GPU), mirroring `MemoryTypeFallback` / `UploadStrategy`: a matching header is accepted; foreign vendor/device, a bumped UUID, unknown version, undersized `headerSize`, and short/empty blobs are all rejected. - The full load→create→atexit-save path is exercised on real hardware by the existing `FrameLoopSync` device test, which now drops a `pipeline_cache.bin` at exit (gitignored). Resolves #69 🤖 Generated with [Claude Code](https://claude.com/claude-code)
vkCreateComputePipelines and vkCreateRayTracingPipelinesKHR were passed
VK_NULL_HANDLE, so the driver couldn't reuse compiled shader binaries
across the pipelines built at startup (4 UI shaders + user/RT pipelines)
or across runs.

Add one process-wide Device::pipelineCache. LoadPipelineCache (called
from Initialize) seeds it from pipeline_cache.bin when the file's
VkPipelineCacheHeaderVersionOne header matches this device's
vendorID / deviceID / pipelineCacheUUID; a stale or foreign blob is
discarded so the driver never rejects it. SavePipelineCache is registered
with std::atexit, serialising the cache at process shutdown without any
explicit teardown hook. Both create sites now pass the cache; a null
handle stays valid, so no create-site null check is needed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PipelineCacheValidation drives Device::PipelineCacheDataCompatible
directly (no GPU): synthetic device identities + 32-byte cache headers
assert that a matching header is accepted while foreign vendor/device,
a bumped UUID (driver update), unknown version, undersized headerSize,
and short/empty blobs are all rejected. Mirrors the GPU-free style of
MemoryTypeFallback / UploadStrategy. Also gitignore the serialized
pipeline_cache.bin a real-device test run drops in the working dir.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
catbot merged commit bd8076769a into master 2026-06-16 20:24:03 +02:00
catbot deleted branch claude/issue-69 2026-06-16 20:24:03 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Catcrafts/Crafter.Graphics!97
No description provided.