Skip to content

Commit

Permalink
extensions/khr: Add VK_KHR_pipeline_binary extension
Browse files Browse the repository at this point in the history
  • Loading branch information
MarijnS95 committed Dec 4, 2024
1 parent eca7251 commit d34d711
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 2 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `VK_KHR_get_display_properties2` instance extension (#932)
- Added `VK_EXT_metal_objects` device extension (#942)
- Added `VK_AMD_anti_lag` device extension (#943)
- Added `VK_KHR_pipeline_binary` device extension (#944)

## [0.38.0] - 2024-04-01

Expand Down
1 change: 1 addition & 0 deletions ash/src/extensions/khr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub mod maintenance4;
pub mod maintenance5;
pub mod maintenance6;
pub mod performance_query;
pub mod pipeline_binary;
pub mod pipeline_executable_properties;
pub mod present_wait;
pub mod push_descriptor;
Expand Down
94 changes: 94 additions & 0 deletions ash/src/extensions/khr/pipeline_binary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//! <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_pipeline_binary.html>
use crate::prelude::*;
use crate::vk;
use crate::RawPtr as _;
use alloc::vec::Vec;
use core::ffi;
use core::mem;

impl crate::khr::pipeline_binary::Device {
/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCreatePipelineBinariesKHR.html>
#[inline]
#[doc(alias = "vkCreatePipelineBinariesKHR")]
pub unsafe fn create_pipeline_binaries(
&self,
create_info: &vk::PipelineBinaryCreateInfoKHR<'_>,
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
binaries: &mut vk::PipelineBinaryHandlesInfoKHR<'_>,
) -> VkResult<()> {
(self.fp.create_pipeline_binaries_khr)(
self.handle,
create_info,
allocation_callbacks.as_raw_ptr(),
binaries,
)
.result()
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkDestroyPipelineBinaryKHR.html>
#[inline]
#[doc(alias = "vkDestroyPipelineBinaryKHR")]
pub unsafe fn destroy_pipeline_binary(
&self,
pipeline_binary: vk::PipelineBinaryKHR,
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
) {
(self.fp.destroy_pipeline_binary_khr)(
self.handle,
pipeline_binary,
allocation_callbacks.as_raw_ptr(),
)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPipelineKeyKHR.html>
#[inline]
#[doc(alias = "vkGetPipelineKeyKHR")]
pub unsafe fn get_pipeline_key(
&self,
pipeline_create_info: Option<&vk::PipelineCreateInfoKHR<'_>>,
) -> VkResult<vk::PipelineBinaryKeyKHR<'_>> {
let mut pipeline_key = mem::MaybeUninit::uninit();
(self.fp.get_pipeline_key_khr)(
self.handle,
pipeline_create_info.as_raw_ptr(),
pipeline_key.as_mut_ptr(),
)
.assume_init_on_success(pipeline_key)
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPipelineBinaryDataKHR.html>
#[inline]
#[doc(alias = "vkGetPipelineBinaryDataKHR")]
pub unsafe fn get_pipeline_binary_data(
&self,
info: &vk::PipelineBinaryDataInfoKHR<'_>,
pipeline_binary_key: &mut vk::PipelineBinaryKeyKHR<'_>,
) -> VkResult<Vec<u8>> {
read_into_uninitialized_binary_vector(|count, data| {
(self.fp.get_pipeline_binary_data_khr)(
self.handle,
info,
pipeline_binary_key,
count,
data,
)
})
}

/// <https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkReleaseCapturedPipelineDataKHR.html>
#[inline]
#[doc(alias = "vkReleaseCapturedPipelineDataKHR")]
pub unsafe fn release_captured_pipeline_data(
&self,
info: &vk::ReleaseCapturedPipelineDataInfoKHR<'_>,
allocation_callbacks: Option<&vk::AllocationCallbacks<'_>>,
) -> VkResult<()> {
(self.fp.release_captured_pipeline_data_khr)(
self.handle,
info,
allocation_callbacks.as_raw_ptr(),
)
.result()
}
}
39 changes: 37 additions & 2 deletions ash/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use alloc::vec::Vec;
use core::convert::TryInto;
use core::ffi;
use core::mem;
use core::ptr;

Expand Down Expand Up @@ -43,7 +44,7 @@ impl vk::Result {
///
/// [`vkEnumerateInstanceExtensionProperties`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html
pub(crate) unsafe fn read_into_uninitialized_vector<N: Copy + Default + TryInto<usize>, T>(
f: impl Fn(&mut N, *mut T) -> vk::Result,
mut f: impl FnMut(&mut N, *mut T) -> vk::Result,
) -> VkResult<Vec<T>>
where
<N as TryInto<usize>>::Error: core::fmt::Debug,
Expand All @@ -64,6 +65,40 @@ where
}
}

/// Calls `f` twice until it does not return [`vk::Result::ERROR_NOT_ENOUGH_SPACE_KHR`], ensuring all
/// available binary data has been read into the vector.
///
/// The first call happens with a [`Vec`] of size `4096`. If this is not adequate, `f` is supposed
/// to return [`vk::Result::ERROR_NOT_ENOUGH_SPACE_KHR`] while also updating `count` to the desired
/// number of elements, allowing us to try again.
///
/// This function is _not_ designed to be used with [`vk::Result::INCOMPLETE`], see
/// [`read_into_uninitialized_vector()`] instead.
///
/// See for example [`vkGetPipelineBinaryDataKHR`].
///
/// [`vkGetPipelineBinaryDataKHR`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkGetPipelineBinaryDataKHR.html
pub(crate) unsafe fn read_into_uninitialized_binary_vector(
mut f: impl FnMut(&mut usize, *mut ffi::c_void) -> vk::Result,
) -> VkResult<Vec<u8>> {
let mut count = 4096;
let mut data = Vec::<u8>::with_capacity(count);
let mut err_code = f(&mut count, data.as_mut_ptr().cast());
if err_code == vk::Result::ERROR_NOT_ENOUGH_SPACE_KHR {
debug_assert!(
count > 4096,
"Implementation should have updated the value to be higher than the initial request"
);
err_code = f(&mut count, data.as_mut_ptr().cast());
debug_assert_ne!(
err_code,
vk::Result::ERROR_NOT_ENOUGH_SPACE_KHR,
"Updated count was still not adequate"
);
}
err_code.set_vec_len_on_success(data, count)
}

/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, ensuring all
/// available data has been read into the vector.
///
Expand All @@ -81,7 +116,7 @@ pub(crate) unsafe fn read_into_defaulted_vector<
N: Copy + Default + TryInto<usize>,
T: Default + Clone,
>(
f: impl Fn(&mut N, *mut T) -> vk::Result,
mut f: impl FnMut(&mut N, *mut T) -> vk::Result,
) -> VkResult<Vec<T>>
where
<N as TryInto<usize>>::Error: core::fmt::Debug,
Expand Down

0 comments on commit d34d711

Please sign in to comment.