From 0c619fcd62c2b5c08230209a69527639c2d6a22d Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 18 Apr 2018 15:30:07 -0400 Subject: [PATCH] Keep a list of allocated command buffes for proper destruction of the pool --- libportability-gfx/src/handle.rs | 16 ++++++++++++++-- libportability-gfx/src/impls.rs | 30 +++++++++++++++++++++++------- libportability-gfx/src/lib.rs | 7 ++++++- libportability-icd/src/lib.rs | 4 ++-- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/libportability-gfx/src/handle.rs b/libportability-gfx/src/handle.rs index a4899bc..843501e 100644 --- a/libportability-gfx/src/handle.rs +++ b/libportability-gfx/src/handle.rs @@ -1,5 +1,5 @@ use VK_NULL_HANDLE; -use std::{borrow, fmt, ops}; +use std::{borrow, cmp, fmt, ops}; #[repr(C)] @@ -51,6 +51,12 @@ impl borrow::Borrow for Handle { } } +impl cmp::PartialEq for Handle { + fn eq(&self, other: &Self) -> bool { + self.0.eq(&other.0) + } +} + impl fmt::Debug for Handle { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "Handle({:p})", self.0) @@ -65,7 +71,7 @@ pub type DispatchHandle = Handle; #[cfg(feature = "dispatch")] mod dispatch { use VK_NULL_HANDLE; - use std::{borrow, fmt, ops}; + use std::{borrow, cmp, fmt, ops}; const ICD_LOADER_MAGIC: u64 = 0x01CDC0DE; @@ -118,6 +124,12 @@ mod dispatch { } } + impl cmp::PartialEq for DispatchHandle { + fn eq(&self, other: &Self) -> bool { + self.0.eq(&other.0) + } + } + impl fmt::Debug for DispatchHandle { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "DispatchHandle({:p})", self.0) diff --git a/libportability-gfx/src/impls.rs b/libportability-gfx/src/impls.rs index 227416e..e61af18 100644 --- a/libportability-gfx/src/impls.rs +++ b/libportability-gfx/src/impls.rs @@ -2334,7 +2334,10 @@ pub extern "C" fn gfxCreateCommandPool( flags |= CommandPoolCreateFlags::RESET_INDIVIDUAL; } - let pool = gpu.device.create_command_pool(family, flags); + let pool = CommandPool { + pool: gpu.device.create_command_pool(family, flags), + buffers: Vec::new(), + }; unsafe { *pCommandPool = Handle::new(pool) }; VkResult::VK_SUCCESS } @@ -2345,7 +2348,11 @@ pub extern "C" fn gfxDestroyCommandPool( commandPool: VkCommandPool, _pAllocator: *const VkAllocationCallbacks, ) { - gpu.device.destroy_command_pool(commandPool.unbox()); + let pool = commandPool.unbox(); + for cmd_buf in pool.buffers { + let _ = cmd_buf.unbox(); + } + gpu.device.destroy_command_pool(pool.pool); } #[inline] @@ -2354,7 +2361,7 @@ pub extern "C" fn gfxResetCommandPool( mut commandPool: VkCommandPool, _flags: VkCommandPoolResetFlags, ) -> VkResult { - commandPool.reset(); + commandPool.pool.reset(); VkResult::VK_SUCCESS } @@ -2373,12 +2380,13 @@ pub extern "C" fn gfxAllocateCommandBuffers( let count = info.commandBufferCount as usize; - let cmd_bufs = info.commandPool.allocate(count, level); + let cmd_bufs = info.commandPool.pool.allocate(count, level); let output = unsafe { slice::from_raw_parts_mut(pCommandBuffers, count) }; for (out, cmd_buf) in output.iter_mut().zip(cmd_bufs) { *out = DispatchHandle::new(cmd_buf); } + info.commandPool.buffers.extend_from_slice(output); VkResult::VK_SUCCESS } @@ -2393,8 +2401,10 @@ pub extern "C" fn gfxFreeCommandBuffers( let slice = unsafe { slice::from_raw_parts(pCommandBuffers, commandBufferCount as _) }; + commandPool.buffers.retain(|buf| !slice.contains(buf)); + let buffers = slice.iter().map(|buffer| buffer.unbox()).collect(); - unsafe { commandPool.free(buffers) }; + unsafe { commandPool.pool.free(buffers) }; } #[inline] @@ -3448,7 +3458,10 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR( } } #[cfg(not(target_os = "windows"))] - unreachable!() + { + let _ = (instance, info, pSurface); + unreachable!() + } } pub extern "C" fn gfxCreateXcbSurfaceKHR( instance: VkInstance, @@ -3469,7 +3482,10 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR( } } #[cfg(not(all(feature = "gfx-backend-vulkan", target_os = "linux")))] - unreachable!() + { + let _ = (instance, info, pSurface); + unreachable!() + } } #[inline] pub extern "C" fn gfxAcquireNextImageKHR( diff --git a/libportability-gfx/src/lib.rs b/libportability-gfx/src/lib.rs index 3d6dcba..f7b3aa8 100644 --- a/libportability-gfx/src/lib.rs +++ b/libportability-gfx/src/lib.rs @@ -42,7 +42,7 @@ pub struct RawInstance { pub type VkInstance = Handle; pub type VkDevice = DispatchHandle>; pub type VkQueue = DispatchHandle<::CommandQueue>; -pub type VkCommandPool = Handle<::CommandPool>; +pub type VkCommandPool = Handle>; pub type VkCommandBuffer = DispatchHandle<::CommandBuffer>; pub type VkDeviceMemory = Handle<::Memory>; pub type VkDescriptorSetLayout = Handle<::DescriptorSetLayout>; @@ -83,6 +83,11 @@ pub enum Buffer { Unbound(B::UnboundBuffer), } +pub struct CommandPool { + pool: B::CommandPool, + buffers: Vec, +} + //NOTE: all *KHR types have to be pure `Handle` things for compatibility with //`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h` pub type VkSurfaceKHR = Handle<::Surface>; diff --git a/libportability-icd/src/lib.rs b/libportability-icd/src/lib.rs index b152bb5..a5a500a 100644 --- a/libportability-icd/src/lib.rs +++ b/libportability-icd/src/lib.rs @@ -7,7 +7,7 @@ use portability_gfx::*; use std::ffi::CStr; use std::mem; -use std::ptr; + const ICD_VERSION: u32 = 5; @@ -33,7 +33,7 @@ pub extern "C" fn vk_icdNegotiateLoaderICDInterfaceVersion( #[no_mangle] pub extern "C" fn vk_icdGetPhysicalDeviceProcAddr( - instance: VkInstance, + _instance: VkInstance, pName: *const ::std::os::raw::c_char, ) -> PFN_vkVoidFunction { let name = unsafe { CStr::from_ptr(pName) };