bort_vk/
pipeline_layout.rs

1use crate::{DescriptorSetLayout, Device, DeviceOwned, ALLOCATION_CALLBACK_NONE};
2use ash::{
3    prelude::VkResult,
4    vk::{self, Handle},
5};
6use std::sync::Arc;
7
8pub struct PipelineLayout {
9    handle: vk::PipelineLayout,
10    properties: PipelineLayoutProperties,
11
12    // dependencies
13    device: Arc<Device>,
14}
15
16impl PipelineLayout {
17    pub fn new(device: Arc<Device>, mut properties: PipelineLayoutProperties) -> VkResult<Self> {
18        let handle = unsafe {
19            device
20                .inner()
21                .create_pipeline_layout(&properties.create_info_builder(), ALLOCATION_CALLBACK_NONE)
22        }?;
23
24        Ok(Self {
25            handle,
26            properties,
27            device,
28        })
29    }
30
31    // Getters
32
33    pub fn handle(&self) -> vk::PipelineLayout {
34        self.handle
35    }
36
37    pub fn properties(&self) -> &PipelineLayoutProperties {
38        &self.properties
39    }
40}
41
42impl DeviceOwned for PipelineLayout {
43    #[inline]
44    fn device(&self) -> &Arc<Device> {
45        &self.device
46    }
47
48    #[inline]
49    fn handle_raw(&self) -> u64 {
50        self.handle.as_raw()
51    }
52}
53
54impl Drop for PipelineLayout {
55    fn drop(&mut self) {
56        unsafe {
57            self.device
58                .inner()
59                .destroy_pipeline_layout(self.handle, ALLOCATION_CALLBACK_NONE);
60        }
61    }
62}
63
64#[derive(Default, Clone)]
65pub struct PipelineLayoutProperties {
66    pub flags: vk::PipelineLayoutCreateFlags,
67    pub set_layouts: Vec<Arc<DescriptorSetLayout>>,
68    pub push_constant_ranges: Vec<vk::PushConstantRange>,
69    // because these need to be stored for the lifetime duration of self
70    set_layouts_vk: Vec<vk::DescriptorSetLayout>,
71}
72
73impl PipelineLayoutProperties {
74    pub fn new(
75        set_layouts: Vec<Arc<DescriptorSetLayout>>,
76        push_constant_ranges: Vec<vk::PushConstantRange>,
77    ) -> Self {
78        Self {
79            flags: vk::PipelineLayoutCreateFlags::empty(),
80            set_layouts,
81            push_constant_ranges,
82            set_layouts_vk: Vec::new(),
83        }
84    }
85
86    pub fn create_info_builder(&mut self) -> vk::PipelineLayoutCreateInfoBuilder {
87        self.set_layouts_vk = self
88            .set_layouts
89            .iter()
90            .map(|layout| layout.handle())
91            .collect();
92
93        vk::PipelineLayoutCreateInfo::builder()
94            .flags(self.flags)
95            .set_layouts(&self.set_layouts_vk)
96            .push_constant_ranges(&self.push_constant_ranges)
97    }
98}