extensions: Only call assume_init() when Vulkan returns SUCCESS (#669)

It is undefined behaviour to construct a safe object by calling
`MaybeUninit::assume_init()` when the object in question hasn't been
initialized by anything (in this case the underlying Vulkan call) at
all, even if the object is never "used".  Postpone the `assume_init()`
call until after checking if `vk::Result::SUCCESS` has been returned by
the native implementation, by introducing a new
`assume_init_on_success()` helper that takes a `MaybeUninit<T>`.
This commit is contained in:
Marijn Suijten 2022-10-14 20:27:15 +02:00
parent 23856e9eb8
commit 1d14729721
3 changed files with 10 additions and 4 deletions

View file

@ -40,7 +40,7 @@ impl AcquireDrmDisplay {
) -> VkResult<vk::DisplayKHR> { ) -> VkResult<vk::DisplayKHR> {
let mut display = mem::MaybeUninit::uninit(); let mut display = mem::MaybeUninit::uninit();
(self.fp.get_drm_display_ext)(physical_device, drm_fd, connector_id, display.as_mut_ptr()) (self.fp.get_drm_display_ext)(physical_device, drm_fd, connector_id, display.as_mut_ptr())
.result_with_success(display.assume_init()) .assume_init_on_success(display)
} }
#[inline] #[inline]

View file

@ -88,7 +88,7 @@ impl Display {
allocation_callbacks.as_raw_ptr(), allocation_callbacks.as_raw_ptr(),
display_mode.as_mut_ptr(), display_mode.as_mut_ptr(),
) )
.result_with_success(display_mode.assume_init()) .assume_init_on_success(display_mode)
} }
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetDisplayPlaneCapabilitiesKHR.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkGetDisplayPlaneCapabilitiesKHR.html>
@ -106,7 +106,7 @@ impl Display {
plane_index, plane_index,
display_plane_capabilities.as_mut_ptr(), display_plane_capabilities.as_mut_ptr(),
) )
.result_with_success(display_plane_capabilities.assume_init()) .assume_init_on_success(display_plane_capabilities)
} }
/// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateDisplayPlaneSurfaceKHR.html> /// <https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateDisplayPlaneSurfaceKHR.html>
@ -123,7 +123,7 @@ impl Display {
allocation_callbacks.as_raw_ptr(), allocation_callbacks.as_raw_ptr(),
surface.as_mut_ptr(), surface.as_mut_ptr(),
) )
.result_with_success(surface.assume_init()) .assume_init_on_success(surface)
} }
#[inline] #[inline]

View file

@ -1,6 +1,7 @@
use std::convert::TryInto; use std::convert::TryInto;
#[cfg(feature = "debug")] #[cfg(feature = "debug")]
use std::fmt; use std::fmt;
use std::mem;
use crate::vk; use crate::vk;
pub type VkResult<T> = Result<T, vk::Result>; pub type VkResult<T> = Result<T, vk::Result>;
@ -18,6 +19,11 @@ impl vk::Result {
_ => Err(self), _ => Err(self),
} }
} }
#[inline]
pub unsafe fn assume_init_on_success<T>(self, v: mem::MaybeUninit<T>) -> VkResult<T> {
self.result().map(move |()| v.assume_init())
}
} }
/// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore, /// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore,