Skip to main content

rotex_vulkan/backend/vulkan/
mod.rs

1mod 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}