Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d59eb7a
Add VK_KHR_pipeline_binary sample and related resources
gpx1000 Oct 16, 2025
11f4384
update the clang format and copyright.
gpx1000 Oct 16, 2025
35286a4
update nav.adoc
gpx1000 Oct 16, 2025
1f92e28
- Enhance README with Antora site-gen support and improved references.
gpx1000 Oct 19, 2025
ff0952d
Adjust code formatting in pipeline_binary.cpp for improved readability
gpx1000 Oct 19, 2025
fe2db8b
Merge branch 'main' into VK_KHR_pipeline_binaries
gpx1000 Jan 1, 2026
8d0497b
Update pipeline binary sample with interactive demo and performance m…
gpx1000 Jan 1, 2026
b60c1a7
Refactor logging to use std::format and eliminate snprintf
gpx1000 Jan 7, 2026
e9d53b7
Add missing std::format include to pipeline_binary sample
gpx1000 Jan 7, 2026
9612175
Remove duplicate logging statement in pipeline_binary sample
gpx1000 Jan 7, 2026
19fa02c
Revert updating volk.
gpx1000 Jan 7, 2026
ed10cd5
Add `-extra-arg=-std=c++20` to clang-tidy and fix include order
gpx1000 Jan 7, 2026
d7a4654
Fix clang-tidy by installing GCC 13 toolchain and configuring gcc-too…
gpx1000 Jan 7, 2026
8aae311
Remove clang-tidy container and use system-installed run-clang-tidy
gpx1000 Jan 7, 2026
96c4369
Disable X11 in GLFW build for clang-tidy check
gpx1000 Jan 7, 2026
145428d
Install XCB headers for CMake configure and re-enable X11 in GLFW build
gpx1000 Jan 7, 2026
92767a5
Disable X11 in GLFW build for clang-tidy check
gpx1000 Jan 7, 2026
0cb3404
Replace std::format with fmt::format in pipeline_binary sample
gpx1000 Jan 8, 2026
992ba12
clang format fix.
gpx1000 Jan 8, 2026
e85706f
Replace std::format with fmt::format in pipeline_binary sample
gpx1000 Jan 9, 2026
376f98d
Merge branch 'main' into VK_KHR_pipeline_binaries
gpx1000 Jan 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions antora/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
////
- Copyright (c) 2023-2025, Holochip Inc
- Copyright (c) 2023-2025, Sascha Willems
- Copyright (c) 2023-2026, Holochip Inc
- Copyright (c) 2023-2026, Sascha Willems
- Copyright (c) 2025, Arm Limited and Contributors
-
- SPDX-License-Identifier: Apache-2.0
Expand Down Expand Up @@ -79,6 +79,7 @@
** xref:samples/extensions/open_cl_interop/README.adoc[OpenCL interop]
** xref:samples/extensions/open_cl_interop_arm/README.adoc[OpenCL interop (Arm)]
** xref:samples/extensions/open_gl_interop/README.adoc[OpenGL interop]
** xref:samples/extensions/pipeline_binary/README.adoc[Pipeline Binary]
** xref:samples/extensions/portability/README.adoc[Portability]
** xref:samples/extensions/push_descriptors/README.adoc[Push descriptors]
*** xref:samples/extensions/hpp_push_descriptors/README.adoc[Push descriptors (Vulkan-Hpp)]
Expand Down
10 changes: 8 additions & 2 deletions framework/vulkan_type_mapping.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Copyright (c) 2025, Arm Limited and Contributors
* Copyright (c) 2024-2025, NVIDIA CORPORATION. All rights reserved.
/* Copyright (c) 2026, Arm Limited and Contributors
* Copyright (c) 2024-2026, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
Expand Down Expand Up @@ -333,6 +333,12 @@ struct HPPType<VkSampler>
using Type = vk::Sampler;
};

template <>
struct HPPType<VkPhysicalDevicePipelineBinaryFeaturesKHR>
{
using Type = vk::PhysicalDevicePipelineBinaryFeaturesKHR;
};

template <>
struct HPPType<VkTensorARM>
{
Expand Down
8 changes: 6 additions & 2 deletions samples/extensions/README.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
////
- Copyright (c) 2025, Arm Limited and Contributors
- Copyright (c) 2021-2025, The Khronos Group
- Copyright (c) 2026, Arm Limited and Contributors
- Copyright (c) 2021-2026, The Khronos Group
-
- SPDX-License-Identifier: Apache-2.0
-
Expand Down Expand Up @@ -234,6 +234,10 @@ Demonstrate how to use logical operations dynamically, which can reduce the numb

=== xref:./{extension_samplespath}patch_control_points/README.adoc[Patch control points]

*Extension*: https://docs.vulkan.org/spec/latest/appendices/extensions.html#VK_KHR_pipeline_binary[`VK_KHR_pipeline_binaries`]

Demonstrate how to use pipeline binaries which provides a method to obtain binary data associated with individual pipelines such that applications can manage caching themselves instead of using VkPipelineCache objects.

*Extension*: https://registry.khronos.org/vulkan/specs/latest/man/html/VK_EXT_extended_dynamic_state2.html[`VK_EXT_extended_dynamic_state2`]

Demonstrate how to use patch control points dynamically, which can reduce the number of pipeline objects that are needed to be created.
Expand Down
29 changes: 29 additions & 0 deletions samples/extensions/pipeline_binary/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright (c) 2025-2026, Holochip Inc
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 the "License";
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

get_filename_component(FOLDER_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)
get_filename_component(PARENT_DIR ${CMAKE_CURRENT_LIST_DIR} PATH)
get_filename_component(CATEGORY_NAME ${PARENT_DIR} NAME)

add_sample_with_tags(
ID ${FOLDER_NAME}
CATEGORY ${CATEGORY_NAME}
AUTHOR "Holochip"
NAME "Pipeline binary"
DESCRIPTION "Demonstrates VK_KHR_pipeline_binary: querying keys and capturing pipeline binaries."
SHADER_FILES_GLSL
"pipeline_binary/glsl/binary_demo.comp")
116 changes: 116 additions & 0 deletions samples/extensions/pipeline_binary/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
////
- Copyright (c) 2026, Holochip Inc.
-
- SPDX-License-Identifier: Apache-2.0
-
- Licensed under the Apache License, Version 2.0 the "License";
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
////
ifdef::site-gen-antora[]
TIP: The source for this sample can be found in the https://github.com/KhronosGroup/Vulkan-Samples/tree/main/samples/extensions/pipeline_binary[Khronos Vulkan samples github repository].
endif::[]

= Pipeline binary (VK_KHR_pipeline_binary)
:description: Interactive demonstration of pipeline binary capture, persistence, and performance benefits.

== Overview
VK_KHR_pipeline_binary lets you explicitly capture and reuse driver-produced pipeline binaries. Instead of relying only on opaque pipeline caches, you can:

- Compute a portable pipeline key up front for a given set of creation parameters.
- Ask the driver to give you an implementation-specific binary for that key.
- Persist that binary and reuse it on the same driver/device to avoid runtime compilation hitches.

This sample provides an interactive demonstration of the complete pipeline binary workflow. It creates a compute pipeline, captures its binary, and allows you to:

- Recreate pipelines from scratch or from cached binaries with performance timing
- Save binaries to disk and load them back
- Compare creation times to see the performance benefits
- Observe the speedup gained from using pre-compiled binaries

== Why and when to use it
Pipeline caches are useful, but they are intentionally opaque and not keyed by a structure you can compute deterministically. Pipeline binaries add:

- Deterministic cache management (you can compute the key before creating a pipeline).
- Cross-process or install-time pre-warming strategies.
- A clear, explicit handle (VkPipelineBinaryKHR) you can store and manage.

They complement other techniques:

- VK_EXT_graphics_pipeline_library reduces link-time work, but doesn’t hand you the final binary for persistence.
- VK_EXT_shader_object changes the binding model, not binary persistence.

== How it works (TL;DR)
. Prepare the same creation info you’d pass to vkCreate*Pipelines (compute or graphics).
. Wrap it in VkPipelineCreateInfoKHR.
. vkGetPipelineKeyKHR(device, &VkPipelineCreateInfoKHR, &VkPipelineBinaryKeyKHR) → portable key.
. vkCreatePipelineBinariesKHR(device, &VkPipelineBinaryCreateInfoKHR, …) → VkPipelineBinaryKHR handle.
. vkGetPipelineBinaryDataKHR(device, &VkPipelineBinaryDataInfoKHR, …) → query size, then fetch bytes.
. Store bytes together with device/vendor/driver identifiers and the key.

== Required Vulkan extensions and features
To use feature chaining like the other samples, this sample enables the following and requests the needed feature explicitly:

- Instance: `VK_KHR_get_physical_device_properties2` — required by the framework to chain extension feature structs during device creation.
- Device: `VK_KHR_pipeline_binary` — the extension demonstrated here.
- Device: `VK_KHR_maintenance5` — defines the `VkPipelineCreateFlags2` flag space that includes CAPTURE_DATA (not required for this sample’s path, but commonly expected by validation).
- Device: `VK_KHR_dynamic_rendering`, `VK_KHR_depth_stencil_resolve`, `VK_KHR_create_renderpass2` — commonly used by the framework/WSI paths; enabled to avoid spurious present-time validation issues.

Note: This sample uses the `pPipelineCreateInfo` path when creating pipeline binaries, so it does not require creating a live pipeline with `CAPTURE_DATA` set.

== Interactive UI Features
The sample provides an interactive GUI with three main sections:

=== Pipeline Binary Info
Displays initial information about pipeline binary support, properties, and the captured binary details including key size and binary signature.

=== Interactive Demo
Provides buttons to interact with the pipeline binary system:

- **Recreate Pipeline (from scratch)**: Destroys and recreates the pipeline using normal creation, measuring the time taken.
- **Recreate Pipeline (from binary)**: Recreates the pipeline using the cached binary data, demonstrating faster creation.
- **Save Binary to File**: Persists the binary and its key to disk (`pipeline_binary.bin`).
- **Load Binary from File**: Loads a previously saved binary from disk, enabling cross-session reuse.

=== Performance Statistics
Shows timing measurements and performance comparisons:

- Creation time from scratch (in milliseconds)
- Creation time from binary (in milliseconds)
- Speedup factor (how much faster binary creation is)
- Total recreation counts for each method
- Binary size and key size information

== Walkthrough of the code
- log_pipeline_binary_support() uses vkGetPhysicalDeviceFeatures2/properties2 to show what the driver supports and prefers regarding internal caches and compression.
- demo_pipeline_key_and_binary():
* Reuses the cached compute pipeline creation info and wraps it in VkPipelineCreateInfoKHR.
* Calls vkGetPipelineKeyKHR to compute the key.
* Calls vkCreatePipelineBinariesKHR with pPipelineCreateInfo set (and pipeline/pKeysAndDataInfo null) to get a VkPipelineBinaryKHR.
* Calls vkGetPipelineBinaryDataKHR twice to first query size, then fetch bytes (requires a valid VkPipelineBinaryKeyKHR pointer on both calls).
* Stores the binary data and key in member variables for later reuse.
- recreate_pipeline_from_scratch(): Destroys and recreates the pipeline normally, measuring creation time with high-resolution timing.
- recreate_pipeline_from_binary(): Creates a pipeline from the cached binary data using VkPipelineBinaryKeysAndDataKHR, demonstrating the reuse path and measuring performance.
- save_binary_to_file() / load_binary_from_file(): Demonstrate persistence by writing/reading the key and binary data to/from disk.
- on_update_ui_overlay(): Provides the interactive GUI with buttons and real-time statistics display.

== Best practices and caveats
- Treat captured binaries as opaque and device/driver-specific; don’t assume portability across vendors or driver revisions.
- Record identity metadata (vendor ID, device ID, driver version, pipeline key) so you can invalidate stale entries.
- Some drivers may prefer or enforce internal caches; honor properties like pipelineBinaryPrefersInternalCache.
- Not all implementations will return data; some may return zero bytes. Handle that gracefully.
- Any change in creation parameters changes the key and the resulting binary.

== References
- VK_KHR_pipeline_binary specification: xref:https://docs.vulkan.org/spec/latest/chapters/pipelines.html#pipelines-binaries[pipeline binaries]
- Related samples: xref:../graphics_pipeline_library/README.adoc[graphics_pipeline_library], xref:../pipeline_cache/README.adoc[pipeline_cache]
- Khronos Blog: xref:https://www.khronos.org/blog/bringing-explicit-pipeline-caching-control-to-vulkan[Bringing explicit pipeline caching control] <- this blog includes graphs and explanation which could help with understanding how this works.
Loading
Loading