From ce20e416296fe55fd200c68610c9b2a0f5755abc Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Wed, 24 Feb 2016 17:32:06 +0100 Subject: [PATCH] Fix thread safety issues --- vulkano/examples/image.rs | 13 ++++----- vulkano/examples/teapot.rs | 12 ++++----- vulkano/src/buffer.rs | 4 +-- vulkano/src/command_buffer/inner.rs | 18 ++++++++----- vulkano/src/command_buffer/outer.rs | 2 +- vulkano/src/command_buffer/pool.rs | 16 ++++++----- vulkano/src/descriptor_set/pool.rs | 16 ++++++----- vulkano/src/descriptor_set/vk_objects.rs | 7 +++-- vulkano/src/device.rs | 23 +++++++++------- vulkano/src/image.rs | 17 +++++++----- vulkano/src/lib.rs | 10 +++++++ vulkano/src/memory/mod.rs | 2 +- vulkano/src/memory/single.rs | 4 +-- vulkano/src/pipeline/cache.rs | 1 + vulkano/src/swapchain/swapchain.rs | 7 ++--- vulkano/src/sync.rs | 34 +++++++++++++----------- 16 files changed, 109 insertions(+), 77 deletions(-) diff --git a/vulkano/examples/image.rs b/vulkano/examples/image.rs index e506ded0..93e73bcf 100644 --- a/vulkano/examples/image.rs +++ b/vulkano/examples/image.rs @@ -52,7 +52,7 @@ fn main() { }; - let cb_pool = vulkano::command_buffer::CommandBufferPool::new(&device, &queue.lock().unwrap().family()) + let cb_pool = vulkano::command_buffer::CommandBufferPool::new(&device, &queue.family()) .expect("failed to create command buffer pool"); @@ -103,7 +103,7 @@ fn main() { let texture = vulkano::image::Image::::new(&device, &vulkano::image::Usage::all(), vulkano::memory::DeviceLocal, &queue, vulkano::formats::R8G8B8A8Unorm, [93, 93], (), 1).unwrap(); - let texture = texture.transition(vulkano::image::Layout::ShaderReadOnlyOptimal, &cb_pool, &mut queue.lock().unwrap()).unwrap(); + let texture = texture.transition(vulkano::image::Layout::ShaderReadOnlyOptimal, &cb_pool, &queue).unwrap(); let texture_view = vulkano::image::ImageView::new(&texture).expect("failed to create image view"); @@ -160,8 +160,7 @@ fn main() { let images = images.into_iter().map(|image| { - let image = image.transition(vulkano::image::Layout::PresentSrc, &cb_pool, - &mut queue.lock().unwrap()).unwrap(); + let image = image.transition(vulkano::image::Layout::PresentSrc, &cb_pool, &queue).unwrap(); vulkano::image::ImageView::new(&image).expect("failed to create image view") }).collect::>(); @@ -215,10 +214,8 @@ fn main() { loop { let image_num = swapchain.acquire_next_image(1000000).unwrap(); - let mut queue = queue.lock().unwrap(); - command_buffers[image_num].submit(&mut queue).unwrap(); - swapchain.present(&mut queue, image_num).unwrap(); - drop(queue); + command_buffers[image_num].submit(&queue).unwrap(); + swapchain.present(&queue, image_num).unwrap(); for ev in window.poll_events() { match ev { diff --git a/vulkano/examples/teapot.rs b/vulkano/examples/teapot.rs index 5d2f1bd9..21151382 100644 --- a/vulkano/examples/teapot.rs +++ b/vulkano/examples/teapot.rs @@ -54,14 +54,14 @@ fn main() { }; - let cb_pool = vulkano::command_buffer::CommandBufferPool::new(&device, &queue.lock().unwrap().family()) + let cb_pool = vulkano::command_buffer::CommandBufferPool::new(&device, &queue.family()) .expect("failed to create command buffer pool"); let depth_buffer = vulkano::image::Image::::new(&device, &vulkano::image::Usage::all(), vulkano::memory::DeviceLocal, &queue, vulkano::formats::D16Unorm, images[0].dimensions(), (), 1).unwrap(); - let depth_buffer = depth_buffer.transition(vulkano::image::Layout::DepthStencilAttachmentOptimal, &cb_pool, &mut queue.lock().unwrap()).unwrap(); + let depth_buffer = depth_buffer.transition(vulkano::image::Layout::DepthStencilAttachmentOptimal, &cb_pool, &queue).unwrap(); let depth_buffer = vulkano::image::ImageView::new(&depth_buffer).expect("failed to create image view"); let vertex_buffer = vulkano::buffer::Buffer::<[teapot::Vertex], _> @@ -126,7 +126,7 @@ fn main() { let images = images.into_iter().map(|image| { let image = image.transition(vulkano::image::Layout::PresentSrc, &cb_pool, - &mut queue.lock().unwrap()).unwrap(); + &queue).unwrap(); vulkano::image::ImageView::new(&image).expect("failed to create image view") }).collect::>(); @@ -219,10 +219,8 @@ fn main() { loop { let image_num = swapchain.acquire_next_image(1000000).unwrap(); - let mut queue = queue.lock().unwrap(); - command_buffers[image_num].submit(&mut queue).unwrap(); - swapchain.present(&mut queue, image_num).unwrap(); - drop(queue); + command_buffers[image_num].submit(&queue).unwrap(); + swapchain.present(&queue, image_num).unwrap(); for ev in window.poll_events() { match ev { diff --git a/vulkano/src/buffer.rs b/vulkano/src/buffer.rs index 55fd781b..518d09a4 100644 --- a/vulkano/src/buffer.rs +++ b/vulkano/src/buffer.rs @@ -63,7 +63,7 @@ pub unsafe trait AbstractBuffer: Resource + ::VulkanObjectU64 { /// /// The function can return a semaphore which will be waited up by the GPU before the /// work starts. - unsafe fn gpu_access(&self, write: bool, offset: usize, size: usize, queue: &mut Queue, + unsafe fn gpu_access(&self, write: bool, offset: usize, size: usize, queue: &Arc, fence: Option>, semaphore: Option>) -> Option>; @@ -246,7 +246,7 @@ unsafe impl AbstractBuffer for Buffer where M: MemorySourceC } #[inline] - unsafe fn gpu_access(&self, write: bool, offset: usize, size: usize, queue: &mut Queue, + unsafe fn gpu_access(&self, write: bool, offset: usize, size: usize, queue: &Arc, fence: Option>, semaphore: Option>) -> Option> { diff --git a/vulkano/src/command_buffer/inner.rs b/vulkano/src/command_buffer/inner.rs index 66314e0f..575817c4 100644 --- a/vulkano/src/command_buffer/inner.rs +++ b/vulkano/src/command_buffer/inner.rs @@ -31,6 +31,7 @@ use sync::Semaphore; use device::Device; use OomError; +use SynchronizedVulkanObject; use VulkanObject; use VulkanPointers; use check_errors; @@ -75,10 +76,12 @@ impl InnerCommandBufferBuilder { let vk = device.pointers(); let cmd = unsafe { + let pool = pool.internal_object_guard(); + let infos = vk::CommandBufferAllocateInfo { sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, pNext: ptr::null(), - commandPool: pool.internal_object(), + commandPool: *pool, level: if secondary { vk::COMMAND_BUFFER_LEVEL_SECONDARY } else { @@ -608,8 +611,9 @@ impl Drop for InnerCommandBufferBuilder { unsafe { let vk = self.device.pointers(); vk.EndCommandBuffer(cmd); - vk.FreeCommandBuffers(self.device.internal_object(), self.pool.internal_object(), - 1, &cmd); + + let pool = self.pool.internal_object_guard(); + vk.FreeCommandBuffers(self.device.internal_object(), *pool, 1, &cmd); } } } @@ -635,7 +639,7 @@ impl InnerCommandBuffer { /// - Panicks if the queue doesn't belong to the device this command buffer was created with. /// - Panicks if the queue doesn't belong to the family the pool was created with. /// - pub fn submit(&self, queue: &mut Queue) -> Result<(), OomError> { // TODO: wrong error type + pub fn submit(&self, queue: &Arc) -> Result<(), OomError> { // TODO: wrong error type // FIXME: the whole function should be checked let vk = self.device.pointers(); @@ -723,7 +727,7 @@ impl InnerCommandBuffer { unsafe { let fence = if let Some(ref fence) = fence { fence.internal_object() } else { 0 }; - try!(check_errors(vk.QueueSubmit(queue.internal_object(), 1, &infos, fence))); + try!(check_errors(vk.QueueSubmit(*queue.internal_object_guard(), 1, &infos, fence))); } // FIXME: the return value shouldn't be () because the command buffer @@ -743,8 +747,8 @@ impl Drop for InnerCommandBuffer { fn drop(&mut self) { unsafe { let vk = self.device.pointers(); - vk.FreeCommandBuffers(self.device.internal_object(), self.pool.internal_object(), - 1, &self.cmd); + let pool = self.pool.internal_object_guard(); + vk.FreeCommandBuffers(self.device.internal_object(), *pool, 1, &self.cmd); } } } diff --git a/vulkano/src/command_buffer/outer.rs b/vulkano/src/command_buffer/outer.rs index ff36e10f..69c72ea4 100644 --- a/vulkano/src/command_buffer/outer.rs +++ b/vulkano/src/command_buffer/outer.rs @@ -437,7 +437,7 @@ impl PrimaryCommandBuffer { /// - Panicks if the queue doesn't belong to the family the pool was created with. /// #[inline] - pub fn submit(&self, queue: &mut Queue) -> Result<(), OomError> { // TODO: wrong error type + pub fn submit(&self, queue: &Arc) -> Result<(), OomError> { // TODO: wrong error type self.inner.submit(queue) } } diff --git a/vulkano/src/command_buffer/pool.rs b/vulkano/src/command_buffer/pool.rs index 0c12c920..63b74de4 100644 --- a/vulkano/src/command_buffer/pool.rs +++ b/vulkano/src/command_buffer/pool.rs @@ -1,11 +1,14 @@ use std::mem; use std::ptr; use std::sync::Arc; +use std::sync::Mutex; +use std::sync::MutexGuard; use instance::QueueFamily; use device::Device; use OomError; +use SynchronizedVulkanObject; use VulkanObject; use VulkanPointers; use check_errors; @@ -13,8 +16,8 @@ use vk; /// A pool from which command buffers are created from. pub struct CommandBufferPool { + pool: Mutex, device: Arc, - pool: vk::CommandPool, queue_family_index: u32, } @@ -52,8 +55,8 @@ impl CommandBufferPool { }; Ok(Arc::new(CommandBufferPool { + pool: Mutex::new(pool), device: device.clone(), - pool: pool, queue_family_index: queue_family.id(), })) } @@ -71,12 +74,12 @@ impl CommandBufferPool { } } -unsafe impl VulkanObject for CommandBufferPool { +unsafe impl SynchronizedVulkanObject for CommandBufferPool { type Object = vk::CommandPool; #[inline] - fn internal_object(&self) -> vk::CommandPool { - self.pool + fn internal_object_guard(&self) -> MutexGuard { + self.pool.lock().unwrap() } } @@ -85,7 +88,8 @@ impl Drop for CommandBufferPool { fn drop(&mut self) { unsafe { let vk = self.device.pointers(); - vk.DestroyCommandPool(self.device.internal_object(), self.pool, ptr::null()); + let pool = self.pool.lock().unwrap(); + vk.DestroyCommandPool(self.device.internal_object(), *pool, ptr::null()); } } } diff --git a/vulkano/src/descriptor_set/pool.rs b/vulkano/src/descriptor_set/pool.rs index ebb089ca..de5fbb29 100644 --- a/vulkano/src/descriptor_set/pool.rs +++ b/vulkano/src/descriptor_set/pool.rs @@ -1,10 +1,13 @@ use std::mem; use std::ptr; use std::sync::Arc; +use std::sync::Mutex; +use std::sync::MutexGuard; use device::Device; use OomError; +use SynchronizedVulkanObject; use VulkanObject; use VulkanPointers; use check_errors; @@ -15,7 +18,7 @@ use vk; /// A pool has a maximum number of descriptor sets and a maximum number of descriptors (one value /// per descriptor type) it can allocate. pub struct DescriptorPool { - pool: vk::DescriptorPool, + pool: Mutex, device: Arc, } @@ -50,7 +53,7 @@ impl DescriptorPool { }; Ok(Arc::new(DescriptorPool { - pool: pool, + pool: Mutex::new(pool), device: device.clone(), })) } @@ -62,12 +65,12 @@ impl DescriptorPool { } } -unsafe impl VulkanObject for DescriptorPool { +unsafe impl SynchronizedVulkanObject for DescriptorPool { type Object = vk::DescriptorPool; #[inline] - fn internal_object(&self) -> vk::DescriptorPool { - self.pool + fn internal_object_guard(&self) -> MutexGuard { + self.pool.lock().unwrap() } } @@ -76,7 +79,8 @@ impl Drop for DescriptorPool { fn drop(&mut self) { unsafe { let vk = self.device.pointers(); - vk.DestroyDescriptorPool(self.device.internal_object(), self.pool, ptr::null()); + let pool = self.pool.lock().unwrap(); + vk.DestroyDescriptorPool(self.device.internal_object(), *pool, ptr::null()); } } } diff --git a/vulkano/src/descriptor_set/vk_objects.rs b/vulkano/src/descriptor_set/vk_objects.rs index 570d6e17..b76b61c2 100644 --- a/vulkano/src/descriptor_set/vk_objects.rs +++ b/vulkano/src/descriptor_set/vk_objects.rs @@ -13,6 +13,7 @@ use image::AbstractImageView; use sampler::Sampler; use OomError; +use SynchronizedVulkanObject; use VulkanObject; use VulkanPointers; use check_errors; @@ -61,10 +62,12 @@ impl DescriptorSet where S: DescriptorSetDesc { let vk = pool.device().pointers(); let set = { + let pool_obj = pool.internal_object_guard(); + let infos = vk::DescriptorSetAllocateInfo { sType: vk::STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, pNext: ptr::null(), - descriptorPool: pool.internal_object(), + descriptorPool: *pool_obj, descriptorSetCount: 1, pSetLayouts: &layout.layout, }; @@ -252,7 +255,7 @@ impl Drop for DescriptorSet { unsafe { let vk = self.pool.device().pointers(); vk.FreeDescriptorSets(self.pool.device().internal_object(), - self.pool.internal_object(), 1, &self.set); + *self.pool.internal_object_guard(), 1, &self.set); } } } diff --git a/vulkano/src/device.rs b/vulkano/src/device.rs index bc80f2d3..126b548a 100644 --- a/vulkano/src/device.rs +++ b/vulkano/src/device.rs @@ -10,6 +10,7 @@ use std::mem; use std::ptr; use std::sync::Arc; use std::sync::Mutex; +use std::sync::MutexGuard; use instance::Features; use instance::Instance; @@ -18,6 +19,7 @@ use instance::QueueFamily; use Error; use OomError; +use SynchronizedVulkanObject; use VulkanObject; use VulkanPointers; use check_errors; @@ -57,7 +59,7 @@ impl Device { // TODO: return Arc and handle synchronization in the Queue pub fn new<'a, I, L>(phys: &'a PhysicalDevice, requested_features: &Features, queue_families: I, layers: L) - -> Result<(Arc, Vec>>), DeviceCreationError> + -> Result<(Arc, Vec>), DeviceCreationError> where I: IntoIterator, f32)>, L: IntoIterator { @@ -163,12 +165,12 @@ impl Device { unsafe { let mut output = mem::uninitialized(); device.vk.GetDeviceQueue(device.device, family, id, &mut output); - Arc::new(Mutex::new(Queue { + Arc::new(Queue { + queue: Mutex::new(output), device: device.clone(), - queue: output, family: family, id: id, - })) + }) } }).collect(); @@ -276,8 +278,8 @@ impl From for DeviceCreationError { /// Represents a queue where commands can be submitted. // TODO: should use internal synchronization pub struct Queue { + queue: Mutex, device: Arc, - queue: vk::Queue, family: u32, id: u32, // id within family } @@ -299,20 +301,21 @@ impl Queue { /// /// Just like `Device::wait()`, you shouldn't have to call this function. #[inline] - pub fn wait(&mut self) -> Result<(), OomError> { + pub fn wait(&self) -> Result<(), OomError> { unsafe { let vk = self.device.pointers(); - try!(check_errors(vk.QueueWaitIdle(self.queue))); + let queue = self.queue.lock().unwrap(); + try!(check_errors(vk.QueueWaitIdle(*queue))); Ok(()) } } } -unsafe impl VulkanObject for Queue { +unsafe impl SynchronizedVulkanObject for Queue { type Object = vk::Queue; #[inline] - fn internal_object(&self) -> vk::Queue { - self.queue + fn internal_object_guard(&self) -> MutexGuard { + self.queue.lock().unwrap() } } diff --git a/vulkano/src/image.rs b/vulkano/src/image.rs index 65612ca7..cb936e26 100644 --- a/vulkano/src/image.rs +++ b/vulkano/src/image.rs @@ -33,6 +33,7 @@ use sync::Semaphore; use sync::SharingMode; use OomError; +use SynchronizedVulkanObject; use VulkanObject; use VulkanPointers; use check_errors; @@ -64,14 +65,14 @@ pub unsafe trait AbstractImage: Resource + ::VulkanObjectU64 { /// /// The function can return a semaphore which will be waited up by the GPU before the /// work starts. - unsafe fn gpu_access(&self, write: bool, queue: &mut Queue, fence: Option>, + unsafe fn gpu_access(&self, write: bool, queue: &Arc, fence: Option>, semaphore: Option>) -> Option>; } pub unsafe trait AbstractImageView: Resource + ::VulkanObjectU64 { fn default_layout(&self) -> Layout; - unsafe fn gpu_access(&self, write: bool, queue: &mut Queue, fence: Option>, + unsafe fn gpu_access(&self, write: bool, queue: &Arc, fence: Option>, semaphore: Option>) -> Option>; /// True if the image can be used as a source for transfers. @@ -441,7 +442,7 @@ unsafe impl AbstractImage for Image } #[inline] - unsafe fn gpu_access(&self, write: bool, queue: &mut Queue, fence: Option>, + unsafe fn gpu_access(&self, write: bool, queue: &Arc, fence: Option>, semaphore: Option>) -> Option> { // FIXME: if the image is in its initial transition phase, we need to a semaphore @@ -507,7 +508,7 @@ impl ImagePrototype /// /// - Panicks if `layout` is `Undefined` or `Preinitialized`. // FIXME: PresentSrc is only allowed for swapchain images - pub fn transition(self, layout: Layout, pool: &CommandBufferPool, submit_queue: &mut Queue) + pub fn transition(self, layout: Layout, pool: &CommandBufferPool, submit_queue: &Arc) -> Result>, OomError> // FIXME: error type { // FIXME: check pool and submit queue correspondance @@ -524,10 +525,12 @@ impl ImagePrototype unsafe { let cmd = { + let pool = pool.internal_object_guard(); + let infos = vk::CommandBufferAllocateInfo { sType: vk::STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, pNext: ptr::null(), - commandPool: pool.internal_object(), + commandPool: *pool, level: vk::COMMAND_BUFFER_LEVEL_SECONDARY, commandBufferCount: 1, }; @@ -588,7 +591,7 @@ impl ImagePrototype pSignalSemaphores: ptr::null(), // TODO: }; - try!(check_errors(vk.QueueSubmit(submit_queue.internal_object(), 1, &infos, 0))); + try!(check_errors(vk.QueueSubmit(*submit_queue.internal_object_guard(), 1, &infos, 0))); } } @@ -769,7 +772,7 @@ unsafe impl AbstractImageView for ImageView } #[inline] - unsafe fn gpu_access(&self, write: bool, queue: &mut Queue, fence: Option>, + unsafe fn gpu_access(&self, write: bool, queue: &Arc, fence: Option>, semaphore: Option>) -> Option> { self.image.gpu_access(write, queue, fence, semaphore) diff --git a/vulkano/src/lib.rs b/vulkano/src/lib.rs index e1b7b744..fe787b67 100644 --- a/vulkano/src/lib.rs +++ b/vulkano/src/lib.rs @@ -67,6 +67,7 @@ use std::error; use std::fmt; use std::mem; use std::path::Path; +use std::sync::MutexGuard; mod vk { #![allow(dead_code)] @@ -106,6 +107,15 @@ pub unsafe trait VulkanObject { fn internal_object(&self) -> Self::Object; } +/// Gives access to the internal identifier of an object. +pub unsafe trait SynchronizedVulkanObject { + /// The type of the object. + type Object; + + /// Returns a reference to the object. + fn internal_object_guard(&self) -> MutexGuard; +} + // TODO: remove eventually // https://github.com/rust-lang/rust/issues/29328 pub unsafe trait VulkanObjectU64 { fn internal_object(&self) -> u64; } diff --git a/vulkano/src/memory/mod.rs b/vulkano/src/memory/mod.rs index 8dae56e3..94707e10 100644 --- a/vulkano/src/memory/mod.rs +++ b/vulkano/src/memory/mod.rs @@ -159,7 +159,7 @@ pub unsafe trait MemorySourceChunk { /// return a semaphore that must be waited upon by the GPU before the access can start. The /// semaphore being returned is usually one that has been previously passed to this function, /// but it doesn't need to be the case. - unsafe fn gpu_access(&self, write: bool, range: ChunkRange, queue: &mut Queue, + unsafe fn gpu_access(&self, write: bool, range: ChunkRange, queue: &Arc, fence: Option>, semaphore: Option>) -> Option>; diff --git a/vulkano/src/memory/single.rs b/vulkano/src/memory/single.rs index 6c3f82ae..beca1493 100644 --- a/vulkano/src/memory/single.rs +++ b/vulkano/src/memory/single.rs @@ -72,7 +72,7 @@ pub struct DeviceLocalChunk { unsafe impl MemorySourceChunk for DeviceLocalChunk { #[inline] - unsafe fn gpu_access(&self, _write: bool, _range: ChunkRange, _: &mut Queue, + unsafe fn gpu_access(&self, _write: bool, _range: ChunkRange, _: &Arc, _: Option>, mut semaphore: Option>) -> Option> { @@ -153,7 +153,7 @@ pub struct HostVisibleChunk { unsafe impl MemorySourceChunk for HostVisibleChunk { #[inline] - unsafe fn gpu_access(&self, _write: bool, _range: ChunkRange, _: &mut Queue, + unsafe fn gpu_access(&self, _write: bool, _range: ChunkRange, _: &Arc, fence: Option>, mut semaphore: Option>) -> Option> { diff --git a/vulkano/src/pipeline/cache.rs b/vulkano/src/pipeline/cache.rs index d97c218f..ff108296 100644 --- a/vulkano/src/pipeline/cache.rs +++ b/vulkano/src/pipeline/cache.rs @@ -76,6 +76,7 @@ impl PipelineCache { /// /// - Panicks if `self` is included in the list of other pipelines. /// + // FIXME: vkMergePipelineCaches is not thread safe for the destination cache pub fn merge<'a, I>(&self, pipelines: I) -> Result<(), OomError> where I: IntoIterator> { diff --git a/vulkano/src/swapchain/swapchain.rs b/vulkano/src/swapchain/swapchain.rs index da6ca42d..05be232c 100644 --- a/vulkano/src/swapchain/swapchain.rs +++ b/vulkano/src/swapchain/swapchain.rs @@ -27,6 +27,7 @@ use check_errors; use Error; use OomError; use Success; +use SynchronizedVulkanObject; use VulkanObject; use VulkanPointers; use vk; @@ -202,7 +203,7 @@ impl Swapchain { /// /// The actual behavior depends on the present mode that you passed when creating the /// swapchain. - pub fn present(&self, queue: &mut Queue, index: usize) -> Result<(), OomError> { // FIXME: wrong error + pub fn present(&self, queue: &Arc, index: usize) -> Result<(), OomError> { // FIXME: wrong error let vk = self.device.pointers(); let wait_semaphore = { @@ -227,7 +228,7 @@ impl Swapchain { pResults: &mut result, }; - try!(check_errors(vk.QueuePresentKHR(queue.internal_object(), &infos))); + try!(check_errors(vk.QueuePresentKHR(*queue.internal_object_guard(), &infos))); try!(check_errors(result)); Ok(()) } @@ -303,7 +304,7 @@ unsafe impl MemorySourceChunk for SwapchainAllocatedChunk { fn may_alias(&self) -> bool { false } #[inline] - unsafe fn gpu_access(&self, _: bool, _: ChunkRange, _: &mut Queue, _: Option>, + unsafe fn gpu_access(&self, _: bool, _: ChunkRange, _: &Arc, _: Option>, post_semaphore: Option>) -> Option> { assert!(post_semaphore.is_some()); diff --git a/vulkano/src/sync.rs b/vulkano/src/sync.rs index 864b368a..521d5d3d 100644 --- a/vulkano/src/sync.rs +++ b/vulkano/src/sync.rs @@ -13,11 +13,13 @@ use std::mem; use std::ptr; use std::sync::Arc; use std::sync::Mutex; +use std::sync::MutexGuard; use device::Device; use device::Queue; use OomError; use Success; +use SynchronizedVulkanObject; use VulkanObject; use VulkanPointers; use check_errors; @@ -54,19 +56,17 @@ pub enum SharingMode { Concurrent(Vec), // TODO: Vec is too expensive here } -impl<'a> From<&'a Arc>> for SharingMode { +impl<'a> From<&'a Arc> for SharingMode { #[inline] - fn from(queue: &'a Arc>) -> SharingMode { - let queue = queue.lock().unwrap(); // TODO: meh + fn from(queue: &'a Arc) -> SharingMode { SharingMode::Exclusive(queue.family().id()) } } -impl<'a> From<&'a [&'a Arc>]> for SharingMode { +impl<'a> From<&'a [&'a Arc]> for SharingMode { #[inline] - fn from(queues: &'a [&'a Arc>]) -> SharingMode { + fn from(queues: &'a [&'a Arc]) -> SharingMode { SharingMode::Concurrent(queues.iter().map(|queue| { - let queue = queue.lock().unwrap(); // TODO: meh queue.family().id() }).collect()) } @@ -270,7 +270,7 @@ impl Drop for Semaphore { /// device loss. pub struct Event { device: Arc, - event: vk::Event, + event: Mutex, } impl Event { @@ -295,7 +295,7 @@ impl Event { Ok(Arc::new(Event { device: device.clone(), - event: event, + event: Mutex::new(event), })) } @@ -304,8 +304,9 @@ impl Event { pub fn signaled(&self) -> Result { unsafe { let vk = self.device.pointers(); + let event = self.event.lock().unwrap(); let result = try!(check_errors(vk.GetEventStatus(self.device.internal_object(), - self.event))); + *event))); match result { Success::EventSet => Ok(true), Success::EventReset => Ok(false), @@ -321,7 +322,8 @@ impl Event { pub fn set(&self) -> Result<(), OomError> { unsafe { let vk = self.device.pointers(); - try!(check_errors(vk.SetEvent(self.device.internal_object(), self.event)).map(|_| ())); + let event = self.event.lock().unwrap(); + try!(check_errors(vk.SetEvent(self.device.internal_object(), *event)).map(|_| ())); Ok(()) } } @@ -331,18 +333,19 @@ impl Event { pub fn reset(&self) -> Result<(), OomError> { unsafe { let vk = self.device.pointers(); - try!(check_errors(vk.ResetEvent(self.device.internal_object(), self.event)).map(|_| ())); + let event = self.event.lock().unwrap(); + try!(check_errors(vk.ResetEvent(self.device.internal_object(), *event)).map(|_| ())); Ok(()) } } } -unsafe impl VulkanObject for Event { +unsafe impl SynchronizedVulkanObject for Event { type Object = vk::Event; #[inline] - fn internal_object(&self) -> vk::Event { - self.event + fn internal_object_guard(&self) -> MutexGuard { + self.event.lock().unwrap() } } @@ -351,7 +354,8 @@ impl Drop for Event { fn drop(&mut self) { unsafe { let vk = self.device.pointers(); - vk.DestroyEvent(self.device.internal_object(), self.event, ptr::null()); + let event = self.event.lock().unwrap(); + vk.DestroyEvent(self.device.internal_object(), *event, ptr::null()); } } }