entry: Mark all extern "C" function-pointer calls unsafe

We don't mark any of the extern calls to Vulkan function-pointers safe
except for a few `Entry` functions.  Their safety contract was easy to
validate, but now that we exposed a constructor function to let the user
provide function pointers in the form of `Entry::from_parts_1_1()` it is
no longer safe to assume that we are calling the function that adheres
to the contract specified in the Vulkan reference.

Because we don't rigorously do this validation and safe-marking anywhere
else either, mark these function calls as `unsafe`.

Related discussion chain: https://github.com/ash-rs/ash/pull/748#discussion_r1186794284
This commit is contained in:
Marijn Suijten 2023-05-29 01:32:22 +02:00 committed by GitHub
parent 53c395b6b6
commit bdafbb4646
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 40 deletions

View file

@ -16,7 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `VK_EXT_shader_object` device extension (#732) - Added `VK_EXT_shader_object` device extension (#732)
- Added missing `Device::get_device_queue2()` wrapper (#736) - Added missing `Device::get_device_queue2()` wrapper (#736)
- Exposed `FramebufferCreateInfo::attachment_count()` builder for `vk::FramebufferCreateFlags::IMAGELESS` (#747) - Exposed `FramebufferCreateInfo::attachment_count()` builder for `vk::FramebufferCreateFlags::IMAGELESS` (#747)
- Allow building `Entry`/`Instance`/`Device` from handle+fns (#748) - Allow building `Entry`/`Instance`/`Device` from handle+fns (see their `from_parts_1_x()` associated functions) (#748)
### Changed ### Changed

View file

@ -184,7 +184,7 @@ impl Entry {
/// # use ash::{Entry, vk}; /// # use ash::{Entry, vk};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> { /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let entry = Entry::linked(); /// let entry = Entry::linked();
/// match entry.try_enumerate_instance_version()? { /// match unsafe { entry.try_enumerate_instance_version() }? {
/// // Vulkan 1.1+ /// // Vulkan 1.1+
/// Some(version) => { /// Some(version) => {
/// let major = vk::version_major(version); /// let major = vk::version_major(version);
@ -197,8 +197,7 @@ impl Entry {
/// # Ok(()) } /// # Ok(()) }
/// ``` /// ```
#[inline] #[inline]
pub fn try_enumerate_instance_version(&self) -> VkResult<Option<u32>> { pub unsafe fn try_enumerate_instance_version(&self) -> VkResult<Option<u32>> {
unsafe {
let mut api_version = 0; let mut api_version = 0;
let enumerate_instance_version: Option<vk::PFN_vkEnumerateInstanceVersion> = { let enumerate_instance_version: Option<vk::PFN_vkEnumerateInstanceVersion> = {
let name = CStr::from_bytes_with_nul_unchecked(b"vkEnumerateInstanceVersion\0"); let name = CStr::from_bytes_with_nul_unchecked(b"vkEnumerateInstanceVersion\0");
@ -208,13 +207,11 @@ impl Entry {
)) ))
}; };
if let Some(enumerate_instance_version) = enumerate_instance_version { if let Some(enumerate_instance_version) = enumerate_instance_version {
(enumerate_instance_version)(&mut api_version) (enumerate_instance_version)(&mut api_version).result_with_success(Some(api_version))
.result_with_success(Some(api_version))
} else { } else {
Ok(None) Ok(None)
} }
} }
}
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateInstance.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateInstance.html>
/// ///
@ -240,21 +237,18 @@ impl Entry {
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceLayerProperties.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceLayerProperties.html>
#[inline] #[inline]
pub fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> { pub unsafe fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
unsafe {
read_into_uninitialized_vector(|count, data| { read_into_uninitialized_vector(|count, data| {
(self.entry_fn_1_0.enumerate_instance_layer_properties)(count, data) (self.entry_fn_1_0.enumerate_instance_layer_properties)(count, data)
}) })
} }
}
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceExtensionProperties.html>
#[inline] #[inline]
pub fn enumerate_instance_extension_properties( pub unsafe fn enumerate_instance_extension_properties(
&self, &self,
layer_name: Option<&CStr>, layer_name: Option<&CStr>,
) -> VkResult<Vec<vk::ExtensionProperties>> { ) -> VkResult<Vec<vk::ExtensionProperties>> {
unsafe {
read_into_uninitialized_vector(|count, data| { read_into_uninitialized_vector(|count, data| {
(self.entry_fn_1_0.enumerate_instance_extension_properties)( (self.entry_fn_1_0.enumerate_instance_extension_properties)(
layer_name.map_or(ptr::null(), |str| str.as_ptr()), layer_name.map_or(ptr::null(), |str| str.as_ptr()),
@ -263,7 +257,6 @@ impl Entry {
) )
}) })
} }
}
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetInstanceProcAddr.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetInstanceProcAddr.html>
#[inline] #[inline]
@ -288,13 +281,11 @@ impl Entry {
/// ///
/// Please use [`try_enumerate_instance_version()`][Self::try_enumerate_instance_version()] instead. /// Please use [`try_enumerate_instance_version()`][Self::try_enumerate_instance_version()] instead.
#[inline] #[inline]
pub fn enumerate_instance_version(&self) -> VkResult<u32> { pub unsafe fn enumerate_instance_version(&self) -> VkResult<u32> {
unsafe {
let mut api_version = 0; let mut api_version = 0;
(self.entry_fn_1_1.enumerate_instance_version)(&mut api_version) (self.entry_fn_1_1.enumerate_instance_version)(&mut api_version)
.result_with_success(api_version) .result_with_success(api_version)
} }
}
} }
#[cfg(feature = "linked")] #[cfg(feature = "linked")]