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}