rafx_api/
descriptor_set_array.rs

1#[cfg(feature = "rafx-dx12")]
2use crate::dx12::{RafxDescriptorSetArrayDx12, RafxDescriptorSetHandleDx12};
3#[cfg(any(
4    feature = "rafx-empty",
5    not(any(
6        feature = "rafx-dx12",
7        feature = "rafx-metal",
8        feature = "rafx-vulkan",
9        feature = "rafx-gles2",
10        feature = "rafx-gles3"
11    ))
12))]
13use crate::empty::{RafxDescriptorSetArrayEmpty, RafxDescriptorSetHandleEmpty};
14#[cfg(feature = "rafx-gles2")]
15use crate::gles2::{RafxDescriptorSetArrayGles2, RafxDescriptorSetHandleGles2};
16#[cfg(feature = "rafx-gles3")]
17use crate::gles3::{RafxDescriptorSetArrayGles3, RafxDescriptorSetHandleGles3};
18#[cfg(feature = "rafx-metal")]
19use crate::metal::{RafxDescriptorSetArrayMetal, RafxDescriptorSetHandleMetal};
20#[cfg(feature = "rafx-vulkan")]
21use crate::vulkan::{RafxDescriptorSetArrayVulkan, RafxDescriptorSetHandleVulkan};
22use crate::{RafxDescriptorUpdate, RafxResult, RafxRootSignature};
23
24/// A lightweight handle to a specific descriptor set in a `RafxDescriptorSetArray`.
25///
26/// Modifying a descriptor set in a `RafxDescriptorSetArray` requires mutable access to the array.
27/// However, many times in an application it is necessary to obtain and use references to
28/// individual descriptor sets. These descriptor sets are not used or even accessed by the CPU, they
29/// are just handles that need to be provided to the GPU.
30///
31/// A `RafxDescriptorSetHandle` can be used to reference descriptor sets and bind them to command
32/// buffers from different threads.
33///
34/// This object is generally speaking optional. A single-threaded application can use
35/// `RafxDescriptorSetArray` directly at any time.
36#[derive(Clone, Debug)]
37pub enum RafxDescriptorSetHandle {
38    #[cfg(feature = "rafx-dx12")]
39    Dx12(RafxDescriptorSetHandleDx12),
40    #[cfg(feature = "rafx-vulkan")]
41    Vk(RafxDescriptorSetHandleVulkan),
42    #[cfg(feature = "rafx-metal")]
43    Metal(RafxDescriptorSetHandleMetal),
44    #[cfg(feature = "rafx-gles2")]
45    Gles2(RafxDescriptorSetHandleGles2),
46    #[cfg(feature = "rafx-gles3")]
47    Gles3(RafxDescriptorSetHandleGles3),
48    #[cfg(any(
49        feature = "rafx-empty",
50        not(any(
51            feature = "rafx-dx12",
52            feature = "rafx-metal",
53            feature = "rafx-vulkan",
54            feature = "rafx-gles2",
55            feature = "rafx-gles3"
56        ))
57    ))]
58    Empty(RafxDescriptorSetHandleEmpty),
59}
60
61impl RafxDescriptorSetHandle {
62    #[cfg(feature = "rafx-dx12")]
63    pub fn dx12_descriptor_set_handle(&self) -> Option<&RafxDescriptorSetHandleDx12> {
64        match self {
65            #[cfg(feature = "rafx-dx12")]
66            RafxDescriptorSetHandle::Dx12(inner) => Some(inner),
67            #[cfg(feature = "rafx-vulkan")]
68            RafxDescriptorSetHandle::Vk(_) => None,
69            #[cfg(feature = "rafx-metal")]
70            RafxDescriptorSetHandle::Metal(_) => None,
71            #[cfg(feature = "rafx-gles2")]
72            RafxDescriptorSetHandle::Gles2(_) => None,
73            #[cfg(feature = "rafx-gles3")]
74            RafxDescriptorSetHandle::Gles3(_) => None,
75            #[cfg(any(
76                feature = "rafx-empty",
77                not(any(
78                    feature = "rafx-dx12",
79                    feature = "rafx-metal",
80                    feature = "rafx-vulkan",
81                    feature = "rafx-gles2",
82                    feature = "rafx-gles3"
83                ))
84            ))]
85            RafxDescriptorSetHandle::Empty(_) => None,
86        }
87    }
88
89    #[cfg(feature = "rafx-vulkan")]
90    pub fn vk_descriptor_set_handle(&self) -> Option<&RafxDescriptorSetHandleVulkan> {
91        match self {
92            #[cfg(feature = "rafx-dx12")]
93            RafxDescriptorSetHandle::Dx12(_) => None,
94            #[cfg(feature = "rafx-vulkan")]
95            RafxDescriptorSetHandle::Vk(inner) => Some(inner),
96            #[cfg(feature = "rafx-metal")]
97            RafxDescriptorSetHandle::Metal(_) => None,
98            #[cfg(feature = "rafx-gles2")]
99            RafxDescriptorSetHandle::Gles2(_) => None,
100            #[cfg(feature = "rafx-gles3")]
101            RafxDescriptorSetHandle::Gles3(_) => None,
102            #[cfg(any(
103                feature = "rafx-empty",
104                not(any(
105                    feature = "rafx-dx12",
106                    feature = "rafx-metal",
107                    feature = "rafx-vulkan",
108                    feature = "rafx-gles2",
109                    feature = "rafx-gles3"
110                ))
111            ))]
112            RafxDescriptorSetHandle::Empty(_) => None,
113        }
114    }
115
116    #[cfg(feature = "rafx-metal")]
117    pub fn metal_descriptor_set_handle(&self) -> Option<&RafxDescriptorSetHandleMetal> {
118        match self {
119            #[cfg(feature = "rafx-dx12")]
120            RafxDescriptorSetHandle::Dx12(_) => None,
121            #[cfg(feature = "rafx-vulkan")]
122            RafxDescriptorSetHandle::Vk(_) => None,
123            #[cfg(feature = "rafx-metal")]
124            RafxDescriptorSetHandle::Metal(inner) => Some(inner),
125            #[cfg(feature = "rafx-gles2")]
126            RafxDescriptorSetHandle::Gles2(_) => None,
127            #[cfg(feature = "rafx-gles3")]
128            RafxDescriptorSetHandle::Gles3(_) => None,
129            #[cfg(any(
130                feature = "rafx-empty",
131                not(any(
132                    feature = "rafx-dx12",
133                    feature = "rafx-metal",
134                    feature = "rafx-vulkan",
135                    feature = "rafx-gles2",
136                    feature = "rafx-gles3"
137                ))
138            ))]
139            RafxDescriptorSetHandle::Empty(_) => None,
140        }
141    }
142
143    #[cfg(feature = "rafx-gles2")]
144    pub fn gles2_descriptor_set_handle(&self) -> Option<&RafxDescriptorSetHandleGles2> {
145        match self {
146            #[cfg(feature = "rafx-dx12")]
147            RafxDescriptorSetHandle::Dx12(_) => None,
148            #[cfg(feature = "rafx-vulkan")]
149            RafxDescriptorSetHandle::Vk(_) => None,
150            #[cfg(feature = "rafx-metal")]
151            RafxDescriptorSetHandle::Metal(_) => None,
152            #[cfg(feature = "rafx-gles2")]
153            RafxDescriptorSetHandle::Gles2(inner) => Some(inner),
154            #[cfg(feature = "rafx-gles3")]
155            RafxDescriptorSetHandle::Gles3(_) => None,
156            #[cfg(any(
157                feature = "rafx-empty",
158                not(any(
159                    feature = "rafx-dx12",
160                    feature = "rafx-metal",
161                    feature = "rafx-vulkan",
162                    feature = "rafx-gles2",
163                    feature = "rafx-gles3"
164                ))
165            ))]
166            RafxDescriptorSetHandle::Empty(_) => None,
167        }
168    }
169
170    #[cfg(feature = "rafx-gles3")]
171    pub fn gles3_descriptor_set_handle(&self) -> Option<&RafxDescriptorSetHandleGles3> {
172        match self {
173            #[cfg(feature = "rafx-dx12")]
174            RafxDescriptorSetHandle::Dx12(_) => None,
175            #[cfg(feature = "rafx-vulkan")]
176            RafxDescriptorSetHandle::Vk(_) => None,
177            #[cfg(feature = "rafx-metal")]
178            RafxDescriptorSetHandle::Metal(_) => None,
179            #[cfg(feature = "rafx-gles2")]
180            RafxDescriptorSetHandle::Gles2(_) => None,
181            #[cfg(feature = "rafx-gles3")]
182            RafxDescriptorSetHandle::Gles3(inner) => Some(inner),
183            #[cfg(any(
184                feature = "rafx-empty",
185                not(any(
186                    feature = "rafx-dx12",
187                    feature = "rafx-metal",
188                    feature = "rafx-vulkan",
189                    feature = "rafx-gles2",
190                    feature = "rafx-gles3"
191                ))
192            ))]
193            RafxDescriptorSetHandle::Empty(_) => None,
194        }
195    }
196
197    #[cfg(any(
198        feature = "rafx-empty",
199        not(any(
200            feature = "rafx-dx12",
201            feature = "rafx-metal",
202            feature = "rafx-vulkan",
203            feature = "rafx-gles2",
204            feature = "rafx-gles3"
205        ))
206    ))]
207    pub fn empty_descriptor_set_handle(&self) -> Option<&RafxDescriptorSetHandleEmpty> {
208        match self {
209            #[cfg(feature = "rafx-dx12")]
210            RafxDescriptorSetHandle::Dx12(_) => None,
211            #[cfg(feature = "rafx-vulkan")]
212            RafxDescriptorSetHandle::Vk(_) => None,
213            #[cfg(feature = "rafx-metal")]
214            RafxDescriptorSetHandle::Metal(_) => None,
215            #[cfg(feature = "rafx-gles2")]
216            RafxDescriptorSetHandle::Gles2(_) => None,
217            #[cfg(feature = "rafx-gles3")]
218            RafxDescriptorSetHandle::Gles3(_) => None,
219            #[cfg(any(
220                feature = "rafx-empty",
221                not(any(
222                    feature = "rafx-dx12",
223                    feature = "rafx-metal",
224                    feature = "rafx-vulkan",
225                    feature = "rafx-gles2",
226                    feature = "rafx-gles3"
227                ))
228            ))]
229            RafxDescriptorSetHandle::Empty(inner) => Some(inner),
230        }
231    }
232}
233
234/// An array of descriptor sets. These are expected to be pooled and reused.
235///
236/// Managing descriptor sets can be challenging and there are many strategies that may be used. So
237/// a `RafxDescriptorSetArray` is intended to be allocated in blocks and pooled. This allows
238/// downstream code to provide more fine-grained allocation strategies appropriate to their needs.
239///
240/// Higher level crates in rafx-framework provide ref-counted descriptor sets and pooling.
241///
242/// Once a RafxDescriptorSetArray is allocated, depending on the backend, it may remain allocated
243/// for the duration of the API object, even if the descriptor set array is dropped. So rather than
244/// drop them, pool and reuse them.
245///
246/// Descriptor sets are like pointers to GPU memory. A command buffer can bind a descriptor set,
247/// meaning that other command may access resources that the descriptor set references.
248///
249/// Once a command buffer using a descriptor set has been submitted, it must not be modified until
250/// the command buffer is finished executing. Fine-grained synchronization primitives allow this
251/// restriction to be loosened.
252///
253/// **Using an incorrectly configured descriptor set can result in undefined behavior. In practice,
254/// this can include GPU hangs, driver crashes, and kernel panics**.
255#[derive(Debug)]
256pub enum RafxDescriptorSetArray {
257    #[cfg(feature = "rafx-dx12")]
258    Dx12(RafxDescriptorSetArrayDx12),
259    #[cfg(feature = "rafx-vulkan")]
260    Vk(RafxDescriptorSetArrayVulkan),
261    #[cfg(feature = "rafx-metal")]
262    Metal(RafxDescriptorSetArrayMetal),
263    #[cfg(feature = "rafx-gles2")]
264    Gles2(RafxDescriptorSetArrayGles2),
265    #[cfg(feature = "rafx-gles3")]
266    Gles3(RafxDescriptorSetArrayGles3),
267    #[cfg(any(
268        feature = "rafx-empty",
269        not(any(
270            feature = "rafx-dx12",
271            feature = "rafx-metal",
272            feature = "rafx-vulkan",
273            feature = "rafx-gles2",
274            feature = "rafx-gles3"
275        ))
276    ))]
277    Empty(RafxDescriptorSetArrayEmpty),
278}
279
280impl RafxDescriptorSetArray {
281    /// Create a lightweight, opaque pointer to a particular set in the array. This pointer can only
282    /// be used for binding the given set in a command buffer.
283    pub fn handle(
284        &self,
285        index: u32,
286    ) -> Option<RafxDescriptorSetHandle> {
287        Some(match self {
288            #[cfg(feature = "rafx-dx12")]
289            RafxDescriptorSetArray::Dx12(inner) => {
290                RafxDescriptorSetHandle::Dx12(inner.handle(index)?)
291            }
292            #[cfg(feature = "rafx-vulkan")]
293            RafxDescriptorSetArray::Vk(inner) => RafxDescriptorSetHandle::Vk(inner.handle(index)?),
294            #[cfg(feature = "rafx-metal")]
295            RafxDescriptorSetArray::Metal(inner) => {
296                RafxDescriptorSetHandle::Metal(inner.handle(index)?)
297            }
298            #[cfg(feature = "rafx-gles2")]
299            RafxDescriptorSetArray::Gles2(inner) => {
300                RafxDescriptorSetHandle::Gles2(inner.handle(index)?)
301            }
302            #[cfg(feature = "rafx-gles3")]
303            RafxDescriptorSetArray::Gles3(inner) => {
304                RafxDescriptorSetHandle::Gles3(inner.handle(index)?)
305            }
306            #[cfg(any(
307                feature = "rafx-empty",
308                not(any(
309                    feature = "rafx-dx12",
310                    feature = "rafx-metal",
311                    feature = "rafx-vulkan",
312                    feature = "rafx-gles2",
313                    feature = "rafx-gles3"
314                ))
315            ))]
316            RafxDescriptorSetArray::Empty(inner) => {
317                RafxDescriptorSetHandle::Empty(inner.handle(index)?)
318            }
319        })
320    }
321
322    /// Get the root signature that this descriptor set is created from
323    pub fn root_signature(&self) -> &RafxRootSignature {
324        match self {
325            #[cfg(feature = "rafx-dx12")]
326            RafxDescriptorSetArray::Dx12(inner) => inner.root_signature(),
327            #[cfg(feature = "rafx-vulkan")]
328            RafxDescriptorSetArray::Vk(inner) => inner.root_signature(),
329            #[cfg(feature = "rafx-metal")]
330            RafxDescriptorSetArray::Metal(inner) => inner.root_signature(),
331            #[cfg(feature = "rafx-gles2")]
332            RafxDescriptorSetArray::Gles2(inner) => inner.root_signature(),
333            #[cfg(feature = "rafx-gles3")]
334            RafxDescriptorSetArray::Gles3(inner) => inner.root_signature(),
335            #[cfg(any(
336                feature = "rafx-empty",
337                not(any(
338                    feature = "rafx-dx12",
339                    feature = "rafx-metal",
340                    feature = "rafx-vulkan",
341                    feature = "rafx-gles2",
342                    feature = "rafx-gles3"
343                ))
344            ))]
345            RafxDescriptorSetArray::Empty(inner) => inner.root_signature(),
346        }
347    }
348
349    /// Update one or more descriptor sets with new values. This is the same as calling
350    /// queue_descriptor_set_update, followed by flush_descriptor_set_updates
351    pub fn update_descriptor_set(
352        &mut self,
353        params: &[RafxDescriptorUpdate],
354    ) -> RafxResult<()> {
355        match self {
356            #[cfg(feature = "rafx-dx12")]
357            RafxDescriptorSetArray::Dx12(inner) => inner.update_descriptor_set(params),
358            #[cfg(feature = "rafx-vulkan")]
359            RafxDescriptorSetArray::Vk(inner) => inner.update_descriptor_set(params),
360            #[cfg(feature = "rafx-metal")]
361            RafxDescriptorSetArray::Metal(inner) => inner.update_descriptor_set(params),
362            #[cfg(feature = "rafx-gles2")]
363            RafxDescriptorSetArray::Gles2(inner) => inner.update_descriptor_set(params),
364            #[cfg(feature = "rafx-gles3")]
365            RafxDescriptorSetArray::Gles3(inner) => inner.update_descriptor_set(params),
366            #[cfg(any(
367                feature = "rafx-empty",
368                not(any(
369                    feature = "rafx-dx12",
370                    feature = "rafx-metal",
371                    feature = "rafx-vulkan",
372                    feature = "rafx-gles2",
373                    feature = "rafx-gles3"
374                ))
375            ))]
376            RafxDescriptorSetArray::Empty(inner) => inner.update_descriptor_set(params),
377        }
378    }
379
380    /// Update a CPU-only copy of the descriptor set, but does not apply the write to the descriptor
381    /// set until flush_descriptor_set_updates() is called.
382    ///
383    /// The main reason for allowing queueing/flushing in separate calls is to help calling code
384    /// avoid borrow-checking difficulties.
385    pub fn queue_descriptor_set_update(
386        &mut self,
387        update: &RafxDescriptorUpdate,
388    ) -> RafxResult<()> {
389        match self {
390            #[cfg(feature = "rafx-dx12")]
391            RafxDescriptorSetArray::Dx12(inner) => inner.queue_descriptor_set_update(update),
392            #[cfg(feature = "rafx-vulkan")]
393            RafxDescriptorSetArray::Vk(inner) => inner.queue_descriptor_set_update(update),
394            #[cfg(feature = "rafx-metal")]
395            RafxDescriptorSetArray::Metal(inner) => inner.queue_descriptor_set_update(update),
396            #[cfg(feature = "rafx-gles2")]
397            RafxDescriptorSetArray::Gles2(inner) => inner.queue_descriptor_set_update(update),
398            #[cfg(feature = "rafx-gles3")]
399            RafxDescriptorSetArray::Gles3(inner) => inner.queue_descriptor_set_update(update),
400            #[cfg(any(
401                feature = "rafx-empty",
402                not(any(
403                    feature = "rafx-dx12",
404                    feature = "rafx-metal",
405                    feature = "rafx-vulkan",
406                    feature = "rafx-gles2",
407                    feature = "rafx-gles3"
408                ))
409            ))]
410            RafxDescriptorSetArray::Empty(inner) => inner.queue_descriptor_set_update(update),
411        }
412    }
413
414    /// Flush all queued descriptor set writes
415    pub fn flush_descriptor_set_updates(&mut self) -> RafxResult<()> {
416        match self {
417            #[cfg(feature = "rafx-dx12")]
418            RafxDescriptorSetArray::Dx12(inner) => inner.flush_descriptor_set_updates(),
419            #[cfg(feature = "rafx-vulkan")]
420            RafxDescriptorSetArray::Vk(inner) => inner.flush_descriptor_set_updates(),
421            #[cfg(feature = "rafx-metal")]
422            RafxDescriptorSetArray::Metal(inner) => inner.flush_descriptor_set_updates(),
423            #[cfg(feature = "rafx-gles2")]
424            RafxDescriptorSetArray::Gles2(inner) => inner.flush_descriptor_set_updates(),
425            #[cfg(feature = "rafx-gles3")]
426            RafxDescriptorSetArray::Gles3(inner) => inner.flush_descriptor_set_updates(),
427            #[cfg(any(
428                feature = "rafx-empty",
429                not(any(
430                    feature = "rafx-dx12",
431                    feature = "rafx-metal",
432                    feature = "rafx-vulkan",
433                    feature = "rafx-gles2",
434                    feature = "rafx-gles3"
435                ))
436            ))]
437            RafxDescriptorSetArray::Empty(inner) => inner.flush_descriptor_set_updates(),
438        }
439    }
440
441    /// Get the underlying dx12 API object. This provides access to any internally created
442    /// vulkan objects.
443    #[cfg(feature = "rafx-dx12")]
444    pub fn dx12_descriptor_set_array(&self) -> Option<&RafxDescriptorSetArrayDx12> {
445        match self {
446            #[cfg(feature = "rafx-dx12")]
447            RafxDescriptorSetArray::Dx12(inner) => Some(inner),
448            #[cfg(feature = "rafx-vulkan")]
449            RafxDescriptorSetArray::Vk(_) => None,
450            #[cfg(feature = "rafx-metal")]
451            RafxDescriptorSetArray::Metal(_) => None,
452            #[cfg(feature = "rafx-gles2")]
453            RafxDescriptorSetArray::Gles2(_) => None,
454            #[cfg(feature = "rafx-gles3")]
455            RafxDescriptorSetArray::Gles3(_) => None,
456            #[cfg(any(
457                feature = "rafx-empty",
458                not(any(
459                    feature = "rafx-dx12",
460                    feature = "rafx-metal",
461                    feature = "rafx-vulkan",
462                    feature = "rafx-gles2",
463                    feature = "rafx-gles3"
464                ))
465            ))]
466            RafxDescriptorSetArray::Empty(_) => None,
467        }
468    }
469
470    /// Get the underlying vulkan API object. This provides access to any internally created
471    /// vulkan objects.
472    #[cfg(feature = "rafx-vulkan")]
473    pub fn vk_descriptor_set_array(&self) -> Option<&RafxDescriptorSetArrayVulkan> {
474        match self {
475            #[cfg(feature = "rafx-dx12")]
476            RafxDescriptorSetArray::Dx12(_) => None,
477            #[cfg(feature = "rafx-vulkan")]
478            RafxDescriptorSetArray::Vk(inner) => Some(inner),
479            #[cfg(feature = "rafx-metal")]
480            RafxDescriptorSetArray::Metal(_) => None,
481            #[cfg(feature = "rafx-gles2")]
482            RafxDescriptorSetArray::Gles2(_) => None,
483            #[cfg(feature = "rafx-gles3")]
484            RafxDescriptorSetArray::Gles3(_) => None,
485            #[cfg(any(
486                feature = "rafx-empty",
487                not(any(
488                    feature = "rafx-dx12",
489                    feature = "rafx-metal",
490                    feature = "rafx-vulkan",
491                    feature = "rafx-gles2",
492                    feature = "rafx-gles3"
493                ))
494            ))]
495            RafxDescriptorSetArray::Empty(_) => None,
496        }
497    }
498
499    /// Get the underlying metal API object. This provides access to any internally created
500    /// metal objects.
501    #[cfg(feature = "rafx-metal")]
502    pub fn metal_descriptor_set_array(&self) -> Option<&RafxDescriptorSetArrayMetal> {
503        match self {
504            #[cfg(feature = "rafx-dx12")]
505            RafxDescriptorSetArray::Dx12(_) => None,
506            #[cfg(feature = "rafx-vulkan")]
507            RafxDescriptorSetArray::Vk(_) => None,
508            #[cfg(feature = "rafx-metal")]
509            RafxDescriptorSetArray::Metal(inner) => Some(inner),
510            #[cfg(feature = "rafx-gles2")]
511            RafxDescriptorSetArray::Gles2(_) => None,
512            #[cfg(feature = "rafx-gles3")]
513            RafxDescriptorSetArray::Gles3(_) => None,
514            #[cfg(any(
515                feature = "rafx-empty",
516                not(any(
517                    feature = "rafx-dx12",
518                    feature = "rafx-metal",
519                    feature = "rafx-vulkan",
520                    feature = "rafx-gles2",
521                    feature = "rafx-gles3"
522                ))
523            ))]
524            RafxDescriptorSetArray::Empty(_) => None,
525        }
526    }
527
528    /// Get the underlying gl API object. This provides access to any internally created
529    /// metal objects.
530    #[cfg(feature = "rafx-gles2")]
531    pub fn gles2_descriptor_set_array(&self) -> Option<&RafxDescriptorSetArrayGles2> {
532        match self {
533            #[cfg(feature = "rafx-dx12")]
534            RafxDescriptorSetArray::Dx12(_) => None,
535            #[cfg(feature = "rafx-vulkan")]
536            RafxDescriptorSetArray::Vk(_) => None,
537            #[cfg(feature = "rafx-metal")]
538            RafxDescriptorSetArray::Metal(_) => None,
539            #[cfg(feature = "rafx-gles2")]
540            RafxDescriptorSetArray::Gles2(inner) => Some(inner),
541            #[cfg(feature = "rafx-gles3")]
542            RafxDescriptorSetArray::Gles3(_) => None,
543            #[cfg(any(
544                feature = "rafx-empty",
545                not(any(
546                    feature = "rafx-dx12",
547                    feature = "rafx-metal",
548                    feature = "rafx-vulkan",
549                    feature = "rafx-gles2",
550                    feature = "rafx-gles3"
551                ))
552            ))]
553            RafxDescriptorSetArray::Empty(_) => None,
554        }
555    }
556
557    /// Get the underlying gl API object. This provides access to any internally created
558    /// metal objects.
559    #[cfg(feature = "rafx-gles3")]
560    pub fn gles3_descriptor_set_array(&self) -> Option<&RafxDescriptorSetArrayGles3> {
561        match self {
562            #[cfg(feature = "rafx-dx12")]
563            RafxDescriptorSetArray::Dx12(_) => None,
564            #[cfg(feature = "rafx-vulkan")]
565            RafxDescriptorSetArray::Vk(_) => None,
566            #[cfg(feature = "rafx-metal")]
567            RafxDescriptorSetArray::Metal(_) => None,
568            #[cfg(feature = "rafx-gles2")]
569            RafxDescriptorSetArray::Gles2(_) => None,
570            #[cfg(feature = "rafx-gles3")]
571            RafxDescriptorSetArray::Gles3(inner) => Some(inner),
572            #[cfg(any(
573                feature = "rafx-empty",
574                not(any(
575                    feature = "rafx-dx12",
576                    feature = "rafx-metal",
577                    feature = "rafx-vulkan",
578                    feature = "rafx-gles2",
579                    feature = "rafx-gles3"
580                ))
581            ))]
582            RafxDescriptorSetArray::Empty(_) => None,
583        }
584    }
585
586    /// Get the underlying metal API object. This provides access to any internally created
587    /// metal objects.
588    #[cfg(any(
589        feature = "rafx-empty",
590        not(any(
591            feature = "rafx-dx12",
592            feature = "rafx-metal",
593            feature = "rafx-vulkan",
594            feature = "rafx-gles2",
595            feature = "rafx-gles3"
596        ))
597    ))]
598    pub fn empty_descriptor_set_array(&self) -> Option<&RafxDescriptorSetArrayEmpty> {
599        match self {
600            #[cfg(feature = "rafx-dx12")]
601            RafxDescriptorSetArray::Dx12(_) => None,
602            #[cfg(feature = "rafx-vulkan")]
603            RafxDescriptorSetArray::Vk(_) => None,
604            #[cfg(feature = "rafx-metal")]
605            RafxDescriptorSetArray::Metal(_) => None,
606            #[cfg(feature = "rafx-gles2")]
607            RafxDescriptorSetArray::Gles2(_) => None,
608            #[cfg(feature = "rafx-gles3")]
609            RafxDescriptorSetArray::Gles3(_) => None,
610            #[cfg(any(
611                feature = "rafx-empty",
612                not(any(
613                    feature = "rafx-dx12",
614                    feature = "rafx-metal",
615                    feature = "rafx-vulkan",
616                    feature = "rafx-gles2",
617                    feature = "rafx-gles3"
618                ))
619            ))]
620            RafxDescriptorSetArray::Empty(inner) => Some(inner),
621        }
622    }
623}