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 std::{borrow, fmt, ops};
use std::{borrow, cmp, fmt, ops};
#[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> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Handle({:p})", self.0)
@ -65,7 +71,7 @@ pub type DispatchHandle<T> = Handle<T>;
#[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<T> cmp::PartialEq for DispatchHandle<T> {
fn eq(&self, other: &Self) -> bool {
self.0.eq(&other.0)
}
}
impl<T> fmt::Debug for DispatchHandle<T> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "DispatchHandle({:p})", self.0)

View file

@ -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(

View file

@ -42,7 +42,7 @@ pub struct RawInstance {
pub type VkInstance = Handle<RawInstance>;
pub type VkDevice = DispatchHandle<Gpu<B>>;
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 VkDeviceMemory = Handle<<B as hal::Backend>::Memory>;
pub type VkDescriptorSetLayout = Handle<<B as hal::Backend>::DescriptorSetLayout>;
@ -83,6 +83,11 @@ pub enum Buffer<B: hal::Backend> {
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
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;

View file

@ -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) };