ailloli_ui_render_vulkan/
target.rs

1//! Borrowed host image targets and their layout transitions.
2
3use ash::vk;
4
5/// One host-owned Vulkan image target for an Ailloli UI render pass.
6///
7/// Immersive hosts will usually wrap the currently acquired presented image and
8/// its image view. The host remains responsible for acquire/release/composition.
9///
10/// # Examples
11///
12/// ```
13/// use ailloli_ui_render_vulkan::VulkanFrameTarget;
14/// use ash::vk;
15/// let target = VulkanFrameTarget::new(
16///     vk::Image::null(),
17///     vk::ImageView::null(),
18///     vk::Format::R8G8B8A8_UNORM,
19///     vk::Extent2D { width: 1280, height: 720 },
20/// );
21/// assert_eq!(target.extent.width, 1280);
22/// ```
23#[derive(Clone, Copy)]
24pub struct VulkanFrameTarget {
25    /// Host-owned target image; null is rejected at render time.
26    pub image: vk::Image,
27    /// Host-owned 2D image view; null is rejected at render time.
28    pub view: vk::ImageView,
29    /// Pixel format used to build compatible render passes and pipelines.
30    pub format: vk::Format,
31    /// Non-zero target extent in physical pixels.
32    pub extent: vk::Extent2D,
33    /// Layout expected before the renderer's transition.
34    pub initial_layout: vk::ImageLayout,
35    /// Layout produced after rendering completes.
36    pub final_layout: vk::ImageLayout,
37}
38
39/// Constructors for host-owned frame targets.
40impl VulkanFrameTarget {
41    /// Creates a target transitioning from `UNDEFINED` to `COLOR_ATTACHMENT_OPTIMAL`.
42    ///
43    /// Handle and extent validation is deferred to rendering so constructing a
44    /// target does not call Vulkan.
45    ///
46    /// # Examples
47    ///
48    /// ```
49    /// use ailloli_ui_render_vulkan::VulkanFrameTarget;
50    /// use ash::vk;
51    /// let target = VulkanFrameTarget::new(
52    ///     vk::Image::null(), vk::ImageView::null(), vk::Format::B8G8R8A8_SRGB,
53    ///     vk::Extent2D { width: 640, height: 480 },
54    /// );
55    /// assert!(target.initial_layout == vk::ImageLayout::UNDEFINED);
56    /// assert!(target.final_layout == vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
57    /// ```
58    pub fn new(
59        image: vk::Image,
60        view: vk::ImageView,
61        format: vk::Format,
62        extent: vk::Extent2D,
63    ) -> Self {
64        Self {
65            image,
66            view,
67            format,
68            extent,
69            initial_layout: vk::ImageLayout::UNDEFINED,
70            final_layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
71        }
72    }
73
74    /// Replaces the layouts consumed and produced by the render pass.
75    ///
76    /// # Examples
77    ///
78    /// ```
79    /// use ailloli_ui_render_vulkan::VulkanFrameTarget;
80    /// use ash::vk;
81    /// let target = VulkanFrameTarget::new(
82    ///     vk::Image::null(), vk::ImageView::null(), vk::Format::B8G8R8A8_SRGB,
83    ///     vk::Extent2D { width: 1, height: 1 },
84    /// ).with_layouts(vk::ImageLayout::PRESENT_SRC_KHR, vk::ImageLayout::PRESENT_SRC_KHR);
85    /// assert!(target.initial_layout == vk::ImageLayout::PRESENT_SRC_KHR);
86    /// ```
87    pub fn with_layouts(
88        mut self,
89        initial_layout: vk::ImageLayout,
90        final_layout: vk::ImageLayout,
91    ) -> Self {
92        self.initial_layout = initial_layout;
93        self.final_layout = final_layout;
94        self
95    }
96}