Fix get_render_pipeline_state / get_compute_pipeline_state panic (#18752)

This fixes a panic that occurs if one calls
`PipelineCache::get_render_pipeline_state(id)` or
`PipelineCache::get_compute_pipeline_state(id)` with a queued pipeline
id that has not yet been processed by `PipelineCache::process_queue()`.

```
thread 'Compute Task Pool (0)' panicked at [...]/bevy/crates/bevy_render/src/render_resource/pipeline_cache.rs:611:24:
index out of bounds: the len is 0 but the index is 20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
This commit is contained in:
Brian Reavis 2025-04-09 09:55:19 -07:00 committed by François Mockers
parent 1830a99785
commit 8eb85ea720

View File

@ -608,7 +608,10 @@ impl PipelineCache {
/// See [`PipelineCache::queue_render_pipeline()`].
#[inline]
pub fn get_render_pipeline_state(&self, id: CachedRenderPipelineId) -> &CachedPipelineState {
&self.pipelines[id.0].state
// If the pipeline id isn't in `pipelines`, it's queued in `new_pipelines`
self.pipelines
.get(id.0)
.map_or(&CachedPipelineState::Queued, |pipeline| &pipeline.state)
}
/// Get the state of a cached compute pipeline.
@ -616,12 +619,18 @@ impl PipelineCache {
/// See [`PipelineCache::queue_compute_pipeline()`].
#[inline]
pub fn get_compute_pipeline_state(&self, id: CachedComputePipelineId) -> &CachedPipelineState {
&self.pipelines[id.0].state
// If the pipeline id isn't in `pipelines`, it's queued in `new_pipelines`
self.pipelines
.get(id.0)
.map_or(&CachedPipelineState::Queued, |pipeline| &pipeline.state)
}
/// Get the render pipeline descriptor a cached render pipeline was inserted from.
///
/// See [`PipelineCache::queue_render_pipeline()`].
///
/// **Note**: Be careful calling this method. It will panic if called with a pipeline that
/// has been queued but has not yet been processed by [`PipelineCache::process_queue()`].
#[inline]
pub fn get_render_pipeline_descriptor(
&self,
@ -636,6 +645,9 @@ impl PipelineCache {
/// Get the compute pipeline descriptor a cached render pipeline was inserted from.
///
/// See [`PipelineCache::queue_compute_pipeline()`].
///
/// **Note**: Be careful calling this method. It will panic if called with a pipeline that
/// has been queued but has not yet been processed by [`PipelineCache::process_queue()`].
#[inline]
pub fn get_compute_pipeline_descriptor(
&self,
@ -657,7 +669,7 @@ impl PipelineCache {
#[inline]
pub fn get_render_pipeline(&self, id: CachedRenderPipelineId) -> Option<&RenderPipeline> {
if let CachedPipelineState::Ok(Pipeline::RenderPipeline(pipeline)) =
&self.pipelines[id.0].state
&self.pipelines.get(id.0)?.state
{
Some(pipeline)
} else {
@ -691,7 +703,7 @@ impl PipelineCache {
#[inline]
pub fn get_compute_pipeline(&self, id: CachedComputePipelineId) -> Option<&ComputePipeline> {
if let CachedPipelineState::Ok(Pipeline::ComputePipeline(pipeline)) =
&self.pipelines[id.0].state
&self.pipelines.get(id.0)?.state
{
Some(pipeline)
} else {