From 2619d2d1c7b140153e89fb9057362c4e553f0994 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Thu, 13 Oct 2022 22:17:44 +0200 Subject: [PATCH] extensions: Only call `assume_init()` when Vulkan returns `SUCCESS` 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_initialized_on_success()` helper that takes a `MaybeUninit`. --- ash/src/extensions/ext/acquire_drm_display.rs | 2 +- ash/src/extensions/khr/display.rs | 6 +++--- ash/src/prelude.rs | 6 ++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/ash/src/extensions/ext/acquire_drm_display.rs b/ash/src/extensions/ext/acquire_drm_display.rs index 3b456aab8..04525ea4d 100644 --- a/ash/src/extensions/ext/acquire_drm_display.rs +++ b/ash/src/extensions/ext/acquire_drm_display.rs @@ -40,7 +40,7 @@ impl AcquireDrmDisplay { ) -> VkResult { 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_initialized_on_success(display) } #[inline] diff --git a/ash/src/extensions/khr/display.rs b/ash/src/extensions/khr/display.rs index 326853b5c..516f817e8 100755 --- a/ash/src/extensions/khr/display.rs +++ b/ash/src/extensions/khr/display.rs @@ -88,7 +88,7 @@ impl Display { allocation_callbacks.as_raw_ptr(), display_mode.as_mut_ptr(), ) - .result_with_success(display_mode.assume_init()) + .assume_initialized_on_success(display_mode) } /// @@ -106,7 +106,7 @@ impl Display { plane_index, display_plane_capabilities.as_mut_ptr(), ) - .result_with_success(display_plane_capabilities.assume_init()) + .assume_initialized_on_success(display_plane_capabilities) } /// @@ -123,7 +123,7 @@ impl Display { allocation_callbacks.as_raw_ptr(), surface.as_mut_ptr(), ) - .result_with_success(surface.assume_init()) + .assume_initialized_on_success(surface) } #[inline] diff --git a/ash/src/prelude.rs b/ash/src/prelude.rs index 218c59bea..071e42622 100644 --- a/ash/src/prelude.rs +++ b/ash/src/prelude.rs @@ -1,6 +1,7 @@ use std::convert::TryInto; #[cfg(feature = "debug")] use std::fmt; +use std::mem; use crate::vk; pub type VkResult = Result; @@ -18,6 +19,11 @@ impl vk::Result { _ => Err(self), } } + + #[inline] + pub unsafe fn assume_initialized_on_success(self, v: mem::MaybeUninit) -> VkResult { + self.result().map(move |()| v.assume_init()) + } } /// Repeatedly calls `f` until it does not return [`vk::Result::INCOMPLETE`] anymore,