From d6e189e170769cc8dfcdbc1e848b5370f914ea3d Mon Sep 17 00:00:00 2001 From: Idan Raiter Date: Mon, 22 Aug 2022 21:32:15 -0700 Subject: [PATCH] Opaque Windows handle external memory import support Adds support for importing OpaqueWin32 and OpaqueWin32Kmt handles. --- vulkano/src/memory/device_memory.rs | 93 +++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/vulkano/src/memory/device_memory.rs b/vulkano/src/memory/device_memory.rs index f799a7620f..e70766e23f 100644 --- a/vulkano/src/memory/device_memory.rs +++ b/vulkano/src/memory/device_memory.rs @@ -288,6 +288,48 @@ impl DeviceMemory { // Can't validate, must be ensured by user } } + &mut MemoryImportInfo::Win32 { + handle_type, + handle: _, + } => { + if !device.enabled_extensions().khr_external_memory_win32 { + return Err(DeviceMemoryAllocationError::ExtensionNotEnabled { + extension: "khr_external_memory_win32", + reason: "`import_info` was `MemoryImportInfo::Win32`", + }); + } + + #[cfg(not(windows))] + unreachable!( + "`khr_external_memory_win32` was somehow enabled on a non-Windows system" + ); + + #[cfg(windows)] + { + // VUID-VkImportMemoryWin32HandleInfoKHR-handleType-00660 + match handle_type { + ExternalMemoryHandleType::OpaqueWin32 + | ExternalMemoryHandleType::OpaqueWin32Kmt => { + // VUID-VkMemoryAllocateInfo-allocationSize-01742 + // Can't validate, must be ensured by user + + // VUID-VkMemoryDedicatedAllocateInfo-buffer-01879 + // Can't validate, must be ensured by user + + // VUID-VkMemoryDedicatedAllocateInfo-image-01878 + // Can't validate, must be ensured by user + } + _ => return Err( + DeviceMemoryAllocationError::ImportWin32HandleTypeNotSupported { + handle_type, + }, + ), + } + + // VUID-VkMemoryAllocateInfo-memoryTypeIndex-00645 + // Can't validate, must be ensured by user + } + } } } @@ -360,6 +402,24 @@ impl DeviceMemory { allocate_info = allocate_info.push_next(info); } + #[cfg(windows)] + let mut import_win32_handle_info = match import_info { + Some(MemoryImportInfo::Win32 { + handle_type, + handle, + }) => Some(ash::vk::ImportMemoryWin32HandleInfoKHR { + handle_type: handle_type.into(), + handle, + ..Default::default() + }), + _ => None, + }; + + #[cfg(windows)] + if let Some(info) = import_win32_handle_info.as_mut() { + allocate_info = allocate_info.push_next(info); + } + let mut allocation_count = device.allocation_count().lock(); // VUID-vkAllocateMemory-maxMemoryAllocationCount-04101 @@ -544,6 +604,11 @@ pub enum DeviceMemoryAllocationError { handle_type: ExternalMemoryHandleType, }, + /// The provided `MemoryImportInfo::Win32::handle_type` is not supported. + ImportWin32HandleTypeNotSupported { + handle_type: ExternalMemoryHandleType, + }, + /// The provided `allocation_size` was greater than the memory type's heap size. MemoryTypeHeapSizeExceeded { allocation_size: DeviceSize, @@ -604,6 +669,11 @@ impl fmt::Display for DeviceMemoryAllocationError { "the provided `MemoryImportInfo::Fd::handle_type` ({:?}) is not supported for file descriptors", handle_type, ), + Self::ImportWin32HandleTypeNotSupported { handle_type } => write!( + fmt, + "the provided `MemoryImportInfo::Win32::handle_type` ({:?}) is not supported", + handle_type, + ), Self::MemoryTypeHeapSizeExceeded { allocation_size, heap_size } => write!( fmt, "the provided `allocation_size` ({}) was greater than the memory type's heap size ({})", @@ -733,6 +803,29 @@ pub enum MemoryImportInfo { handle_type: ExternalMemoryHandleType, file: File, }, + /// Import memory from a Windows handle. + /// + /// `handle_type` must be either [`ExternalMemoryHandleType::OpaqueWin32`] or + /// [`ExternalMemoryHandleType::OpaqueWin32Kmt`]. + /// + /// # Safety + /// + /// - `handle` must be a valid Windows handle. + /// - Vulkan will not take ownership of `handle`. + /// - If `handle_type` is [`ExternalMemoryHandleType::OpaqueWin32`], it owns a reference + /// to the underlying resource and must eventually be closed by the caller. + /// - If `handle_type` is [`ExternalMemoryHandleType::OpaqueWin32Kmt`], it does not own a + /// reference to the underlying resource. + /// - `handle` must be created by the Vulkan API. + /// - [`MemoryAllocateInfo::allocation_size`] and [`MemoryAllocateInfo::memory_type_index`] + /// must match those of the original memory allocation. + /// - If the original memory allocation used [`MemoryAllocateInfo::dedicated_allocation`], + /// the imported one must also use it, and the associated buffer or image must be defined + /// identically to the original. + Win32 { + handle_type: ExternalMemoryHandleType, + handle: ash::vk::HANDLE, + }, } /// Describes a handle type used for Vulkan external memory apis. This is **not** just a