diff --git a/vulkano/src/buffer/sys.rs b/vulkano/src/buffer/sys.rs index b8a1fbe0ca..b9f4259bab 100644 --- a/vulkano/src/buffer/sys.rs +++ b/vulkano/src/buffer/sys.rs @@ -182,6 +182,28 @@ impl UnsafeBuffer { Ok(Arc::new(buffer)) } + /// Creates a new `UnsafeBuffer` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::Buffer, + create_info: UnsafeBufferCreateInfo, + device: Arc, + ) -> Arc { + let UnsafeBufferCreateInfo { size, usage, .. } = create_info; + + Arc::new(UnsafeBuffer { + handle, + device, + + size, + usage, + + state: Mutex::new(BufferState::new(size)), + }) + } + /// Returns the memory requirements for this buffer. pub fn memory_requirements(&self) -> MemoryRequirements { #[inline] diff --git a/vulkano/src/command_buffer/pool/sys.rs b/vulkano/src/command_buffer/pool/sys.rs index a20b2fe657..214af72abd 100644 --- a/vulkano/src/command_buffer/pool/sys.rs +++ b/vulkano/src/command_buffer/pool/sys.rs @@ -72,6 +72,33 @@ impl UnsafeCommandPool { }) } + /// Creates a new `UnsafeCommandPool` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::CommandPool, + create_info: UnsafeCommandPoolCreateInfo, + device: Arc, + ) -> UnsafeCommandPool { + let UnsafeCommandPoolCreateInfo { + queue_family_index, + transient, + reset_command_buffer, + _ne: _, + } = create_info; + + UnsafeCommandPool { + handle, + device, + dummy_avoid_sync: PhantomData, + + queue_family_index, + transient, + reset_command_buffer, + } + } + fn validate( device: &Device, create_info: &mut UnsafeCommandPoolCreateInfo, diff --git a/vulkano/src/descriptor_set/layout.rs b/vulkano/src/descriptor_set/layout.rs index 2d4ad89554..eabb507740 100644 --- a/vulkano/src/descriptor_set/layout.rs +++ b/vulkano/src/descriptor_set/layout.rs @@ -65,6 +65,41 @@ impl DescriptorSetLayout { })) } + /// Creates a new `DescriptorSetLayout` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::DescriptorSetLayout, + create_info: DescriptorSetLayoutCreateInfo, + device: Arc, + ) -> Arc { + let DescriptorSetLayoutCreateInfo { + bindings, + push_descriptor, + _ne: _, + } = create_info; + + let mut descriptor_counts = HashMap::default(); + for (&binding_num, binding) in bindings.iter() { + if binding.descriptor_count != 0 { + *descriptor_counts + .entry(binding.descriptor_type) + .or_default() += binding.descriptor_count; + } + } + + Arc::new(DescriptorSetLayout { + handle, + device, + + bindings, + push_descriptor, + + descriptor_counts, + }) + } + fn validate( device: &Device, create_info: &mut DescriptorSetLayoutCreateInfo, diff --git a/vulkano/src/descriptor_set/pool/sys.rs b/vulkano/src/descriptor_set/pool/sys.rs index 07aa452e1c..cc7c30ec4d 100644 --- a/vulkano/src/descriptor_set/pool/sys.rs +++ b/vulkano/src/descriptor_set/pool/sys.rs @@ -116,6 +116,32 @@ impl UnsafeDescriptorPool { }) } + /// Creates a new `UnsafeDescriptorPool` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::DescriptorPool, + create_info: UnsafeDescriptorPoolCreateInfo, + device: Arc, + ) -> UnsafeDescriptorPool { + let UnsafeDescriptorPoolCreateInfo { + max_sets, + pool_sizes, + can_free_descriptor_sets, + _ne: _, + } = create_info; + + UnsafeDescriptorPool { + handle, + device, + + max_sets, + pool_sizes, + can_free_descriptor_sets, + } + } + /// Returns the maximum number of sets that can be allocated from the pool. #[inline] pub fn max_sets(&self) -> u32 { diff --git a/vulkano/src/image/sys.rs b/vulkano/src/image/sys.rs index a31db78609..5e80dd6148 100644 --- a/vulkano/src/image/sys.rs +++ b/vulkano/src/image/sys.rs @@ -105,9 +105,21 @@ impl UnsafeImage { device: Arc, mut create_info: UnsafeImageCreateInfo, ) -> Result, ImageCreationError> { - let format_features = Self::validate(&device, &mut create_info)?; + Self::validate(&device, &mut create_info)?; let handle = unsafe { Self::create(&device, &create_info)? }; + unsafe { Ok(UnsafeImage::from_handle(handle, create_info, device)) } + } + + /// Creates a new `UnsafeImage` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::Image, + create_info: UnsafeImageCreateInfo, + device: Arc, + ) -> Arc { let UnsafeImageCreateInfo { dimensions, format, @@ -125,13 +137,21 @@ impl UnsafeImage { _ne: _, } = create_info; + // Get format features + let format_features = { + let format_properties = device.physical_device().format_properties(format.unwrap()); + match tiling { + ImageTiling::Linear => format_properties.linear_tiling_features, + ImageTiling::Optimal => format_properties.optimal_tiling_features, + } + }; let aspects = format.unwrap().aspects(); let aspect_list: SmallVec<[ImageAspect; 4]> = aspects.iter().collect(); let mip_level_size = dimensions.array_layers() as DeviceSize; let aspect_size = mip_level_size * mip_levels as DeviceSize; let range_size = aspect_list.len() as DeviceSize * aspect_size; - let image = UnsafeImage { + Arc::new(UnsafeImage { device, handle, @@ -154,9 +174,7 @@ impl UnsafeImage { needs_destruction: true, range_size, state: Mutex::new(ImageState::new(range_size, initial_layout)), - }; - - Ok(Arc::new(image)) + }) } fn validate( diff --git a/vulkano/src/pipeline/layout.rs b/vulkano/src/pipeline/layout.rs index 4c1bcd42a3..aed626d022 100644 --- a/vulkano/src/pipeline/layout.rs +++ b/vulkano/src/pipeline/layout.rs @@ -123,7 +123,21 @@ impl PipelineLayout { ) }); - // Create a list of disjoint ranges. + let push_constant_ranges_disjoint = + Self::create_push_constant_ranges_disjoint(&push_constant_ranges); + + Ok(Arc::new(PipelineLayout { + handle, + device, + set_layouts, + push_constant_ranges, + push_constant_ranges_disjoint, + })) + } + + fn create_push_constant_ranges_disjoint( + push_constant_ranges: &Vec, + ) -> Vec { let mut push_constant_ranges_disjoint: Vec = Vec::with_capacity(push_constant_ranges.len()); @@ -159,14 +173,34 @@ impl PipelineLayout { min_offset = max_offset; } } + push_constant_ranges_disjoint + } - Ok(Arc::new(PipelineLayout { + /// Creates a new `PipelineLayout` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::PipelineLayout, + create_info: PipelineLayoutCreateInfo, + device: Arc, + ) -> Arc { + let PipelineLayoutCreateInfo { + set_layouts, + push_constant_ranges, + _ne: _, + } = create_info; + + let push_constant_ranges_disjoint = + Self::create_push_constant_ranges_disjoint(&push_constant_ranges); + + Arc::new(PipelineLayout { handle, device, set_layouts, push_constant_ranges, push_constant_ranges_disjoint, - })) + }) } fn validate( diff --git a/vulkano/src/query.rs b/vulkano/src/query.rs index a8f84a1a6c..8aa87e8324 100644 --- a/vulkano/src/query.rs +++ b/vulkano/src/query.rs @@ -102,6 +102,28 @@ impl QueryPool { })) } + /// Creates a new `QueryPool` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::QueryPool, + create_info: QueryPoolCreateInfo, + device: Arc, + ) -> Arc { + let QueryPoolCreateInfo { + query_type, + query_count, + _ne: _, + } = create_info; + return Arc::new(QueryPool { + handle, + device, + query_type, + query_count, + }); + } + /// Returns the query type of the pool. #[inline] pub fn query_type(&self) -> QueryType { diff --git a/vulkano/src/render_pass/framebuffer.rs b/vulkano/src/render_pass/framebuffer.rs index 039ea4fb29..9bfeee3edf 100644 --- a/vulkano/src/render_pass/framebuffer.rs +++ b/vulkano/src/render_pass/framebuffer.rs @@ -328,6 +328,31 @@ impl Framebuffer { })) } + /// Creates a new `Framebuffer` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::Framebuffer, + create_info: FramebufferCreateInfo, + render_pass: Arc, + ) -> Arc { + let FramebufferCreateInfo { + attachments, + extent, + layers, + _ne: _, + } = create_info; + + Arc::new(Framebuffer { + handle, + render_pass, + + attachments, + extent, + layers, + }) + } /// Returns the renderpass that was used to create this framebuffer. #[inline] pub fn render_pass(&self) -> &Arc { diff --git a/vulkano/src/render_pass/mod.rs b/vulkano/src/render_pass/mod.rs index 8ad4cc55a2..a1496510c4 100644 --- a/vulkano/src/render_pass/mod.rs +++ b/vulkano/src/render_pass/mod.rs @@ -148,20 +148,58 @@ impl RenderPass { _ne: _, } = create_info; - let granularity = unsafe { - let fns = device.fns(); - let mut out = MaybeUninit::uninit(); - (fns.v1_0.get_render_area_granularity)( - device.internal_object(), - handle, - out.as_mut_ptr(), - ); - - let out = out.assume_init(); - debug_assert_ne!(out.width, 0); - debug_assert_ne!(out.height, 0); - [out.width, out.height] - }; + let granularity = unsafe { Self::get_granularity(&device, handle) }; + + Ok(Arc::new(RenderPass { + handle, + device, + + attachments, + subpasses, + dependencies, + correlated_view_masks, + + granularity, + views_used, + })) + } + + unsafe fn get_granularity(device: &Arc, handle: ash::vk::RenderPass) -> [u32; 2] { + let fns = device.fns(); + let mut out = MaybeUninit::uninit(); + (fns.v1_0.get_render_area_granularity)(device.internal_object(), handle, out.as_mut_ptr()); + + let out = out.assume_init(); + debug_assert_ne!(out.width, 0); + debug_assert_ne!(out.height, 0); + [out.width, out.height] + } + + /// Creates a new `RenderPass` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::RenderPass, + create_info: RenderPassCreateInfo, + granularity: [u32; 2], + device: Arc, + ) -> Result, RenderPassCreationError> { + let views_used = create_info + .subpasses + .iter() + .map(|subpass| u32::BITS - subpass.view_mask.leading_zeros()) + .max() + .unwrap(); + let granularity = Self::get_granularity(&device, handle); + + let RenderPassCreateInfo { + attachments, + subpasses, + dependencies, + correlated_view_masks, + _ne: _, + } = create_info; Ok(Arc::new(RenderPass { handle, diff --git a/vulkano/src/sampler/mod.rs b/vulkano/src/sampler/mod.rs index 1bd0632e92..63ffeebf76 100644 --- a/vulkano/src/sampler/mod.rs +++ b/vulkano/src/sampler/mod.rs @@ -424,6 +424,53 @@ impl Sampler { })) } + /// Creates a new `Sampler` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::Sampler, + create_info: SamplerCreateInfo, + device: Arc, + ) -> Arc { + let SamplerCreateInfo { + mag_filter, + min_filter, + mipmap_mode, + address_mode, + mip_lod_bias, + anisotropy, + compare, + lod, + border_color, + unnormalized_coordinates, + reduction_mode, + sampler_ycbcr_conversion, + _ne: _, + } = create_info; + + Arc::new(Sampler { + handle, + device, + + address_mode, + anisotropy, + border_color: address_mode + .into_iter() + .any(|mode| mode == SamplerAddressMode::ClampToBorder) + .then(|| border_color), + compare, + lod, + mag_filter, + min_filter, + mip_lod_bias, + mipmap_mode, + reduction_mode, + sampler_ycbcr_conversion, + unnormalized_coordinates, + }) + } + /// Checks whether this sampler is compatible with `image_view`. pub fn check_can_sample( &self, diff --git a/vulkano/src/sampler/ycbcr.rs b/vulkano/src/sampler/ycbcr.rs index 2031536b0b..94005fd09b 100644 --- a/vulkano/src/sampler/ycbcr.rs +++ b/vulkano/src/sampler/ycbcr.rs @@ -316,6 +316,39 @@ impl SamplerYcbcrConversion { })) } + /// Creates a new `SamplerYcbcrConversion` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + /// `create_info.format` must be some -- see `SamplerYcbcrConversion`::new` + pub unsafe fn from_handle( + handle: ash::vk::SamplerYcbcrConversion, + create_info: SamplerYcbcrConversionCreateInfo, + device: Arc, + ) -> Arc { + let SamplerYcbcrConversionCreateInfo { + format, + ycbcr_model, + ycbcr_range, + component_mapping, + chroma_offset, + chroma_filter, + force_explicit_reconstruction, + _ne: _, + } = create_info; + Arc::new(SamplerYcbcrConversion { + handle, + device, + format, + ycbcr_model, + ycbcr_range, + component_mapping, + chroma_offset, + chroma_filter, + force_explicit_reconstruction, + }) + } + /// Returns the chroma filter used by the conversion. #[inline] pub fn chroma_filter(&self) -> Filter { diff --git a/vulkano/src/sync/event.rs b/vulkano/src/sync/event.rs index 09eb25bdd9..7db814607f 100644 --- a/vulkano/src/sync/event.rs +++ b/vulkano/src/sync/event.rs @@ -91,6 +91,22 @@ impl Event { Ok(event) } + /// Creates a new `Event` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::Event, + create_info: EventCreateInfo, + device: Arc, + ) -> Event { + Event { + device, + handle, + must_put_in_pool: false, + } + } + /// Returns true if the event is signaled. #[inline] pub fn signaled(&self) -> Result { diff --git a/vulkano/src/sync/fence.rs b/vulkano/src/sync/fence.rs index e477c45718..9d83d33c25 100644 --- a/vulkano/src/sync/fence.rs +++ b/vulkano/src/sync/fence.rs @@ -119,6 +119,25 @@ impl Fence { Ok(fence) } + /// Creates a new `Fence` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::Fence, + create_info: FenceCreateInfo, + device: Arc, + ) -> Fence { + let FenceCreateInfo { signaled, _ne: _ } = create_info; + + Fence { + handle, + device, + is_signaled: AtomicBool::new(signaled), + must_put_in_pool: false, + } + } + /// Returns true if the fence is signaled. #[inline] pub fn is_signaled(&self) -> Result { diff --git a/vulkano/src/sync/semaphore.rs b/vulkano/src/sync/semaphore.rs index b8749a2c8c..0be9048c6a 100644 --- a/vulkano/src/sync/semaphore.rs +++ b/vulkano/src/sync/semaphore.rs @@ -140,6 +140,29 @@ impl Semaphore { Ok(semaphore) } + /// Creates a new `Semaphore` from an ash-handle + /// # Safety + /// The `handle` has to be a valid vulkan object handle and + /// the `create_info` must match the info used to create said object + pub unsafe fn from_handle( + handle: ash::vk::Semaphore, + create_info: SemaphoreCreateInfo, + device: Arc, + ) -> Semaphore { + let SemaphoreCreateInfo { + export_handle_types, + _ne: _, + } = create_info; + + Semaphore { + device, + handle, + must_put_in_pool: false, + + export_handle_types, + } + } + /// # Safety /// /// - The semaphore must not be used, or have been used, to acquire a swapchain image.