concinnity_device/factory.rs
1// src/factory.rs
2//
3// The backend factory: route the assembled inputs to the backend selected at
4// compile time. The three backend_* cfgs are mutually exclusive, so exactly one
5// arm compiles. This is the single construction choke point - the client holds
6// only a `Box<dyn RenderBackend>` and never names a concrete backend context.
7
8/// Probe a cheap throwaway device handle to classify the GPU, so the auto-config
9/// quality ceiling can influence the render targets / effect pipelines the backend
10/// sizes at init. Each backend creates only the cheap handle it needs and
11/// classifies it: Metal the default-device handle, DirectX the DXGI adapter (no
12/// device / swapchain), Vulkan a surface-free instance (destroyed immediately).
13pub fn probe_gpu_profile() -> crate::gfx::backend::GpuProfile {
14 #[cfg(backend_dx)]
15 {
16 crate::directx::probe_gpu_profile()
17 }
18 #[cfg(backend_vk)]
19 {
20 crate::vulkan::probe_gpu_profile()
21 }
22 #[cfg(backend_metal)]
23 {
24 crate::metal::probe_gpu_profile()
25 }
26}
27
28/// Route the assembled `BackendInit` to the backend selected at compile time.
29/// Construction inputs are documented on `BackendInit` itself.
30pub fn init_backend(
31 init: crate::gfx::backend_init::BackendInit<'_>,
32) -> Option<Box<dyn crate::gfx::backend::RenderBackend>> {
33 #[cfg(backend_dx)]
34 {
35 match crate::directx::DxContext::new(init) {
36 Ok(dx) => Some(Box::new(dx)),
37 Err(e) => {
38 tracing::error!("GraphicsSystem: D3D12 init failed: {}", e);
39 None
40 }
41 }
42 }
43
44 #[cfg(backend_vk)]
45 {
46 match crate::vulkan::VkContext::new(init) {
47 Ok(vk) => Some(Box::new(vk)),
48 Err(e) => {
49 tracing::error!("GraphicsSystem: Vulkan init failed: {}", e);
50 None
51 }
52 }
53 }
54
55 #[cfg(backend_metal)]
56 {
57 match crate::metal::MtlContext::new(init) {
58 Ok(mtl) => Some(Box::new(mtl)),
59 Err(e) => {
60 tracing::error!("GraphicsSystem: Metal init failed: {}", e);
61 None
62 }
63 }
64 }
65}