Skip to content

Commit

Permalink
entry: Mark all extern "C" function-pointer calls unsafe
Browse files Browse the repository at this point in the history
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: #748 (comment)
  • Loading branch information
MarijnS95 committed May 28, 2023
1 parent 53c395b commit ee5e651
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 missing `Device::get_device_queue2()` wrapper (#736)
- 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

Expand Down
69 changes: 30 additions & 39 deletions ash/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl Entry {
/// # use ash::{Entry, vk};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let entry = Entry::linked();
/// match entry.try_enumerate_instance_version()? {
/// match unsafe { entry.try_enumerate_instance_version() }? {
/// // Vulkan 1.1+
/// Some(version) => {
/// let major = vk::version_major(version);
Expand All @@ -197,22 +197,19 @@ impl Entry {
/// # Ok(()) }
/// ```
#[inline]
pub fn try_enumerate_instance_version(&self) -> VkResult<Option<u32>> {
unsafe {
let mut api_version = 0;
let enumerate_instance_version: Option<vk::PFN_vkEnumerateInstanceVersion> = {
let name = CStr::from_bytes_with_nul_unchecked(b"vkEnumerateInstanceVersion\0");
mem::transmute((self.static_fn.get_instance_proc_addr)(
vk::Instance::null(),
name.as_ptr(),
))
};
if let Some(enumerate_instance_version) = enumerate_instance_version {
(enumerate_instance_version)(&mut api_version)
.result_with_success(Some(api_version))
} else {
Ok(None)
}
pub unsafe fn try_enumerate_instance_version(&self) -> VkResult<Option<u32>> {
let mut api_version = 0;
let enumerate_instance_version: Option<vk::PFN_vkEnumerateInstanceVersion> = {
let name = CStr::from_bytes_with_nul_unchecked(b"vkEnumerateInstanceVersion\0");
mem::transmute((self.static_fn.get_instance_proc_addr)(
vk::Instance::null(),
name.as_ptr(),
))
};
if let Some(enumerate_instance_version) = enumerate_instance_version {
(enumerate_instance_version)(&mut api_version).result_with_success(Some(api_version))
} else {
Ok(None)
}
}

Expand Down Expand Up @@ -240,29 +237,25 @@ impl Entry {

/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkEnumerateInstanceLayerProperties.html>
#[inline]
pub fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
unsafe {
read_into_uninitialized_vector(|count, data| {
(self.entry_fn_1_0.enumerate_instance_layer_properties)(count, data)
})
}
pub unsafe fn enumerate_instance_layer_properties(&self) -> VkResult<Vec<vk::LayerProperties>> {
read_into_uninitialized_vector(|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>
#[inline]
pub fn enumerate_instance_extension_properties(
pub unsafe fn enumerate_instance_extension_properties(
&self,
layer_name: Option<&CStr>,
) -> VkResult<Vec<vk::ExtensionProperties>> {
unsafe {
read_into_uninitialized_vector(|count, data| {
(self.entry_fn_1_0.enumerate_instance_extension_properties)(
layer_name.map_or(ptr::null(), |str| str.as_ptr()),
count,
data,
)
})
}
read_into_uninitialized_vector(|count, data| {
(self.entry_fn_1_0.enumerate_instance_extension_properties)(
layer_name.map_or(ptr::null(), |str| str.as_ptr()),
count,
data,
)
})
}

/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetInstanceProcAddr.html>
Expand All @@ -288,12 +281,10 @@ impl Entry {
///
/// Please use [`try_enumerate_instance_version()`][Self::try_enumerate_instance_version()] instead.
#[inline]
pub fn enumerate_instance_version(&self) -> VkResult<u32> {
unsafe {
let mut api_version = 0;
(self.entry_fn_1_1.enumerate_instance_version)(&mut api_version)
.result_with_success(api_version)
}
pub unsafe fn enumerate_instance_version(&self) -> VkResult<u32> {
let mut api_version = 0;
(self.entry_fn_1_1.enumerate_instance_version)(&mut api_version)
.result_with_success(api_version)
}
}

Expand Down

0 comments on commit ee5e651

Please sign in to comment.