Skip to content

Commit 7be4595

Browse files
committed
extensions/khr: Add VK_KHR_pipeline_binary extension
1 parent 7dcf57b commit 7be4595

File tree

4 files changed

+133
-3
lines changed

4 files changed

+133
-3
lines changed

Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- Added `VK_KHR_get_display_properties2` instance extension (#932)
1414
- Added `VK_EXT_metal_objects` device extension (#942)
1515
- Added `VK_AMD_anti_lag` device extension (#943)
16+
- Added `VK_KHR_pipeline_binary` device extension (#944)
1617

1718
### Changed
1819

ash/src/extensions/khr/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub mod maintenance4;
3030
pub mod maintenance5;
3131
pub mod maintenance6;
3232
pub mod performance_query;
33+
pub mod pipeline_binary;
3334
pub mod pipeline_executable_properties;
3435
pub mod present_wait;
3536
pub mod push_descriptor;
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//! <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_pipeline_binary.html>
2+
3+
use crate::prelude::*;
4+
use crate::vk;
5+
use crate::RawPtr as _;
6+
use alloc::vec::Vec;
7+
use core::mem;
8+
9+
impl crate::khr::pipeline_binary::Device {
10+
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCreatePipelineBinariesKHR.html>
11+
#[inline]
12+
#[doc(alias = "vkCreatePipelineBinariesKHR")]
13+
pub unsafe fn create_pipeline_binaries(
14+
&self,
15+
create_info: &vk::PipelineBinaryCreateInfoKHR<'_>,
16+
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
17+
binaries: &mut vk::PipelineBinaryHandlesInfoKHR<'_>,
18+
) -> VkResult<()> {
19+
(self.fp.create_pipeline_binaries_khr)(
20+
self.handle,
21+
create_info,
22+
allocation_callbacks.as_raw_ptr(),
23+
binaries,
24+
)
25+
.result()
26+
}
27+
28+
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkDestroyPipelineBinaryKHR.html>
29+
#[inline]
30+
#[doc(alias = "vkDestroyPipelineBinaryKHR")]
31+
pub unsafe fn destroy_pipeline_binary(
32+
&self,
33+
pipeline_binary: vk::PipelineBinaryKHR,
34+
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
35+
) {
36+
(self.fp.destroy_pipeline_binary_khr)(
37+
self.handle,
38+
pipeline_binary,
39+
allocation_callbacks.as_raw_ptr(),
40+
)
41+
}
42+
43+
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPipelineKeyKHR.html>
44+
#[inline]
45+
#[doc(alias = "vkGetPipelineKeyKHR")]
46+
pub unsafe fn get_pipeline_key(
47+
&self,
48+
pipeline_create_info: Option<&vk::PipelineCreateInfoKHR<'_>>,
49+
) -> VkResult<vk::PipelineBinaryKeyKHR<'_>> {
50+
let mut pipeline_key = mem::MaybeUninit::uninit();
51+
(self.fp.get_pipeline_key_khr)(
52+
self.handle,
53+
pipeline_create_info.as_raw_ptr(),
54+
pipeline_key.as_mut_ptr(),
55+
)
56+
.assume_init_on_success(pipeline_key)
57+
}
58+
59+
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPipelineBinaryDataKHR.html>
60+
#[inline]
61+
#[doc(alias = "vkGetPipelineBinaryDataKHR")]
62+
pub unsafe fn get_pipeline_binary_data(
63+
&self,
64+
info: &vk::PipelineBinaryDataInfoKHR<'_>,
65+
pipeline_binary_key: &mut vk::PipelineBinaryKeyKHR<'_>,
66+
) -> VkResult<Vec<u8>> {
67+
read_into_uninitialized_binary_vector(|count, data| {
68+
(self.fp.get_pipeline_binary_data_khr)(
69+
self.handle,
70+
info,
71+
pipeline_binary_key,
72+
count,
73+
data,
74+
)
75+
})
76+
}
77+
78+
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkReleaseCapturedPipelineDataKHR.html>
79+
#[inline]
80+
#[doc(alias = "vkReleaseCapturedPipelineDataKHR")]
81+
pub unsafe fn release_captured_pipeline_data(
82+
&self,
83+
info: &vk::ReleaseCapturedPipelineDataInfoKHR<'_>,
84+
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
85+
) -> VkResult<()> {
86+
(self.fp.release_captured_pipeline_data_khr)(
87+
self.handle,
88+
info,
89+
allocation_callbacks.as_raw_ptr(),
90+
)
91+
.result()
92+
}
93+
}

ash/src/prelude.rs

+38-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use alloc::vec::Vec;
22
use core::convert::TryInto;
3+
use core::ffi;
34
use core::mem;
45
use core::ptr;
56

@@ -37,13 +38,13 @@ impl vk::Result {
3738
/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, ensuring all
3839
/// available data has been read into the vector.
3940
///
40-
/// See for example [`vkEnumerateInstanceExtensionProperties`]: the number of available items may
41+
/// See for example [`vkEnumerateInstanceExtensionProperties()`]: the number of available items may
4142
/// change between calls; [`vk::Result::INCOMPLETE`] is returned when the count increased (and the
4243
/// vector is not large enough after querying the initial size), requiring Ash to try again.
4344
///
44-
/// [`vkEnumerateInstanceExtensionProperties`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
45+
/// [`vkEnumerateInstanceExtensionProperties()`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
4546
pub(crate) unsafe fn read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>(
46-
f: impl Fn(&mut N, *mut T) -> vk::Result,
47+
mut f: impl FnMut(&mut N, *mut T) -> vk::Result,
4748
) -> VkResult<Vec<T>>
4849
where
4950
<N as TryInto<usize>>::Error: core::fmt::Debug,
@@ -64,6 +65,40 @@ where
6465
}
6566
}
6667

68+
/// Calls `f` twice until it does not return [`vk::Result::ERROR_NOT_ENOUGH_SPACE_KHR`], ensuring all
69+
/// available binary data has been read into the vector.
70+
///
71+
/// The first call happens with a [`Vec`] of size `4096`. If this is not adequate, `f` is supposed
72+
/// to return [`vk::Result::ERROR_NOT_ENOUGH_SPACE_KHR`] while also updating `count` to the desired
73+
/// number of elements, allowing us to try again.
74+
///
75+
/// This function is _not_ designed to be used with [`vk::Result::INCOMPLETE`], see
76+
/// [`read_into_uninitialized_vector()`] instead.
77+
///
78+
/// See for example [`vkGetPipelineBinaryDataKHR()`], where the new return code was first introduced.
79+
///
80+
/// [`vkGetPipelineBinaryDataKHR()`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPipelineBinaryDataKHR.html
81+
pub(crate) unsafe fn read_into_uninitialized_binary_vector(
82+
mut f: impl FnMut(&mut usize, *mut ffi::c_void) -> vk::Result,
83+
) -> VkResult<Vec<u8>> {
84+
let mut count = 4096;
85+
let mut data = Vec::<u8>::with_capacity(count);
86+
let mut err_code = f(&mut count, data.as_mut_ptr().cast());
87+
if err_code == vk::Result::ERROR_NOT_ENOUGH_SPACE_KHR {
88+
debug_assert!(
89+
count > 4096,
90+
"Implementation should have updated the value to be higher than the initial request"
91+
);
92+
err_code = f(&mut count, data.as_mut_ptr().cast());
93+
debug_assert_ne!(
94+
err_code,
95+
vk::Result::ERROR_NOT_ENOUGH_SPACE_KHR,
96+
"Updated count was still not adequate"
97+
);
98+
}
99+
err_code.set_vec_len_on_success(data, count)
100+
}
101+
67102
#[cfg(feature = "debug")]
68103
pub(crate) fn debug_flags<Value: Into<u64> + Copy>(
69104
f: &mut core::fmt::Formatter<'_>,

0 commit comments

Comments
 (0)