Keep a list of allocated command buffes for proper destruction of the pool

This commit is contained in:
Dzmitry Malyshau 2018-04-18 15:30:07 -04:00
parent b46ade6360
commit 0c619fcd62
4 changed files with 45 additions and 12 deletions

View file

@ -1,5 +1,5 @@
use VK_NULL_HANDLE; use VK_NULL_HANDLE;
use std::{borrow, fmt, ops}; use std::{borrow, cmp, fmt, ops};
#[repr(C)] #[repr(C)]
@ -51,6 +51,12 @@ impl<T> borrow::Borrow<T> for Handle<T> {
} }
} }
impl<T> cmp::PartialEq for Handle<T> {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl<T> fmt::Debug for Handle<T> { impl<T> fmt::Debug for Handle<T> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Handle({:p})", self.0) write!(formatter, "Handle({:p})", self.0)
@ -65,7 +71,7 @@ pub type DispatchHandle<T> = Handle<T>;
#[cfg(feature = "dispatch")] #[cfg(feature = "dispatch")]
mod dispatch { mod dispatch {
use VK_NULL_HANDLE; use VK_NULL_HANDLE;
use std::{borrow, fmt, ops}; use std::{borrow, cmp, fmt, ops};
const ICD_LOADER_MAGIC: u64 = 0x01CDC0DE; const ICD_LOADER_MAGIC: u64 = 0x01CDC0DE;
@ -118,6 +124,12 @@ mod dispatch {
} }
} }
impl<T> cmp::PartialEq for DispatchHandle<T> {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl<T> fmt::Debug for DispatchHandle<T> { impl<T> fmt::Debug for DispatchHandle<T> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "DispatchHandle({:p})", self.0) write!(formatter, "DispatchHandle({:p})", self.0)

View file

@ -2334,7 +2334,10 @@ pub extern "C" fn gfxCreateCommandPool(
flags |= CommandPoolCreateFlags::RESET_INDIVIDUAL; 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) }; unsafe { *pCommandPool = Handle::new(pool) };
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -2345,7 +2348,11 @@ pub extern "C" fn gfxDestroyCommandPool(
commandPool: VkCommandPool, commandPool: VkCommandPool,
_pAllocator: *const VkAllocationCallbacks, _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] #[inline]
@ -2354,7 +2361,7 @@ pub extern "C" fn gfxResetCommandPool(
mut commandPool: VkCommandPool, mut commandPool: VkCommandPool,
_flags: VkCommandPoolResetFlags, _flags: VkCommandPoolResetFlags,
) -> VkResult { ) -> VkResult {
commandPool.reset(); commandPool.pool.reset();
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -2373,12 +2380,13 @@ pub extern "C" fn gfxAllocateCommandBuffers(
let count = info.commandBufferCount as usize; 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) }; let output = unsafe { slice::from_raw_parts_mut(pCommandBuffers, count) };
for (out, cmd_buf) in output.iter_mut().zip(cmd_bufs) { for (out, cmd_buf) in output.iter_mut().zip(cmd_bufs) {
*out = DispatchHandle::new(cmd_buf); *out = DispatchHandle::new(cmd_buf);
} }
info.commandPool.buffers.extend_from_slice(output);
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
@ -2393,8 +2401,10 @@ pub extern "C" fn gfxFreeCommandBuffers(
let slice = unsafe { let slice = unsafe {
slice::from_raw_parts(pCommandBuffers, commandBufferCount as _) slice::from_raw_parts(pCommandBuffers, commandBufferCount as _)
}; };
commandPool.buffers.retain(|buf| !slice.contains(buf));
let buffers = slice.iter().map(|buffer| buffer.unbox()).collect(); let buffers = slice.iter().map(|buffer| buffer.unbox()).collect();
unsafe { commandPool.free(buffers) }; unsafe { commandPool.pool.free(buffers) };
} }
#[inline] #[inline]
@ -3448,7 +3458,10 @@ pub extern "C" fn gfxCreateWin32SurfaceKHR(
} }
} }
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
unreachable!() {
let _ = (instance, info, pSurface);
unreachable!()
}
} }
pub extern "C" fn gfxCreateXcbSurfaceKHR( pub extern "C" fn gfxCreateXcbSurfaceKHR(
instance: VkInstance, instance: VkInstance,
@ -3469,7 +3482,10 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR(
} }
} }
#[cfg(not(all(feature = "gfx-backend-vulkan", target_os = "linux")))] #[cfg(not(all(feature = "gfx-backend-vulkan", target_os = "linux")))]
unreachable!() {
let _ = (instance, info, pSurface);
unreachable!()
}
} }
#[inline] #[inline]
pub extern "C" fn gfxAcquireNextImageKHR( pub extern "C" fn gfxAcquireNextImageKHR(

View file

@ -42,7 +42,7 @@ pub struct RawInstance {
pub type VkInstance = Handle<RawInstance>; pub type VkInstance = Handle<RawInstance>;
pub type VkDevice = DispatchHandle<Gpu<B>>; pub type VkDevice = DispatchHandle<Gpu<B>>;
pub type VkQueue = DispatchHandle<<B as hal::Backend>::CommandQueue>; pub type VkQueue = DispatchHandle<<B as hal::Backend>::CommandQueue>;
pub type VkCommandPool = Handle<<B as hal::Backend>::CommandPool>; pub type VkCommandPool = Handle<CommandPool<B>>;
pub type VkCommandBuffer = DispatchHandle<<B as hal::Backend>::CommandBuffer>; pub type VkCommandBuffer = DispatchHandle<<B as hal::Backend>::CommandBuffer>;
pub type VkDeviceMemory = Handle<<B as hal::Backend>::Memory>; pub type VkDeviceMemory = Handle<<B as hal::Backend>::Memory>;
pub type VkDescriptorSetLayout = Handle<<B as hal::Backend>::DescriptorSetLayout>; pub type VkDescriptorSetLayout = Handle<<B as hal::Backend>::DescriptorSetLayout>;
@ -83,6 +83,11 @@ pub enum Buffer<B: hal::Backend> {
Unbound(B::UnboundBuffer), Unbound(B::UnboundBuffer),
} }
pub struct CommandPool<B: hal::Backend> {
pool: B::CommandPool,
buffers: Vec<VkCommandBuffer>,
}
//NOTE: all *KHR types have to be pure `Handle` things for compatibility with //NOTE: all *KHR types have to be pure `Handle` things for compatibility with
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h` //`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>; pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;

View file

@ -7,7 +7,7 @@ use portability_gfx::*;
use std::ffi::CStr; use std::ffi::CStr;
use std::mem; use std::mem;
use std::ptr;
const ICD_VERSION: u32 = 5; const ICD_VERSION: u32 = 5;
@ -33,7 +33,7 @@ pub extern "C" fn vk_icdNegotiateLoaderICDInterfaceVersion(
#[no_mangle] #[no_mangle]
pub extern "C" fn vk_icdGetPhysicalDeviceProcAddr( pub extern "C" fn vk_icdGetPhysicalDeviceProcAddr(
instance: VkInstance, _instance: VkInstance,
pName: *const ::std::os::raw::c_char, pName: *const ::std::os::raw::c_char,
) -> PFN_vkVoidFunction { ) -> PFN_vkVoidFunction {
let name = unsafe { CStr::from_ptr(pName) }; let name = unsafe { CStr::from_ptr(pName) };