Skip to content

Commit

Permalink
Add from_handle constructors for various Vulkan object types. #1935 (#…
Browse files Browse the repository at this point in the history
…1938)

* add from_handle to QueryPool

* add from_handle to Sampler

* add from_handle to Semaphore

* add from_handle to Fence

* add from_handle to Event

* add must_put_in_pool parameter to fence and semaphore

* add from_handle to SamplerYcbcrConversion

* add from_handle to RenderPass

* add from_handle to Framebuffer

* add from_handle to PipelineLayout

* cargo fmt

* remove must_put_in_pool flag from event, fence and semaphore because we don't want the user to add stuff to the pool via indirect means

* don't use validate method when creating RenderPass from_handle, instead determine views manually without validation

* add from_handle to UnsafeImage, adapted new() a bit to avoid duplicating logic of creation (at the cost of getting the format_features twice

* add from_handle to UnsafeDescriptorPool

* add from_handle to DescriptorSetLayout, duplicating logic from validate

* add from_handle to UnsafeCommandPool

* add from_handle to UnsafeBuffer

* cargo fmt

Co-authored-by: Peterix <git@kuelzer.me>
  • Loading branch information
p3t3rix and Peterix authored Jul 31, 2022
1 parent 847ab58 commit 4980ee4
Show file tree
Hide file tree
Showing 14 changed files with 407 additions and 22 deletions.
22 changes: 22 additions & 0 deletions vulkano/src/buffer/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Device>,
) -> Arc<UnsafeBuffer> {
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]
Expand Down
27 changes: 27 additions & 0 deletions vulkano/src/command_buffer/pool/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Device>,
) -> 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,
Expand Down
35 changes: 35 additions & 0 deletions vulkano/src/descriptor_set/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Device>,
) -> Arc<DescriptorSetLayout> {
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,
Expand Down
26 changes: 26 additions & 0 deletions vulkano/src/descriptor_set/pool/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Device>,
) -> 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 {
Expand Down
28 changes: 23 additions & 5 deletions vulkano/src/image/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,21 @@ impl UnsafeImage {
device: Arc<Device>,
mut create_info: UnsafeImageCreateInfo,
) -> Result<Arc<UnsafeImage>, 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<Device>,
) -> Arc<UnsafeImage> {
let UnsafeImageCreateInfo {
dimensions,
format,
Expand All @@ -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,

Expand All @@ -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(
Expand Down
40 changes: 37 additions & 3 deletions vulkano/src/pipeline/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<PushConstantRange>,
) -> Vec<PushConstantRange> {
let mut push_constant_ranges_disjoint: Vec<PushConstantRange> =
Vec::with_capacity(push_constant_ranges.len());

Expand Down Expand Up @@ -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<Device>,
) -> Arc<PipelineLayout> {
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(
Expand Down
22 changes: 22 additions & 0 deletions vulkano/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Device>,
) -> Arc<QueryPool> {
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 {
Expand Down
25 changes: 25 additions & 0 deletions vulkano/src/render_pass/framebuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<RenderPass>,
) -> Arc<Framebuffer> {
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<RenderPass> {
Expand Down
66 changes: 52 additions & 14 deletions vulkano/src/render_pass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Device>, 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<Device>,
) -> Result<Arc<RenderPass>, 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,
Expand Down
Loading

0 comments on commit 4980ee4

Please sign in to comment.