oximedia_gpu/backend/
vulkan.rs1use super::{Backend, BackendCapabilities, BackendType};
7use crate::{GpuDevice, Result};
8
9pub struct VulkanBackend {
11 capabilities: BackendCapabilities,
12 device: Option<GpuDevice>,
13}
14
15impl VulkanBackend {
16 pub fn new() -> Result<Self> {
18 let device = GpuDevice::new(None)?;
19 let capabilities = Self::query_capabilities(&device);
20
21 Ok(Self {
22 capabilities,
23 device: Some(device),
24 })
25 }
26
27 fn query_capabilities(device: &GpuDevice) -> BackendCapabilities {
29 let info = device.info();
30
31 let backend_type = match info.backend.as_str() {
33 "Vulkan" => BackendType::Vulkan,
34 "Metal" => BackendType::Metal,
35 "DirectX 12" => BackendType::DX12,
36 _ => BackendType::Vulkan, };
38
39 BackendCapabilities {
41 backend_type,
42 max_workgroup_size: (256, 256, 64),
43 max_workgroup_invocations: 256,
44 max_buffer_size: 1024 * 1024 * 1024, compute_shaders: true,
46 subgroups: false,
47 push_constants: false,
48 }
49 }
50
51 #[must_use]
53 pub fn device(&self) -> Option<&GpuDevice> {
54 self.device.as_ref()
55 }
56
57 #[must_use]
59 pub fn is_vulkan(&self) -> bool {
60 matches!(self.capabilities.backend_type, BackendType::Vulkan)
61 }
62
63 #[must_use]
65 pub fn device_info(&self) -> Option<String> {
66 self.device.as_ref().map(|d| {
67 let info = d.info();
68 format!("{} ({}) - {}", info.name, info.device_type, info.backend)
69 })
70 }
71}
72
73impl Backend for VulkanBackend {
74 fn capabilities(&self) -> &BackendCapabilities {
75 &self.capabilities
76 }
77
78 fn is_available() -> bool {
79 GpuDevice::new(None).is_ok()
81 }
82
83 fn initialize() -> Result<Self> {
84 Self::new()
85 }
86}
87
88impl Default for VulkanBackend {
89 fn default() -> Self {
96 match Self::new() {
97 Ok(backend) => backend,
98 Err(e) => panic!("Failed to initialize Vulkan backend: {e}"),
99 }
100 }
101}
102
103pub struct VulkanFeatures {
105 pub descriptor_indexing: bool,
107 pub buffer_device_address: bool,
109 pub subgroup_operations: bool,
111 pub ray_tracing: bool,
113}
114
115impl VulkanFeatures {
116 #[must_use]
118 pub fn query() -> Self {
119 Self {
122 descriptor_indexing: false,
123 buffer_device_address: false,
124 subgroup_operations: false,
125 ray_tracing: false,
126 }
127 }
128
129 #[must_use]
131 pub fn has_advanced_features(&self) -> bool {
132 self.descriptor_indexing
133 || self.buffer_device_address
134 || self.subgroup_operations
135 || self.ray_tracing
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 #[ignore] fn test_vulkan_backend_available() {
146 let available = VulkanBackend::is_available();
148 println!("Vulkan available: {available}");
149 }
150
151 #[test]
152 fn test_vulkan_features() {
153 let features = VulkanFeatures::query();
154 println!("Vulkan features: {:?}", features.has_advanced_features());
155 }
156}