rotex_vulkan/backend/vulkan/
mod.rs1mod buffer;
2mod command;
3mod descriptor;
4mod device;
5mod framebuffer;
6mod graphics_pipeline;
7mod image;
8mod pass;
9mod swapchain;
10mod sync;
11
12pub use buffer::RotexBuffer;
13pub use command::{CommandBuffer, CommandPool};
14pub use descriptor::{DescriptorPool, DescriptorSet};
15pub use device::{Adapter, Device, DeviceDescriptor, QueueAllocation, QueueCategory, QueueRequest};
16pub use framebuffer::{Framebuffer, FramebufferBuilder};
17pub use graphics_pipeline::{
18 ColorBlendAttachmentState, ColorBlendState, DepthStencilState, DescriptorSetLayout,
19 GraphicsPipeline, GraphicsPipelineBuilder, GraphicsPipelineLayout, RasterizationState,
20 ShaderModule, ShaderStageDescriptor, Vertex, VertexInputDescriptor,
21};
22pub use image::{ImageDescriptor, RotexImage, RotexSampler, SamplerDescriptor};
23pub use pass::{RenderPass, RenderPassBuilder, SubpassBlueprint};
24pub use swapchain::{Surface, Swapchain};
25pub use sync::{Fence, Semaphore};
26
27use ash::vk;
28use std::cmp::Reverse;
29
30use crate::core::{DebugMessenger, Instance, InstanceOptions};
31use crate::error::{Error, ErrorKind, Severity};
32
33pub(crate) struct VulkanInstance {
34 raw: Instance,
35 debug: Option<DebugMessenger>,
36}
37
38impl VulkanInstance {
39 pub(crate) fn new(options: &InstanceOptions, extensions: &[*const i8]) -> Result<Self, Error> {
40 let (raw, debug) = Instance::new_with_options(options, extensions)?;
41 Ok(Self { raw, debug })
42 }
43
44 pub(crate) fn request_device(&self, desc: DeviceDescriptor) -> Result<VulkanDevice, Error> {
45 let mut adapters = self.raw.enumerate_adapters();
46 if adapters.is_empty() {
47 return Err(Error {
48 kind: ErrorKind::NoCompatibleDevice,
49 severity: Severity::Fatal,
50 });
51 }
52 adapters.sort_by_key(|adapter| Reverse(adapter.selection_score()));
53
54 let mut last_error = None;
55 for adapter in adapters {
56 if !adapter.supports_queue_requests(&self.raw, &desc.queues) {
57 continue;
58 }
59 if desc.enable_swapchain && !adapter.has_swapchain_extension(&self.raw)? {
60 continue;
61 }
62 match adapter.request_device(&self.raw, desc.clone()) {
63 Ok(device) => {
64 eprintln!(
65 "[vulkan] selected adapter: {} ({:?})",
66 adapter.name(),
67 adapter.device_type()
68 );
69 return Ok(VulkanDevice { raw: device });
70 }
71 Err(err) => {
72 last_error = Some(err);
73 }
74 }
75 }
76
77 Err(last_error.unwrap_or(Error {
78 kind: ErrorKind::NoCompatibleDevice,
79 severity: Severity::Fatal,
80 }))
81 }
82
83 pub(crate) fn create_surface_from_raw(&self, raw_surface: vk::SurfaceKHR) -> VulkanSurface {
84 VulkanSurface {
85 raw: Surface::new(&self.raw, raw_surface),
86 }
87 }
88
89 pub(crate) fn raw_entry(&self) -> &ash::Entry {
90 self.raw.entry()
91 }
92
93 pub(crate) fn raw_instance(&self) -> &ash::Instance {
94 self.raw.instance()
95 }
96
97 pub(crate) fn raw(&self) -> &Instance {
98 &self.raw
99 }
100
101 pub(crate) fn destroy(mut self) {
102 if let Some(debug) = self.debug.take() {
103 debug.destroy();
104 }
105 self.raw.destroy();
106 }
107}
108
109pub(crate) struct VulkanDevice {
110 raw: Device,
111}
112
113impl VulkanDevice {
114 pub(crate) fn raw(&self) -> &Device {
115 &self.raw
116 }
117
118 pub(crate) fn destroy(mut self) {
119 self.raw.destroy();
120 }
121}
122
123pub(crate) struct VulkanSurface {
124 raw: Surface,
125}
126
127impl VulkanSurface {
128 pub(crate) fn create_swapchain(
129 &self,
130 instance: &VulkanInstance,
131 device: &VulkanDevice,
132 extent_hint: vk::Extent2D,
133 ) -> Result<VulkanSwapchain, Error> {
134 let swapchain = Swapchain::new(&instance.raw, device.raw(), &self.raw, extent_hint)?;
135 Ok(VulkanSwapchain { raw: swapchain })
136 }
137
138 pub(crate) fn create_swapchain_with_old(
139 &self,
140 instance: &VulkanInstance,
141 device: &VulkanDevice,
142 extent_hint: vk::Extent2D,
143 old_swapchain: vk::SwapchainKHR,
144 ) -> Result<VulkanSwapchain, Error> {
145 let swapchain = Swapchain::new_with_old(
146 instance.raw(),
147 device.raw(),
148 &self.raw,
149 extent_hint,
150 old_swapchain,
151 )?;
152 Ok(VulkanSwapchain { raw: swapchain })
153 }
154
155 pub(crate) fn destroy(mut self) {
156 self.raw.destroy();
157 }
158}
159
160pub(crate) struct VulkanSwapchain {
161 raw: Swapchain,
162}
163
164impl VulkanSwapchain {
165 pub(crate) fn raw(&self) -> &Swapchain {
166 &self.raw
167 }
168
169 pub(crate) fn destroy(mut self, device: &VulkanDevice) {
170 self.raw.destroy(device.raw());
171 }
172
173 pub(crate) fn destroy_in_place(&mut self, device: &VulkanDevice) {
174 self.raw.destroy(device.raw());
175 }
176
177 pub(crate) fn handle(&self) -> vk::SwapchainKHR {
178 self.raw.swapchain
179 }
180}