rafx_api/
device_context.rs

1#[cfg(any(
2    feature = "rafx-empty",
3    not(any(
4        feature = "rafx-dx12",
5        feature = "rafx-metal",
6        feature = "rafx-vulkan",
7        feature = "rafx-gles2",
8        feature = "rafx-gles3",
9    ))
10))]
11use crate::backends::empty::RafxDeviceContextEmpty;
12#[cfg(feature = "rafx-dx12")]
13use crate::dx12::RafxDeviceContextDx12;
14#[cfg(feature = "rafx-gles2")]
15use crate::gles2::RafxDeviceContextGles2;
16#[cfg(feature = "rafx-gles3")]
17use crate::gles3::RafxDeviceContextGles3;
18#[cfg(feature = "rafx-metal")]
19use crate::metal::RafxDeviceContextMetal;
20#[cfg(feature = "rafx-vulkan")]
21use crate::vulkan::RafxDeviceContextVulkan;
22use crate::*;
23use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
24
25/// A cloneable, thread-safe handle used to create graphics resources.
26///
27/// All device contexts, and resources created from them, must be dropped before the `RafxApi`
28/// object that they came from is dropped or destroyed.
29#[derive(Clone)]
30pub enum RafxDeviceContext {
31    #[cfg(feature = "rafx-dx12")]
32    Dx12(RafxDeviceContextDx12),
33    #[cfg(feature = "rafx-vulkan")]
34    Vk(RafxDeviceContextVulkan),
35    #[cfg(feature = "rafx-metal")]
36    Metal(RafxDeviceContextMetal),
37    #[cfg(feature = "rafx-gles2")]
38    Gles2(RafxDeviceContextGles2),
39    #[cfg(feature = "rafx-gles3")]
40    Gles3(RafxDeviceContextGles3),
41    #[cfg(any(
42        feature = "rafx-empty",
43        not(any(
44            feature = "rafx-dx12",
45            feature = "rafx-metal",
46            feature = "rafx-vulkan",
47            feature = "rafx-gles2",
48            feature = "rafx-gles3",
49        ))
50    ))]
51    Empty(RafxDeviceContextEmpty),
52}
53
54impl RafxDeviceContext {
55    pub fn is_dx12(&self) -> bool {
56        #[allow(unreachable_patterns)]
57        match self {
58            #[cfg(feature = "rafx-dx12")]
59            RafxDeviceContext::Dx12(_) => true,
60            _ => false,
61        }
62    }
63
64    pub fn is_vulkan(&self) -> bool {
65        #[allow(unreachable_patterns)]
66        match self {
67            #[cfg(feature = "rafx-vulkan")]
68            RafxDeviceContext::Vk(_) => true,
69            _ => false,
70        }
71    }
72
73    pub fn is_metal(&self) -> bool {
74        #[allow(unreachable_patterns)]
75        match self {
76            #[cfg(feature = "rafx-metal")]
77            RafxDeviceContext::Metal(_) => true,
78            _ => false,
79        }
80    }
81
82    pub fn is_gles3(&self) -> bool {
83        #[allow(unreachable_patterns)]
84        match self {
85            #[cfg(feature = "rafx-gles3")]
86            RafxDeviceContext::Gles3(_) => true,
87            _ => false,
88        }
89    }
90
91    pub fn is_gles2(&self) -> bool {
92        #[allow(unreachable_patterns)]
93        match self {
94            #[cfg(feature = "rafx-gles2")]
95            RafxDeviceContext::Gles2(_) => true,
96            _ => false,
97        }
98    }
99
100    pub fn api_type(&self) -> RafxApiType {
101        match self {
102            #[cfg(feature = "rafx-dx12")]
103            RafxDeviceContext::Dx12(_) => RafxApiType::Dx12,
104            #[cfg(feature = "rafx-vulkan")]
105            RafxDeviceContext::Vk(_) => RafxApiType::Vk,
106            #[cfg(feature = "rafx-metal")]
107            RafxDeviceContext::Metal(_) => RafxApiType::Metal,
108            #[cfg(feature = "rafx-gles2")]
109            RafxDeviceContext::Gles2(_) => RafxApiType::Gles2,
110            #[cfg(feature = "rafx-gles3")]
111            RafxDeviceContext::Gles3(_) => RafxApiType::Gles3,
112            #[cfg(any(
113                feature = "rafx-empty",
114                not(any(
115                    feature = "rafx-dx12",
116                    feature = "rafx-metal",
117                    feature = "rafx-vulkan",
118                    feature = "rafx-gles2",
119                    feature = "rafx-gles3"
120                ))
121            ))]
122            RafxDeviceContext::Empty(_) => RafxApiType::Empty,
123        }
124    }
125
126    /// Get metadata about the device
127    pub fn device_info(&self) -> &RafxDeviceInfo {
128        match self {
129            #[cfg(feature = "rafx-dx12")]
130            RafxDeviceContext::Dx12(inner) => inner.device_info(),
131            #[cfg(feature = "rafx-vulkan")]
132            RafxDeviceContext::Vk(inner) => inner.device_info(),
133            #[cfg(feature = "rafx-metal")]
134            RafxDeviceContext::Metal(inner) => inner.device_info(),
135            #[cfg(feature = "rafx-gles2")]
136            RafxDeviceContext::Gles2(inner) => inner.device_info(),
137            #[cfg(feature = "rafx-gles3")]
138            RafxDeviceContext::Gles3(inner) => inner.device_info(),
139            #[cfg(any(
140                feature = "rafx-empty",
141                not(any(
142                    feature = "rafx-dx12",
143                    feature = "rafx-metal",
144                    feature = "rafx-vulkan",
145                    feature = "rafx-gles2",
146                    feature = "rafx-gles3"
147                ))
148            ))]
149            RafxDeviceContext::Empty(inner) => inner.device_info(),
150        }
151    }
152
153    pub fn find_supported_format(
154        &self,
155        candidates: &[RafxFormat],
156        resource_type: RafxResourceType,
157    ) -> Option<RafxFormat> {
158        match self {
159            #[cfg(feature = "rafx-dx12")]
160            RafxDeviceContext::Dx12(inner) => {
161                inner.find_supported_format(candidates, resource_type)
162            }
163            #[cfg(feature = "rafx-vulkan")]
164            RafxDeviceContext::Vk(inner) => inner.find_supported_format(candidates, resource_type),
165            #[cfg(feature = "rafx-metal")]
166            RafxDeviceContext::Metal(inner) => {
167                inner.find_supported_format(candidates, resource_type)
168            }
169            #[cfg(feature = "rafx-gles2")]
170            RafxDeviceContext::Gles2(inner) => {
171                inner.find_supported_format(candidates, resource_type)
172            }
173            #[cfg(feature = "rafx-gles3")]
174            RafxDeviceContext::Gles3(inner) => {
175                inner.find_supported_format(candidates, resource_type)
176            }
177            #[cfg(any(
178                feature = "rafx-empty",
179                not(any(
180                    feature = "rafx-dx12",
181                    feature = "rafx-metal",
182                    feature = "rafx-vulkan",
183                    feature = "rafx-gles2",
184                    feature = "rafx-gles3"
185                ))
186            ))]
187            RafxDeviceContext::Empty(inner) => {
188                inner.find_supported_format(candidates, resource_type)
189            }
190        }
191    }
192
193    pub fn find_supported_sample_count(
194        &self,
195        candidates: &[RafxSampleCount],
196    ) -> Option<RafxSampleCount> {
197        match self {
198            #[cfg(feature = "rafx-dx12")]
199            RafxDeviceContext::Dx12(inner) => inner.find_supported_sample_count(candidates),
200            #[cfg(feature = "rafx-vulkan")]
201            RafxDeviceContext::Vk(inner) => inner.find_supported_sample_count(candidates),
202            #[cfg(feature = "rafx-metal")]
203            RafxDeviceContext::Metal(inner) => inner.find_supported_sample_count(candidates),
204            #[cfg(feature = "rafx-gles2")]
205            RafxDeviceContext::Gles2(inner) => inner.find_supported_sample_count(candidates),
206            #[cfg(feature = "rafx-gles3")]
207            RafxDeviceContext::Gles3(inner) => inner.find_supported_sample_count(candidates),
208            #[cfg(any(
209                feature = "rafx-empty",
210                not(any(
211                    feature = "rafx-dx12",
212                    feature = "rafx-metal",
213                    feature = "rafx-vulkan",
214                    feature = "rafx-gles2",
215                    feature = "rafx-gles3",
216                ))
217            ))]
218            RafxDeviceContext::Empty(inner) => inner.find_supported_sample_count(candidates),
219        }
220    }
221
222    /// Create a queue
223    pub fn create_queue(
224        &self,
225        queue_type: RafxQueueType,
226    ) -> RafxResult<RafxQueue> {
227        Ok(match self {
228            #[cfg(feature = "rafx-dx12")]
229            RafxDeviceContext::Dx12(inner) => RafxQueue::Dx12(inner.create_queue(queue_type)?),
230            #[cfg(feature = "rafx-vulkan")]
231            RafxDeviceContext::Vk(inner) => RafxQueue::Vk(inner.create_queue(queue_type)?),
232            #[cfg(feature = "rafx-metal")]
233            RafxDeviceContext::Metal(inner) => RafxQueue::Metal(inner.create_queue(queue_type)?),
234            #[cfg(feature = "rafx-gles2")]
235            RafxDeviceContext::Gles2(inner) => RafxQueue::Gles2(inner.create_queue(queue_type)?),
236            #[cfg(feature = "rafx-gles3")]
237            RafxDeviceContext::Gles3(inner) => RafxQueue::Gles3(inner.create_queue(queue_type)?),
238            #[cfg(any(
239                feature = "rafx-empty",
240                not(any(
241                    feature = "rafx-dx12",
242                    feature = "rafx-metal",
243                    feature = "rafx-vulkan",
244                    feature = "rafx-gles2",
245                    feature = "rafx-gles3",
246                ))
247            ))]
248            RafxDeviceContext::Empty(inner) => RafxQueue::Empty(inner.create_queue(queue_type)?),
249        })
250    }
251
252    /// Create a fence
253    pub fn create_fence(&self) -> RafxResult<RafxFence> {
254        Ok(match self {
255            #[cfg(feature = "rafx-dx12")]
256            RafxDeviceContext::Dx12(inner) => RafxFence::Dx12(inner.create_fence()?),
257            #[cfg(feature = "rafx-vulkan")]
258            RafxDeviceContext::Vk(inner) => RafxFence::Vk(inner.create_fence()?),
259            #[cfg(feature = "rafx-metal")]
260            RafxDeviceContext::Metal(inner) => RafxFence::Metal(inner.create_fence()?),
261            #[cfg(feature = "rafx-gles2")]
262            RafxDeviceContext::Gles2(inner) => RafxFence::Gles2(inner.create_fence()?),
263            #[cfg(feature = "rafx-gles3")]
264            RafxDeviceContext::Gles3(inner) => RafxFence::Gles3(inner.create_fence()?),
265            #[cfg(any(
266                feature = "rafx-empty",
267                not(any(
268                    feature = "rafx-dx12",
269                    feature = "rafx-metal",
270                    feature = "rafx-vulkan",
271                    feature = "rafx-gles2",
272                    feature = "rafx-gles3"
273                ))
274            ))]
275            RafxDeviceContext::Empty(inner) => RafxFence::Empty(inner.create_fence()?),
276        })
277    }
278
279    /// Create a semaphore
280    pub fn create_semaphore(&self) -> RafxResult<RafxSemaphore> {
281        Ok(match self {
282            #[cfg(feature = "rafx-dx12")]
283            RafxDeviceContext::Dx12(inner) => RafxSemaphore::Dx12(inner.create_semaphore()?),
284            #[cfg(feature = "rafx-vulkan")]
285            RafxDeviceContext::Vk(inner) => RafxSemaphore::Vk(inner.create_semaphore()?),
286            #[cfg(feature = "rafx-metal")]
287            RafxDeviceContext::Metal(inner) => RafxSemaphore::Metal(inner.create_semaphore()?),
288            #[cfg(feature = "rafx-gles2")]
289            RafxDeviceContext::Gles2(inner) => RafxSemaphore::Gles2(inner.create_semaphore()?),
290            #[cfg(feature = "rafx-gles3")]
291            RafxDeviceContext::Gles3(inner) => RafxSemaphore::Gles3(inner.create_semaphore()?),
292            #[cfg(any(
293                feature = "rafx-empty",
294                not(any(
295                    feature = "rafx-dx12",
296                    feature = "rafx-metal",
297                    feature = "rafx-vulkan",
298                    feature = "rafx-gles2",
299                    feature = "rafx-gles3"
300                ))
301            ))]
302            RafxDeviceContext::Empty(inner) => RafxSemaphore::Empty(inner.create_semaphore()?),
303        })
304    }
305
306    /// Create a swapchain
307    pub fn create_swapchain(
308        &self,
309        raw_display_handle: &dyn HasRawDisplayHandle,
310        raw_window_handle: &dyn HasRawWindowHandle,
311        present_queue: &RafxQueue,
312        swapchain_def: &RafxSwapchainDef,
313    ) -> RafxResult<RafxSwapchain> {
314        Ok(match self {
315            #[cfg(feature = "rafx-dx12")]
316            RafxDeviceContext::Dx12(inner) => RafxSwapchain::Dx12(inner.create_swapchain(
317                raw_display_handle,
318                raw_window_handle,
319                present_queue.dx12_queue().unwrap(),
320                swapchain_def,
321            )?),
322            #[cfg(feature = "rafx-vulkan")]
323            RafxDeviceContext::Vk(inner) => RafxSwapchain::Vk(inner.create_swapchain(
324                raw_display_handle,
325                raw_window_handle,
326                present_queue.vk_queue().unwrap(),
327                swapchain_def,
328            )?),
329            #[cfg(feature = "rafx-metal")]
330            RafxDeviceContext::Metal(inner) => RafxSwapchain::Metal(inner.create_swapchain(
331                raw_display_handle,
332                raw_window_handle,
333                present_queue.metal_queue().unwrap(),
334                swapchain_def,
335            )?),
336            #[cfg(feature = "rafx-gles2")]
337            RafxDeviceContext::Gles2(inner) => RafxSwapchain::Gles2(inner.create_swapchain(
338                raw_display_handle,
339                raw_window_handle,
340                present_queue.gles2_queue().unwrap(),
341                swapchain_def,
342            )?),
343            #[cfg(feature = "rafx-gles3")]
344            RafxDeviceContext::Gles3(inner) => RafxSwapchain::Gles3(inner.create_swapchain(
345                raw_display_handle,
346                raw_window_handle,
347                present_queue.gles3_queue().unwrap(),
348                swapchain_def,
349            )?),
350            #[cfg(any(
351                feature = "rafx-empty",
352                not(any(
353                    feature = "rafx-dx12",
354                    feature = "rafx-metal",
355                    feature = "rafx-vulkan",
356                    feature = "rafx-gles2",
357                    feature = "rafx-gles3",
358                ))
359            ))]
360            RafxDeviceContext::Empty(inner) => RafxSwapchain::Empty(inner.create_swapchain(
361                raw_display_handle,
362                raw_window_handle,
363                present_queue,
364                swapchain_def,
365            )?),
366        })
367    }
368
369    /// Wait for the given fences to complete. If a fence is in an unsubmitted state, the fence is
370    /// ignored.
371    pub fn wait_for_fences(
372        &self,
373        fences: &[&RafxFence],
374    ) -> RafxResult<()> {
375        Ok(match self {
376            #[cfg(feature = "rafx-dx12")]
377            RafxDeviceContext::Dx12(inner) => {
378                let fences: Vec<_> = fences.iter().map(|x| x.dx12_fence().unwrap()).collect();
379                inner.wait_for_fences(&fences)?
380            }
381            #[cfg(feature = "rafx-vulkan")]
382            RafxDeviceContext::Vk(inner) => {
383                let fences: Vec<_> = fences.iter().map(|x| x.vk_fence().unwrap()).collect();
384                inner.wait_for_fences(&fences)?
385            }
386            #[cfg(feature = "rafx-metal")]
387            RafxDeviceContext::Metal(inner) => {
388                let fences: Vec<_> = fences.iter().map(|x| x.metal_fence().unwrap()).collect();
389                inner.wait_for_fences(&fences)?
390            }
391            #[cfg(feature = "rafx-gles2")]
392            RafxDeviceContext::Gles2(inner) => {
393                let fences: Vec<_> = fences.iter().map(|x| x.gles2_fence().unwrap()).collect();
394                inner.wait_for_fences(&fences)?
395            }
396            #[cfg(feature = "rafx-gles3")]
397            RafxDeviceContext::Gles3(inner) => {
398                let fences: Vec<_> = fences.iter().map(|x| x.gles3_fence().unwrap()).collect();
399                inner.wait_for_fences(&fences)?
400            }
401            #[cfg(any(
402                feature = "rafx-empty",
403                not(any(
404                    feature = "rafx-dx12",
405                    feature = "rafx-metal",
406                    feature = "rafx-vulkan",
407                    feature = "rafx-gles2",
408                    feature = "rafx-gles3"
409                ))
410            ))]
411            RafxDeviceContext::Empty(inner) => {
412                let fences: Vec<_> = fences.iter().map(|x| x.empty_fence().unwrap()).collect();
413                inner.wait_for_fences(&fences)?
414            }
415        })
416    }
417
418    /// Create a sampler
419    pub fn create_sampler(
420        &self,
421        sampler_def: &RafxSamplerDef,
422    ) -> RafxResult<RafxSampler> {
423        Ok(match self {
424            #[cfg(feature = "rafx-dx12")]
425            RafxDeviceContext::Dx12(inner) => RafxSampler::Dx12(inner.create_sampler(sampler_def)?),
426            #[cfg(feature = "rafx-vulkan")]
427            RafxDeviceContext::Vk(inner) => RafxSampler::Vk(inner.create_sampler(sampler_def)?),
428            #[cfg(feature = "rafx-metal")]
429            RafxDeviceContext::Metal(inner) => {
430                RafxSampler::Metal(inner.create_sampler(sampler_def)?)
431            }
432            #[cfg(feature = "rafx-gles2")]
433            RafxDeviceContext::Gles2(inner) => {
434                RafxSampler::Gles2(inner.create_sampler(sampler_def)?)
435            }
436            #[cfg(feature = "rafx-gles3")]
437            RafxDeviceContext::Gles3(inner) => {
438                RafxSampler::Gles3(inner.create_sampler(sampler_def)?)
439            }
440            #[cfg(any(
441                feature = "rafx-empty",
442                not(any(
443                    feature = "rafx-dx12",
444                    feature = "rafx-metal",
445                    feature = "rafx-vulkan",
446                    feature = "rafx-gles2",
447                    feature = "rafx-gles3"
448                ))
449            ))]
450            RafxDeviceContext::Empty(inner) => {
451                RafxSampler::Empty(inner.create_sampler(sampler_def)?)
452            }
453        })
454    }
455
456    /// Create a texture
457    pub fn create_texture(
458        &self,
459        texture_def: &RafxTextureDef,
460    ) -> RafxResult<RafxTexture> {
461        Ok(match self {
462            #[cfg(feature = "rafx-dx12")]
463            RafxDeviceContext::Dx12(inner) => RafxTexture::Dx12(inner.create_texture(texture_def)?),
464            #[cfg(feature = "rafx-vulkan")]
465            RafxDeviceContext::Vk(inner) => RafxTexture::Vk(inner.create_texture(texture_def)?),
466            #[cfg(feature = "rafx-metal")]
467            RafxDeviceContext::Metal(inner) => {
468                RafxTexture::Metal(inner.create_texture(texture_def)?)
469            }
470            #[cfg(feature = "rafx-gles2")]
471            RafxDeviceContext::Gles2(inner) => {
472                RafxTexture::Gles2(inner.create_texture(texture_def)?)
473            }
474            #[cfg(feature = "rafx-gles3")]
475            RafxDeviceContext::Gles3(inner) => {
476                RafxTexture::Gles3(inner.create_texture(texture_def)?)
477            }
478            #[cfg(any(
479                feature = "rafx-empty",
480                not(any(
481                    feature = "rafx-dx12",
482                    feature = "rafx-metal",
483                    feature = "rafx-vulkan",
484                    feature = "rafx-gles2",
485                    feature = "rafx-gles3"
486                ))
487            ))]
488            RafxDeviceContext::Empty(inner) => {
489                RafxTexture::Empty(inner.create_texture(texture_def)?)
490            }
491        })
492    }
493
494    /// Create a buffer
495    pub fn create_buffer(
496        &self,
497        buffer_def: &RafxBufferDef,
498    ) -> RafxResult<RafxBuffer> {
499        Ok(match self {
500            #[cfg(feature = "rafx-dx12")]
501            RafxDeviceContext::Dx12(inner) => RafxBuffer::Dx12(inner.create_buffer(buffer_def)?),
502            #[cfg(feature = "rafx-vulkan")]
503            RafxDeviceContext::Vk(inner) => RafxBuffer::Vk(inner.create_buffer(buffer_def)?),
504            #[cfg(feature = "rafx-metal")]
505            RafxDeviceContext::Metal(inner) => RafxBuffer::Metal(inner.create_buffer(buffer_def)?),
506            #[cfg(feature = "rafx-gles2")]
507            RafxDeviceContext::Gles2(inner) => RafxBuffer::Gles2(inner.create_buffer(buffer_def)?),
508            #[cfg(feature = "rafx-gles3")]
509            RafxDeviceContext::Gles3(inner) => RafxBuffer::Gles3(inner.create_buffer(buffer_def)?),
510            #[cfg(any(
511                feature = "rafx-empty",
512                not(any(
513                    feature = "rafx-dx12",
514                    feature = "rafx-metal",
515                    feature = "rafx-vulkan",
516                    feature = "rafx-gles2",
517                    feature = "rafx-gles3"
518                ))
519            ))]
520            RafxDeviceContext::Empty(inner) => RafxBuffer::Empty(inner.create_buffer(buffer_def)?),
521        })
522    }
523
524    pub fn create_shader_module(
525        &self,
526        shader_module_def: RafxShaderModuleDef,
527    ) -> RafxResult<RafxShaderModule> {
528        Ok(match self {
529            #[cfg(feature = "rafx-dx12")]
530            RafxDeviceContext::Dx12(inner) => {
531                RafxShaderModule::Dx12(inner.create_shader_module(shader_module_def.dx12.unwrap())?)
532            }
533            #[cfg(feature = "rafx-vulkan")]
534            RafxDeviceContext::Vk(inner) => {
535                RafxShaderModule::Vk(inner.create_shader_module(shader_module_def.vk.unwrap())?)
536            }
537            #[cfg(feature = "rafx-metal")]
538            RafxDeviceContext::Metal(inner) => RafxShaderModule::Metal(
539                inner.create_shader_module(shader_module_def.metal.unwrap())?,
540            ),
541            #[cfg(feature = "rafx-gles2")]
542            RafxDeviceContext::Gles2(inner) => RafxShaderModule::Gles2(
543                inner.create_shader_module(shader_module_def.gles2.unwrap())?,
544            ),
545            #[cfg(feature = "rafx-gles3")]
546            RafxDeviceContext::Gles3(inner) => RafxShaderModule::Gles3(
547                inner.create_shader_module(shader_module_def.gles3.unwrap())?,
548            ),
549            #[cfg(any(
550                feature = "rafx-empty",
551                not(any(
552                    feature = "rafx-dx12",
553                    feature = "rafx-metal",
554                    feature = "rafx-vulkan",
555                    feature = "rafx-gles2",
556                    feature = "rafx-gles3",
557                ))
558            ))]
559            RafxDeviceContext::Empty(inner) => RafxShaderModule::Empty(
560                inner.create_shader_module(shader_module_def.empty.unwrap())?,
561            ),
562        })
563    }
564
565    //TODO: Consider a struct with each kind of shader stage instead of a vec of stages
566    /// Create a shader
567    pub fn create_shader(
568        &self,
569        stages: Vec<RafxShaderStageDef>,
570    ) -> RafxResult<RafxShader> {
571        Ok(match self {
572            #[cfg(feature = "rafx-dx12")]
573            RafxDeviceContext::Dx12(inner) => RafxShader::Dx12(inner.create_shader(stages)?),
574            #[cfg(feature = "rafx-vulkan")]
575            RafxDeviceContext::Vk(inner) => RafxShader::Vk(inner.create_shader(stages)?),
576            #[cfg(feature = "rafx-metal")]
577            RafxDeviceContext::Metal(inner) => RafxShader::Metal(inner.create_shader(stages)?),
578            #[cfg(feature = "rafx-gles2")]
579            RafxDeviceContext::Gles2(inner) => RafxShader::Gles2(inner.create_shader(stages)?),
580            #[cfg(feature = "rafx-gles3")]
581            RafxDeviceContext::Gles3(inner) => RafxShader::Gles3(inner.create_shader(stages)?),
582            #[cfg(any(
583                feature = "rafx-empty",
584                not(any(
585                    feature = "rafx-dx12",
586                    feature = "rafx-metal",
587                    feature = "rafx-vulkan",
588                    feature = "rafx-gles2",
589                    feature = "rafx-gles3",
590                ))
591            ))]
592            RafxDeviceContext::Empty(inner) => RafxShader::Empty(inner.create_shader(stages)?),
593        })
594    }
595
596    /// Create a root signature
597    pub fn create_root_signature(
598        &self,
599        root_signature_def: &RafxRootSignatureDef,
600    ) -> RafxResult<RafxRootSignature> {
601        Ok(match self {
602            #[cfg(feature = "rafx-dx12")]
603            RafxDeviceContext::Dx12(inner) => {
604                RafxRootSignature::Dx12(inner.create_root_signature(root_signature_def)?)
605            }
606            #[cfg(feature = "rafx-vulkan")]
607            RafxDeviceContext::Vk(inner) => {
608                RafxRootSignature::Vk(inner.create_root_signature(root_signature_def)?)
609            }
610            #[cfg(feature = "rafx-metal")]
611            RafxDeviceContext::Metal(inner) => {
612                RafxRootSignature::Metal(inner.create_root_signature(root_signature_def)?)
613            }
614            #[cfg(feature = "rafx-gles2")]
615            RafxDeviceContext::Gles2(inner) => {
616                RafxRootSignature::Gles2(inner.create_root_signature(root_signature_def)?)
617            }
618            #[cfg(feature = "rafx-gles3")]
619            RafxDeviceContext::Gles3(inner) => {
620                RafxRootSignature::Gles3(inner.create_root_signature(root_signature_def)?)
621            }
622            #[cfg(any(
623                feature = "rafx-empty",
624                not(any(
625                    feature = "rafx-dx12",
626                    feature = "rafx-metal",
627                    feature = "rafx-vulkan",
628                    feature = "rafx-gles2",
629                    feature = "rafx-gles3"
630                ))
631            ))]
632            RafxDeviceContext::Empty(inner) => {
633                RafxRootSignature::Empty(inner.create_root_signature(root_signature_def)?)
634            }
635        })
636    }
637
638    /// Create a graphics pipeline
639    pub fn create_graphics_pipeline(
640        &self,
641        pipeline_def: &RafxGraphicsPipelineDef,
642    ) -> RafxResult<RafxPipeline> {
643        Ok(match self {
644            #[cfg(feature = "rafx-dx12")]
645            RafxDeviceContext::Dx12(inner) => {
646                RafxPipeline::Dx12(inner.create_graphics_pipeline(pipeline_def)?)
647            }
648            #[cfg(feature = "rafx-vulkan")]
649            RafxDeviceContext::Vk(inner) => {
650                RafxPipeline::Vk(inner.create_graphics_pipeline(pipeline_def)?)
651            }
652            #[cfg(feature = "rafx-metal")]
653            RafxDeviceContext::Metal(inner) => {
654                RafxPipeline::Metal(inner.create_graphics_pipeline(pipeline_def)?)
655            }
656            #[cfg(feature = "rafx-gles2")]
657            RafxDeviceContext::Gles2(inner) => {
658                RafxPipeline::Gles2(inner.create_graphics_pipeline(pipeline_def)?)
659            }
660            #[cfg(feature = "rafx-gles3")]
661            RafxDeviceContext::Gles3(inner) => {
662                RafxPipeline::Gles3(inner.create_graphics_pipeline(pipeline_def)?)
663            }
664            #[cfg(any(
665                feature = "rafx-empty",
666                not(any(
667                    feature = "rafx-dx12",
668                    feature = "rafx-metal",
669                    feature = "rafx-vulkan",
670                    feature = "rafx-gles2",
671                    feature = "rafx-gles3"
672                ))
673            ))]
674            RafxDeviceContext::Empty(inner) => {
675                RafxPipeline::Empty(inner.create_graphics_pipeline(pipeline_def)?)
676            }
677        })
678    }
679
680    /// Create a compute pipeline
681    pub fn create_compute_pipeline(
682        &self,
683        pipeline_def: &RafxComputePipelineDef,
684    ) -> RafxResult<RafxPipeline> {
685        Ok(match self {
686            #[cfg(feature = "rafx-dx12")]
687            RafxDeviceContext::Dx12(inner) => {
688                RafxPipeline::Dx12(inner.create_compute_pipeline(pipeline_def)?)
689            }
690            #[cfg(feature = "rafx-vulkan")]
691            RafxDeviceContext::Vk(inner) => {
692                RafxPipeline::Vk(inner.create_compute_pipeline(pipeline_def)?)
693            }
694            #[cfg(feature = "rafx-metal")]
695            RafxDeviceContext::Metal(inner) => {
696                RafxPipeline::Metal(inner.create_compute_pipeline(pipeline_def)?)
697            }
698            #[cfg(feature = "rafx-gles2")]
699            RafxDeviceContext::Gles2(inner) => {
700                RafxPipeline::Gles2(inner.create_compute_pipeline(pipeline_def)?)
701            }
702            #[cfg(feature = "rafx-gles3")]
703            RafxDeviceContext::Gles3(inner) => {
704                RafxPipeline::Gles3(inner.create_compute_pipeline(pipeline_def)?)
705            }
706            #[cfg(any(
707                feature = "rafx-empty",
708                not(any(
709                    feature = "rafx-dx12",
710                    feature = "rafx-metal",
711                    feature = "rafx-vulkan",
712                    feature = "rafx-gles2",
713                    feature = "rafx-gles3"
714                ))
715            ))]
716            RafxDeviceContext::Empty(inner) => {
717                RafxPipeline::Empty(inner.create_compute_pipeline(pipeline_def)?)
718            }
719        })
720    }
721
722    /// Create a descriptor set array
723    pub fn create_descriptor_set_array(
724        &self,
725        descriptor_set_array_def: &RafxDescriptorSetArrayDef,
726    ) -> RafxResult<RafxDescriptorSetArray> {
727        Ok(match self {
728            #[cfg(feature = "rafx-dx12")]
729            RafxDeviceContext::Dx12(inner) => RafxDescriptorSetArray::Dx12(
730                inner.create_descriptor_set_array(descriptor_set_array_def)?,
731            ),
732            #[cfg(feature = "rafx-vulkan")]
733            RafxDeviceContext::Vk(inner) => RafxDescriptorSetArray::Vk(
734                inner.create_descriptor_set_array(descriptor_set_array_def)?,
735            ),
736            #[cfg(feature = "rafx-metal")]
737            RafxDeviceContext::Metal(inner) => RafxDescriptorSetArray::Metal(
738                inner.create_descriptor_set_array(descriptor_set_array_def)?,
739            ),
740            #[cfg(feature = "rafx-gles2")]
741            RafxDeviceContext::Gles2(inner) => RafxDescriptorSetArray::Gles2(
742                inner.create_descriptor_set_array(descriptor_set_array_def)?,
743            ),
744            #[cfg(feature = "rafx-gles3")]
745            RafxDeviceContext::Gles3(inner) => RafxDescriptorSetArray::Gles3(
746                inner.create_descriptor_set_array(descriptor_set_array_def)?,
747            ),
748            #[cfg(any(
749                feature = "rafx-empty",
750                not(any(
751                    feature = "rafx-dx12",
752                    feature = "rafx-metal",
753                    feature = "rafx-vulkan",
754                    feature = "rafx-gles2",
755                    feature = "rafx-gles3"
756                ))
757            ))]
758            RafxDeviceContext::Empty(inner) => RafxDescriptorSetArray::Empty(
759                inner.create_descriptor_set_array(descriptor_set_array_def)?,
760            ),
761        })
762    }
763
764    /// Get the underlying vulkan API object. This provides access to any internally created
765    /// vulkan objects.
766    #[cfg(feature = "rafx-dx12")]
767    pub fn dx12_device_context(&self) -> Option<&RafxDeviceContextDx12> {
768        match self {
769            #[cfg(feature = "rafx-dx12")]
770            RafxDeviceContext::Dx12(inner) => Some(inner),
771            #[cfg(feature = "rafx-vulkan")]
772            RafxDeviceContext::Vk(_) => None,
773            #[cfg(feature = "rafx-metal")]
774            RafxDeviceContext::Metal(_) => None,
775            #[cfg(feature = "rafx-gles2")]
776            RafxDeviceContext::Gles2(_) => None,
777            #[cfg(feature = "rafx-gles3")]
778            RafxDeviceContext::Gles3(_) => None,
779            #[cfg(any(
780                feature = "rafx-empty",
781                not(any(
782                    feature = "rafx-dx12",
783                    feature = "rafx-metal",
784                    feature = "rafx-vulkan",
785                    feature = "rafx-gles2",
786                    feature = "rafx-gles3"
787                ))
788            ))]
789            RafxDeviceContext::Empty(_) => None,
790        }
791    }
792
793    /// Get the underlying vulkan API object. This provides access to any internally created
794    /// vulkan objects.
795    #[cfg(feature = "rafx-vulkan")]
796    pub fn vk_device_context(&self) -> Option<&RafxDeviceContextVulkan> {
797        match self {
798            #[cfg(feature = "rafx-dx12")]
799            RafxDeviceContext::Dx12(_) => None,
800            #[cfg(feature = "rafx-vulkan")]
801            RafxDeviceContext::Vk(inner) => Some(inner),
802            #[cfg(feature = "rafx-metal")]
803            RafxDeviceContext::Metal(_) => None,
804            #[cfg(feature = "rafx-gles2")]
805            RafxDeviceContext::Gles2(_) => None,
806            #[cfg(feature = "rafx-gles3")]
807            RafxDeviceContext::Gles3(_) => None,
808            #[cfg(any(
809                feature = "rafx-empty",
810                not(any(
811                    feature = "rafx-dx12",
812                    feature = "rafx-metal",
813                    feature = "rafx-vulkan",
814                    feature = "rafx-gles2",
815                    feature = "rafx-gles3"
816                ))
817            ))]
818            RafxDeviceContext::Empty(_) => None,
819        }
820    }
821
822    /// Get the underlying metal API object. This provides access to any internally created
823    /// metal objects.
824    #[cfg(feature = "rafx-metal")]
825    pub fn metal_device_context(&self) -> Option<&RafxDeviceContextMetal> {
826        match self {
827            #[cfg(feature = "rafx-dx12")]
828            RafxDeviceContext::Dx12(_) => None,
829            #[cfg(feature = "rafx-vulkan")]
830            RafxDeviceContext::Vk(_) => None,
831            #[cfg(feature = "rafx-metal")]
832            RafxDeviceContext::Metal(inner) => Some(inner),
833            #[cfg(feature = "rafx-gles2")]
834            RafxDeviceContext::Gles2(_) => None,
835            #[cfg(feature = "rafx-gles3")]
836            RafxDeviceContext::Gles3(_) => None,
837            #[cfg(any(
838                feature = "rafx-empty",
839                not(any(
840                    feature = "rafx-dx12",
841                    feature = "rafx-metal",
842                    feature = "rafx-vulkan",
843                    feature = "rafx-gles2",
844                    feature = "rafx-gles3"
845                ))
846            ))]
847            RafxDeviceContext::Empty(_) => None,
848        }
849    }
850
851    /// Get the underlying gl API object. This provides access to any internally created
852    /// metal objects.
853    #[cfg(feature = "rafx-gles2")]
854    pub fn gles2_device_context(&self) -> Option<&RafxDeviceContextGles2> {
855        match self {
856            #[cfg(feature = "rafx-dx12")]
857            RafxDeviceContext::Dx12(_) => None,
858            #[cfg(feature = "rafx-vulkan")]
859            RafxDeviceContext::Vk(_) => None,
860            #[cfg(feature = "rafx-metal")]
861            RafxDeviceContext::Metal(_) => None,
862            #[cfg(feature = "rafx-gles2")]
863            RafxDeviceContext::Gles2(inner) => Some(inner),
864            #[cfg(feature = "rafx-gles3")]
865            RafxDeviceContext::Gles3(_) => None,
866            #[cfg(any(
867                feature = "rafx-empty",
868                not(any(
869                    feature = "rafx-dx12",
870                    feature = "rafx-metal",
871                    feature = "rafx-vulkan",
872                    feature = "rafx-gles2",
873                    feature = "rafx-gles3"
874                ))
875            ))]
876            RafxDeviceContext::Empty(_) => None,
877        }
878    }
879
880    /// Get the underlying gl API object. This provides access to any internally created
881    /// metal objects.
882    #[cfg(feature = "rafx-gles3")]
883    pub fn gles3_device_context(&self) -> Option<&RafxDeviceContextGles3> {
884        match self {
885            #[cfg(feature = "rafx-dx12")]
886            RafxDeviceContext::Dx12(_) => None,
887            #[cfg(feature = "rafx-vulkan")]
888            RafxDeviceContext::Vk(_) => None,
889            #[cfg(feature = "rafx-metal")]
890            RafxDeviceContext::Metal(_) => None,
891            #[cfg(feature = "rafx-gles2")]
892            RafxDeviceContext::Gles2(_) => None,
893            #[cfg(feature = "rafx-gles3")]
894            RafxDeviceContext::Gles3(inner) => Some(inner),
895            #[cfg(any(
896                feature = "rafx-empty",
897                not(any(
898                    feature = "rafx-dx12",
899                    feature = "rafx-metal",
900                    feature = "rafx-vulkan",
901                    feature = "rafx-gles2",
902                    feature = "rafx-gles3"
903                ))
904            ))]
905            RafxDeviceContext::Empty(_) => None,
906        }
907    }
908
909    /// Get the underlying metal API object. This provides access to any internally created
910    /// metal objects.
911    #[cfg(any(
912        feature = "rafx-empty",
913        not(any(
914            feature = "rafx-dx12",
915            feature = "rafx-metal",
916            feature = "rafx-vulkan",
917            feature = "rafx-gles2",
918            feature = "rafx-gles3"
919        ))
920    ))]
921    pub fn empty_device_context(&self) -> Option<&RafxDeviceContextEmpty> {
922        match self {
923            #[cfg(feature = "rafx-dx12")]
924            RafxDeviceContext::Dx12(_) => None,
925            #[cfg(feature = "rafx-vulkan")]
926            RafxDeviceContext::Vk(_) => None,
927            #[cfg(feature = "rafx-metal")]
928            RafxDeviceContext::Metal(_) => None,
929            #[cfg(feature = "rafx-gles2")]
930            RafxDeviceContext::Gles2(_) => None,
931            #[cfg(feature = "rafx-gles3")]
932            RafxDeviceContext::Gles3(_) => None,
933            #[cfg(any(
934                feature = "rafx-empty",
935                not(any(
936                    feature = "rafx-dx12",
937                    feature = "rafx-metal",
938                    feature = "rafx-vulkan",
939                    feature = "rafx-gles2",
940                    feature = "rafx-gles3"
941                ))
942            ))]
943            RafxDeviceContext::Empty(inner) => Some(inner),
944        }
945    }
946}