rafx_api/
pipeline.rs

1#[cfg(feature = "rafx-dx12")]
2use crate::dx12::RafxPipelineDx12;
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::RafxPipelineEmpty;
14#[cfg(feature = "rafx-gles2")]
15use crate::gles2::RafxPipelineGles2;
16#[cfg(feature = "rafx-gles3")]
17use crate::gles3::RafxPipelineGles3;
18#[cfg(feature = "rafx-metal")]
19use crate::metal::RafxPipelineMetal;
20#[cfg(feature = "rafx-vulkan")]
21use crate::vulkan::RafxPipelineVulkan;
22use crate::{RafxPipelineType, RafxRootSignature};
23
24/// Represents a complete GPU configuration for executing work.
25///
26/// There are two kinds of pipelines: Graphics and Compute
27///
28/// A pipeline includes fixed-function state (i.e. configuration) and programmable state
29/// (i.e. shaders). Pipelines are expensive objects to create. Ideally, they should be created
30/// when the application initializes or on a separate thread.
31///
32/// Pipelines are bound by command buffers. Fewer pipeline changes is better, and it is often worth
33/// batching draw calls that use the same pipeline to happen together so that the pipeline does not
34/// need to be changed as frequently.
35///
36/// Pipelines must not be dropped if they are in use by the GPU.
37#[derive(Debug)]
38pub enum RafxPipeline {
39    #[cfg(feature = "rafx-dx12")]
40    Dx12(RafxPipelineDx12),
41    #[cfg(feature = "rafx-vulkan")]
42    Vk(RafxPipelineVulkan),
43    #[cfg(feature = "rafx-metal")]
44    Metal(RafxPipelineMetal),
45    #[cfg(feature = "rafx-gles2")]
46    Gles2(RafxPipelineGles2),
47    #[cfg(feature = "rafx-gles3")]
48    Gles3(RafxPipelineGles3),
49    #[cfg(any(
50        feature = "rafx-empty",
51        not(any(
52            feature = "rafx-dx12",
53            feature = "rafx-metal",
54            feature = "rafx-vulkan",
55            feature = "rafx-gles2",
56            feature = "rafx-gles3"
57        ))
58    ))]
59    Empty(RafxPipelineEmpty),
60}
61
62impl RafxPipeline {
63    /// Returns the type of pipeline that this is
64    pub fn pipeline_type(&self) -> RafxPipelineType {
65        match self {
66            #[cfg(feature = "rafx-dx12")]
67            RafxPipeline::Dx12(inner) => inner.pipeline_type(),
68            #[cfg(feature = "rafx-vulkan")]
69            RafxPipeline::Vk(inner) => inner.pipeline_type(),
70            #[cfg(feature = "rafx-metal")]
71            RafxPipeline::Metal(inner) => inner.pipeline_type(),
72            #[cfg(feature = "rafx-gles2")]
73            RafxPipeline::Gles2(inner) => inner.pipeline_type(),
74            #[cfg(feature = "rafx-gles3")]
75            RafxPipeline::Gles3(inner) => inner.pipeline_type(),
76            #[cfg(any(
77                feature = "rafx-empty",
78                not(any(
79                    feature = "rafx-dx12",
80                    feature = "rafx-metal",
81                    feature = "rafx-vulkan",
82                    feature = "rafx-gles2",
83                    feature = "rafx-gles3"
84                ))
85            ))]
86            RafxPipeline::Empty(inner) => inner.pipeline_type(),
87        }
88    }
89
90    /// Returns the root signature used to create the pipeline
91    pub fn root_signature(&self) -> &RafxRootSignature {
92        match self {
93            #[cfg(feature = "rafx-dx12")]
94            RafxPipeline::Dx12(inner) => inner.root_signature(),
95            #[cfg(feature = "rafx-vulkan")]
96            RafxPipeline::Vk(inner) => inner.root_signature(),
97            #[cfg(feature = "rafx-metal")]
98            RafxPipeline::Metal(inner) => inner.root_signature(),
99            #[cfg(feature = "rafx-gles2")]
100            RafxPipeline::Gles2(inner) => inner.root_signature(),
101            #[cfg(feature = "rafx-gles3")]
102            RafxPipeline::Gles3(inner) => inner.root_signature(),
103            #[cfg(any(
104                feature = "rafx-empty",
105                not(any(
106                    feature = "rafx-dx12",
107                    feature = "rafx-metal",
108                    feature = "rafx-vulkan",
109                    feature = "rafx-gles2",
110                    feature = "rafx-gles3"
111                ))
112            ))]
113            RafxPipeline::Empty(inner) => inner.root_signature(),
114        }
115    }
116
117    /// Sets a name for this pipeline. This is useful for debugging, graphics debuggers/profilers such
118    /// as nsight graphics or renderdoc will display this pipeline with the given name in the list of resources.
119    ///
120    /// WARNING: Metal doesn't support specifying debug names after pipeline creation, so it's better
121    /// to provide a debug_name in RafxGraphicsPipelineDef/RafxComputePipelineDef
122    pub fn set_debug_name(
123        &self,
124        _name: impl AsRef<str>,
125    ) {
126        match self {
127            #[cfg(feature = "rafx-dx12")]
128            RafxPipeline::Dx12(inner) => inner.set_debug_name(_name),
129            #[cfg(feature = "rafx-vulkan")]
130            RafxPipeline::Vk(inner) => inner.set_debug_name(_name),
131            #[cfg(feature = "rafx-metal")]
132            // Not possible to set after creation, recommend providing debug_name on pipeline
133            // creation via RafxGraphicsPipelineDef/RafxComputePipelineDef
134            RafxPipeline::Metal(_) => {}
135            #[cfg(feature = "rafx-gles2")]
136            RafxPipeline::Gles2(_) => {}
137            #[cfg(feature = "rafx-gles3")]
138            RafxPipeline::Gles3(_) => {}
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            RafxPipeline::Empty(inner) => inner.set_debug_name(_name),
150        }
151    }
152
153    /// Get the underlying vulkan API object. This provides access to any internally created
154    /// vulkan objects.
155    #[cfg(feature = "rafx-dx12")]
156    pub fn dx12_pipeline(&self) -> Option<&RafxPipelineDx12> {
157        match self {
158            #[cfg(feature = "rafx-dx12")]
159            RafxPipeline::Dx12(inner) => Some(inner),
160            #[cfg(feature = "rafx-vulkan")]
161            RafxPipeline::Vk(_) => None,
162            #[cfg(feature = "rafx-metal")]
163            RafxPipeline::Metal(_) => None,
164            #[cfg(feature = "rafx-gles2")]
165            RafxPipeline::Gles2(_) => None,
166            #[cfg(feature = "rafx-gles3")]
167            RafxPipeline::Gles3(_) => None,
168            #[cfg(any(
169                feature = "rafx-empty",
170                not(any(
171                    feature = "rafx-dx12",
172                    feature = "rafx-metal",
173                    feature = "rafx-vulkan",
174                    feature = "rafx-gles2",
175                    feature = "rafx-gles3"
176                ))
177            ))]
178            RafxPipeline::Empty(_) => None,
179        }
180    }
181
182    /// Get the underlying vulkan API object. This provides access to any internally created
183    /// vulkan objects.
184    #[cfg(feature = "rafx-vulkan")]
185    pub fn vk_pipeline(&self) -> Option<&RafxPipelineVulkan> {
186        match self {
187            #[cfg(feature = "rafx-dx12")]
188            RafxPipeline::Dx12(_) => None,
189            #[cfg(feature = "rafx-vulkan")]
190            RafxPipeline::Vk(inner) => Some(inner),
191            #[cfg(feature = "rafx-metal")]
192            RafxPipeline::Metal(_) => None,
193            #[cfg(feature = "rafx-gles2")]
194            RafxPipeline::Gles2(_) => None,
195            #[cfg(feature = "rafx-gles3")]
196            RafxPipeline::Gles3(_) => None,
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            RafxPipeline::Empty(_) => None,
208        }
209    }
210
211    /// Get the underlying metal API object. This provides access to any internally created
212    /// metal objects.
213    #[cfg(feature = "rafx-metal")]
214    pub fn metal_pipeline(&self) -> Option<&RafxPipelineMetal> {
215        match self {
216            #[cfg(feature = "rafx-dx12")]
217            RafxPipeline::Dx12(_) => None,
218            #[cfg(feature = "rafx-vulkan")]
219            RafxPipeline::Vk(_) => None,
220            #[cfg(feature = "rafx-metal")]
221            RafxPipeline::Metal(inner) => Some(inner),
222            #[cfg(feature = "rafx-gles2")]
223            RafxPipeline::Gles2(_) => None,
224            #[cfg(feature = "rafx-gles3")]
225            RafxPipeline::Gles3(_) => None,
226            #[cfg(any(
227                feature = "rafx-empty",
228                not(any(
229                    feature = "rafx-dx12",
230                    feature = "rafx-metal",
231                    feature = "rafx-vulkan",
232                    feature = "rafx-gles2",
233                    feature = "rafx-gles3"
234                ))
235            ))]
236            RafxPipeline::Empty(_) => None,
237        }
238    }
239
240    /// Get the underlying gl API object. This provides access to any internally created
241    /// metal objects.
242    #[cfg(feature = "rafx-gles2")]
243    pub fn gles2_pipeline(&self) -> Option<&RafxPipelineGles2> {
244        match self {
245            #[cfg(feature = "rafx-dx12")]
246            RafxPipeline::Dx12(_) => None,
247            #[cfg(feature = "rafx-vulkan")]
248            RafxPipeline::Vk(_) => None,
249            #[cfg(feature = "rafx-metal")]
250            RafxPipeline::Metal(_) => None,
251            #[cfg(feature = "rafx-gles2")]
252            RafxPipeline::Gles2(inner) => Some(inner),
253            #[cfg(feature = "rafx-gles3")]
254            RafxPipeline::Gles3(_) => None,
255            #[cfg(any(
256                feature = "rafx-empty",
257                not(any(
258                    feature = "rafx-dx12",
259                    feature = "rafx-metal",
260                    feature = "rafx-vulkan",
261                    feature = "rafx-gles2",
262                    feature = "rafx-gles3"
263                ))
264            ))]
265            RafxPipeline::Empty(_) => None,
266        }
267    }
268
269    /// Get the underlying gl API object. This provides access to any internally created
270    /// metal objects.
271    #[cfg(feature = "rafx-gles3")]
272    pub fn gles3_pipeline(&self) -> Option<&RafxPipelineGles3> {
273        match self {
274            #[cfg(feature = "rafx-dx12")]
275            RafxPipeline::Dx12(_) => None,
276            #[cfg(feature = "rafx-vulkan")]
277            RafxPipeline::Vk(_) => None,
278            #[cfg(feature = "rafx-metal")]
279            RafxPipeline::Metal(_) => None,
280            #[cfg(feature = "rafx-gles2")]
281            RafxPipeline::Gles2(_) => None,
282            #[cfg(feature = "rafx-gles3")]
283            RafxPipeline::Gles3(inner) => Some(inner),
284            #[cfg(any(
285                feature = "rafx-empty",
286                not(any(
287                    feature = "rafx-dx12",
288                    feature = "rafx-metal",
289                    feature = "rafx-vulkan",
290                    feature = "rafx-gles2",
291                    feature = "rafx-gles3"
292                ))
293            ))]
294            RafxPipeline::Empty(_) => None,
295        }
296    }
297
298    #[cfg(any(
299        feature = "rafx-empty",
300        not(any(
301            feature = "rafx-dx12",
302            feature = "rafx-metal",
303            feature = "rafx-vulkan",
304            feature = "rafx-gles2",
305            feature = "rafx-gles3"
306        ))
307    ))]
308    pub fn empty_pipeline(&self) -> Option<&RafxPipelineEmpty> {
309        match self {
310            #[cfg(feature = "rafx-dx12")]
311            RafxPipeline::Dx12(_) => None,
312            #[cfg(feature = "rafx-vulkan")]
313            RafxPipeline::Vk(_) => None,
314            #[cfg(feature = "rafx-metal")]
315            RafxPipeline::Metal(_) => None,
316            #[cfg(feature = "rafx-gles2")]
317            RafxPipeline::Gles2(_) => None,
318            #[cfg(feature = "rafx-gles3")]
319            RafxPipeline::Gles3(_) => None,
320            #[cfg(any(
321                feature = "rafx-empty",
322                not(any(
323                    feature = "rafx-dx12",
324                    feature = "rafx-metal",
325                    feature = "rafx-vulkan",
326                    feature = "rafx-gles2",
327                    feature = "rafx-gles3"
328                ))
329            ))]
330            RafxPipeline::Empty(inner) => Some(inner),
331        }
332    }
333}