vkobject_rs/
renderpass.rs1
2use crate::prelude::*;
3use std::{
4 fmt::{self, Debug, Formatter},
5 ptr::null,
6 sync::Arc,
7};
8
9#[derive(Debug, Clone, Copy)]
11pub struct VulkanRenderPassAttachment {
12 pub format: VkFormat,
14
15 pub is_depth_stencil: bool,
17}
18
19impl VulkanRenderPassAttachment {
20 pub fn new(format: VkFormat, is_depth_stencil: bool) -> Self {
22 Self {
23 format,
24 is_depth_stencil,
25 }
26 }
27
28 pub(crate) fn get_attachment_desc(&self) -> VkAttachmentDescription {
30 VkAttachmentDescription {
31 flags: 0,
32 format: self.format,
33 samples: VkSampleCountFlagBits::VK_SAMPLE_COUNT_1_BIT,
34 loadOp: VkAttachmentLoadOp::VK_ATTACHMENT_LOAD_OP_CLEAR,
35 storeOp: VkAttachmentStoreOp::VK_ATTACHMENT_STORE_OP_STORE,
36 stencilLoadOp: VkAttachmentLoadOp::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
37 stencilStoreOp: VkAttachmentStoreOp::VK_ATTACHMENT_STORE_OP_DONT_CARE,
38 initialLayout: VkImageLayout::VK_IMAGE_LAYOUT_UNDEFINED,
39 finalLayout: if !self.is_depth_stencil {VkImageLayout::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR} else {VkImageLayout::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL},
40 }
41 }
42}
43
44unsafe impl Sync for VulkanRenderPassAttachment {}
45unsafe impl Send for VulkanRenderPassAttachment {}
46
47pub struct VulkanRenderPass {
49 pub device: Arc<VulkanDevice>,
51
52 pub attachments: Vec<VulkanRenderPassAttachment>,
54
55 renderpass: VkRenderPass,
57}
58
59impl VulkanRenderPass {
60 pub fn new(device: Arc<VulkanDevice>, attachments: &[VulkanRenderPassAttachment]) -> Result<Self, VulkanError> {
62 let vkcore = device.vkcore.clone();
63 let attachment_descs: Vec<VkAttachmentDescription> = attachments.iter().map(|a|a.get_attachment_desc()).collect();
64 let color_attachment_refs: Vec<VkAttachmentReference> = attachments.iter().enumerate().filter_map(|(i, a)|
65 if !a.is_depth_stencil {
66 Some(VkAttachmentReference {
67 attachment: i as u32,
68 layout: VkImageLayout::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
69 })
70 } else {
71 None
72 }
73 ).collect();
74 let depth_attachment_ref: Option<VkAttachmentReference> = attachments.iter().enumerate().filter_map(|(i, a)|
75 if a.is_depth_stencil {
76 Some(VkAttachmentReference {
77 attachment: i as u32,
78 layout: VkImageLayout::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
79 })
80 } else {
81 None
82 }
83 ).next();
84 let subpass_desc = VkSubpassDescription {
85 flags: 0,
86 pipelineBindPoint: VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS,
87 inputAttachmentCount: 0,
88 pInputAttachments: null(),
89 colorAttachmentCount: color_attachment_refs.len() as u32,
90 pColorAttachments: color_attachment_refs.as_ptr(),
91 pResolveAttachments: null(),
92 pDepthStencilAttachment: if let Some(depth) = &depth_attachment_ref {
93 depth
94 } else {
95 null()
96 },
97 preserveAttachmentCount: 0,
98 pPreserveAttachments: null(),
99 };
100 let dependencies: [VkSubpassDependency; 2] = [
101 VkSubpassDependency {
102 srcSubpass: VK_SUBPASS_EXTERNAL,
103 dstSubpass: 0,
104 srcStageMask:
105 VkPipelineStageFlagBits::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT as VkPipelineStageFlags |
106 VkPipelineStageFlagBits::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT as VkPipelineStageFlags,
107 dstStageMask:
108 VkPipelineStageFlagBits::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT as VkPipelineStageFlags |
109 VkPipelineStageFlagBits::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT as VkPipelineStageFlags,
110 srcAccessMask:
111 VkAccessFlagBits::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT as VkPipelineStageFlags,
112 dstAccessMask:
113 VkAccessFlagBits::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT as VkPipelineStageFlags |
114 VkAccessFlagBits::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT as VkPipelineStageFlags,
115 dependencyFlags: 0,
116 },
117 VkSubpassDependency {
118 srcSubpass: VK_SUBPASS_EXTERNAL,
119 dstSubpass: 0,
120 srcStageMask: VkPipelineStageFlagBits::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT as VkPipelineStageFlags,
121 dstStageMask: VkPipelineStageFlagBits::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT as VkPipelineStageFlags,
122 srcAccessMask: 0,
123 dstAccessMask:
124 VkAccessFlagBits::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT as VkAccessFlags |
125 VkAccessFlagBits::VK_ACCESS_COLOR_ATTACHMENT_READ_BIT as VkAccessFlags,
126 dependencyFlags: 0,
127 },
128 ];
129 let renderpass_ci = VkRenderPassCreateInfo {
130 sType: VkStructureType::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
131 pNext: null(),
132 flags: 0,
133 attachmentCount: attachment_descs.len() as u32,
134 pAttachments: attachment_descs.as_ptr(),
135 subpassCount: 1,
136 pSubpasses: &subpass_desc,
137 dependencyCount: dependencies.len() as u32,
138 pDependencies: dependencies.as_ptr(),
139 };
140 let mut renderpass: VkRenderPass = null();
141 vkcore.vkCreateRenderPass(device.get_vk_device(), &renderpass_ci, null(), &mut renderpass)?;
142 Ok(Self {
143 device,
144 attachments: attachments.to_vec(),
145 renderpass,
146 })
147 }
148
149 pub(crate) fn get_vk_renderpass(&self) -> VkRenderPass {
151 self.renderpass
152 }
153}
154
155impl Debug for VulkanRenderPass {
156 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
157 f.debug_struct("VulkanRenderPass")
158 .field("renderpass", &self.renderpass)
159 .finish()
160 }
161}
162
163impl Drop for VulkanRenderPass {
164 fn drop(&mut self) {
165 let vkcore = self.device.vkcore.clone();
166 vkcore.vkDestroyRenderPass(self.device.get_vk_device(), self.renderpass, null()).unwrap();
167 }
168}
169
170unsafe impl Sync for VulkanRenderPass {}
171unsafe impl Send for VulkanRenderPass {}