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 committed by GitHub
parent a4a85318c8
commit eb682d415d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 10 additions and 4 deletions

View file

@ -40,7 +40,7 @@ impl AcquireDrmDisplay {
) -> VkResult<vk::DisplayKHR> {
let mut display = mem::MaybeUninit::uninit();
(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]

View file

@ -88,7 +88,7 @@ impl Display {
allocation_callbacks.as_raw_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>
@ -106,7 +106,7 @@ impl Display {
plane_index,
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>
@ -123,7 +123,7 @@ impl Display {
allocation_callbacks.as_raw_ptr(),
surface.as_mut_ptr(),
)
.result_with_success(surface.assume_init())
.assume_init_on_success(surface)
}
#[inline]

View file

@ -1,6 +1,7 @@
use std::convert::TryInto;
#[cfg(feature = "debug")]
use std::fmt;
use std::mem;
use crate::vk;
pub type VkResult<T> = Result<T, vk::Result>;
@ -18,6 +19,11 @@ impl vk::Result {
_ => 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,