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 {
90 Self::new().expect("Failed to initialize Vulkan backend")
91 }
92}
93
94pub struct VulkanFeatures {
96 pub descriptor_indexing: bool,
98 pub buffer_device_address: bool,
100 pub subgroup_operations: bool,
102 pub ray_tracing: bool,
104}
105
106impl VulkanFeatures {
107 #[must_use]
109 pub fn query() -> Self {
110 Self {
113 descriptor_indexing: false,
114 buffer_device_address: false,
115 subgroup_operations: false,
116 ray_tracing: false,
117 }
118 }
119
120 #[must_use]
122 pub fn has_advanced_features(&self) -> bool {
123 self.descriptor_indexing
124 || self.buffer_device_address
125 || self.subgroup_operations
126 || self.ray_tracing
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 #[ignore] fn test_vulkan_backend_available() {
137 let available = VulkanBackend::is_available();
139 println!("Vulkan available: {available}");
140 }
141
142 #[test]
143 fn test_vulkan_features() {
144 let features = VulkanFeatures::query();
145 println!("Vulkan features: {:?}", features.has_advanced_features());
146 }
147}