Skip to content

Commit 26d30fe

Browse files
committed
Document PipelineCache and related types (#5600)
# Objective Document `PipelineCache` and a few other related types. ## Solution Add documenting comments to `PipelineCache` and a few other related types in the same file.
1 parent c3cdb12 commit 26d30fe

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

crates/bevy_render/src/render_resource/pipeline_cache.rs

+97
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,18 @@ use wgpu::{
2424
VertexBufferLayout as RawVertexBufferLayout,
2525
};
2626

27+
/// A descriptor for a [`Pipeline`].
28+
///
29+
/// Used to store an heterogenous collection of render and compute pipeline descriptors together.
30+
#[derive(Debug)]
2731
pub enum PipelineDescriptor {
2832
RenderPipelineDescriptor(Box<RenderPipelineDescriptor>),
2933
ComputePipelineDescriptor(Box<ComputePipelineDescriptor>),
3034
}
3135

36+
/// A pipeline defining the data layout and shader logic for a specific GPU task.
37+
///
38+
/// Used to store an heterogenous collection of render and compute pipelines together.
3239
#[derive(Debug)]
3340
pub enum Pipeline {
3441
RenderPipeline(RenderPipeline),
@@ -37,17 +44,21 @@ pub enum Pipeline {
3744

3845
type CachedPipelineId = usize;
3946

47+
/// Index of a cached render pipeline in a [`PipelineCache`].
4048
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
4149
pub struct CachedRenderPipelineId(CachedPipelineId);
4250

4351
impl CachedRenderPipelineId {
52+
/// An invalid cached render pipeline index, often used to initialize a variable.
4453
pub const INVALID: Self = CachedRenderPipelineId(usize::MAX);
4554
}
4655

56+
/// Index of a cached compute pipeline in a [`PipelineCache`].
4757
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
4858
pub struct CachedComputePipelineId(CachedPipelineId);
4959

5060
impl CachedComputePipelineId {
61+
/// An invalid cached compute pipeline index, often used to initialize a variable.
5162
pub const INVALID: Self = CachedComputePipelineId(usize::MAX);
5263
}
5364

@@ -56,14 +67,28 @@ pub struct CachedPipeline {
5667
pub state: CachedPipelineState,
5768
}
5869

70+
/// State of a cached pipeline inserted into a [`PipelineCache`].
5971
#[derive(Debug)]
6072
pub enum CachedPipelineState {
73+
/// The pipeline GPU object is queued for creation.
6174
Queued,
75+
/// The pipeline GPU object was created successfully and is available (allocated on the GPU).
6276
Ok(Pipeline),
77+
/// An error occurred while trying to create the pipeline GPU object.
6378
Err(PipelineCacheError),
6479
}
6580

6681
impl CachedPipelineState {
82+
/// Convenience method to "unwrap" a pipeline state into its underlying GPU object.
83+
///
84+
/// # Returns
85+
///
86+
/// The method returns the allocated pipeline GPU object.
87+
///
88+
/// # Panics
89+
///
90+
/// This method panics if the pipeline GPU object is not available, either because it is
91+
/// pending creation or because an error occurred while attempting to create GPU object.
6792
pub fn unwrap(&self) -> &Pipeline {
6893
match self {
6994
CachedPipelineState::Ok(pipeline) => pipeline,
@@ -271,6 +296,18 @@ impl LayoutCache {
271296
}
272297
}
273298

299+
/// Cache for render and compute pipelines.
300+
///
301+
/// The cache stores existing render and compute pipelines allocated on the GPU, as well as
302+
/// pending creation. Pipelines inserted into the cache are identified by a unique ID, which
303+
/// can be used to retrieve the actual GPU object once it's ready. The creation of the GPU
304+
/// pipeline object is deferred to the [`RenderStage::Render`] stage, just before the render
305+
/// graph starts being processed, as this requires access to the GPU.
306+
///
307+
/// Note that the cache do not perform automatic deduplication of identical pipelines. It is
308+
/// up to the user not to insert the same pipeline twice to avoid wasting GPU resources.
309+
///
310+
/// [`RenderStage::Render`]: crate::RenderStage::Render
274311
#[derive(Resource)]
275312
pub struct PipelineCache {
276313
layout_cache: LayoutCache,
@@ -285,6 +322,7 @@ impl PipelineCache {
285322
self.pipelines.iter()
286323
}
287324

325+
/// Create a new pipeline cache associated with the given render device.
288326
pub fn new(device: RenderDevice) -> Self {
289327
Self {
290328
device,
@@ -295,16 +333,25 @@ impl PipelineCache {
295333
}
296334
}
297335

336+
/// Get the state of a cached render pipeline.
337+
///
338+
/// See [`PipelineCache::queue_render_pipeline()`].
298339
#[inline]
299340
pub fn get_render_pipeline_state(&self, id: CachedRenderPipelineId) -> &CachedPipelineState {
300341
&self.pipelines[id.0].state
301342
}
302343

344+
/// Get the state of a cached compute pipeline.
345+
///
346+
/// See [`PipelineCache::queue_compute_pipeline()`].
303347
#[inline]
304348
pub fn get_compute_pipeline_state(&self, id: CachedComputePipelineId) -> &CachedPipelineState {
305349
&self.pipelines[id.0].state
306350
}
307351

352+
/// Get the render pipeline descriptor a cached render pipeline was inserted from.
353+
///
354+
/// See [`PipelineCache::queue_render_pipeline()`].
308355
#[inline]
309356
pub fn get_render_pipeline_descriptor(
310357
&self,
@@ -316,6 +363,9 @@ impl PipelineCache {
316363
}
317364
}
318365

366+
/// Get the compute pipeline descriptor a cached render pipeline was inserted from.
367+
///
368+
/// See [`PipelineCache::queue_compute_pipeline()`].
319369
#[inline]
320370
pub fn get_compute_pipeline_descriptor(
321371
&self,
@@ -327,6 +377,13 @@ impl PipelineCache {
327377
}
328378
}
329379

380+
/// Try to retrieve a render pipeline GPU object from a cached ID.
381+
///
382+
/// # Returns
383+
///
384+
/// This method returns a successfully created render pipeline if any, or `None` if the pipeline
385+
/// was not created yet or if there was an error during creation. You can check the actual creation
386+
/// state with [`PipelineCache::get_render_pipeline_state()`].
330387
#[inline]
331388
pub fn get_render_pipeline(&self, id: CachedRenderPipelineId) -> Option<&RenderPipeline> {
332389
if let CachedPipelineState::Ok(Pipeline::RenderPipeline(pipeline)) =
@@ -338,6 +395,13 @@ impl PipelineCache {
338395
}
339396
}
340397

398+
/// Try to retrieve a compute pipeline GPU object from a cached ID.
399+
///
400+
/// # Returns
401+
///
402+
/// This method returns a successfully created compute pipeline if any, or `None` if the pipeline
403+
/// was not created yet or if there was an error during creation. You can check the actual creation
404+
/// state with [`PipelineCache::get_compute_pipeline_state()`].
341405
#[inline]
342406
pub fn get_compute_pipeline(&self, id: CachedComputePipelineId) -> Option<&ComputePipeline> {
343407
if let CachedPipelineState::Ok(Pipeline::ComputePipeline(pipeline)) =
@@ -349,6 +413,19 @@ impl PipelineCache {
349413
}
350414
}
351415

416+
/// Insert a render pipeline into the cache, and queue its creation.
417+
///
418+
/// The pipeline is always inserted and queued for creation. There is no attempt to deduplicate it with
419+
/// an already cached pipeline.
420+
///
421+
/// # Returns
422+
///
423+
/// This method returns the unique render shader ID of the cached pipeline, which can be used to query
424+
/// the caching state with [`get_render_pipeline_state()`] and to retrieve the created GPU pipeline once
425+
/// it's ready with [`get_render_pipeline()`].
426+
///
427+
/// [`get_render_pipeline_state()`]: PipelineCache::get_render_pipeline_state
428+
/// [`get_render_pipeline()`]: PipelineCache::get_render_pipeline
352429
pub fn queue_render_pipeline(
353430
&mut self,
354431
descriptor: RenderPipelineDescriptor,
@@ -362,6 +439,19 @@ impl PipelineCache {
362439
id
363440
}
364441

442+
/// Insert a compute pipeline into the cache, and queue its creation.
443+
///
444+
/// The pipeline is always inserted and queued for creation. There is no attempt to deduplicate it with
445+
/// an already cached pipeline.
446+
///
447+
/// # Returns
448+
///
449+
/// This method returns the unique compute shader ID of the cached pipeline, which can be used to query
450+
/// the caching state with [`get_compute_pipeline_state()`] and to retrieve the created GPU pipeline once
451+
/// it's ready with [`get_compute_pipeline()`].
452+
///
453+
/// [`get_compute_pipeline_state()`]: PipelineCache::get_compute_pipeline_state
454+
/// [`get_compute_pipeline()`]: PipelineCache::get_compute_pipeline
365455
pub fn queue_compute_pipeline(
366456
&mut self,
367457
descriptor: ComputePipelineDescriptor,
@@ -507,6 +597,12 @@ impl PipelineCache {
507597
CachedPipelineState::Ok(Pipeline::ComputePipeline(pipeline))
508598
}
509599

600+
/// Process the pipeline queue and create all pending pipelines if possible.
601+
///
602+
/// This is generally called automatically during the [`RenderStage::Render`] stage, but can
603+
/// be called manually to force creation at a different time.
604+
///
605+
/// [`RenderStage::Render`]: crate::RenderStage::Render
510606
pub fn process_queue(&mut self) {
511607
let waiting_pipelines = mem::take(&mut self.waiting_pipelines);
512608
let mut pipelines = mem::take(&mut self.pipelines);
@@ -667,6 +763,7 @@ fn log_shader_error(source: &ProcessedShader, error: &AsModuleDescriptorError) {
667763
}
668764
}
669765

766+
/// Type of error returned by a [`PipelineCache`] when the creation of a GPU pipeline object failed.
670767
#[derive(Error, Debug)]
671768
pub enum PipelineCacheError {
672769
#[error(

0 commit comments

Comments
 (0)