Skip to content

Commit

Permalink
Fix prepass binding issues causing crashes when not all prepass bindi…
Browse files Browse the repository at this point in the history
…ngs are used (#10788)

# Objective

Fixes #10786

## Solution

The bind_group_layout entries for the prepass were wrong when not all 4
prepass textures were used, as it just zipped [17, 18, 19, 20] with the
smallvec of prepass `bind_group_layout` entries that potentially didn't
contain 4 entries. (eg. if you had a depth and motion vector prepass but
no normal prepass, then depth would be correct but the entry for the
motion vector prepass would be 18 (normal prepass' spot) instead of 19).

Change the prepass `get_bind_group_layout_entries` function to return an
array of `[Option<BindGroupLayoutEntryBuilder>; 4]` and only add the
layout entry if it exists.
  • Loading branch information
Elabajaba authored Nov 29, 2023
1 parent 47447be commit 0f5d812
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 33 deletions.
59 changes: 27 additions & 32 deletions crates/bevy_pbr/src/prepass/prepass_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,58 +7,53 @@ use bevy_render::render_resource::{
TextureViewDescriptor,
};
use bevy_utils::default;
use smallvec::SmallVec;

use crate::MeshPipelineViewLayoutKey;

pub fn get_bind_group_layout_entries(
layout_key: MeshPipelineViewLayoutKey,
) -> SmallVec<[BindGroupLayoutEntryBuilder; 4]> {
let mut result = SmallVec::<[BindGroupLayoutEntryBuilder; 4]>::new();
) -> [Option<BindGroupLayoutEntryBuilder>; 4] {
let mut entries: [Option<BindGroupLayoutEntryBuilder>; 4] = [None; 4];

let multisampled = layout_key.contains(MeshPipelineViewLayoutKey::MULTISAMPLED);

if layout_key.contains(MeshPipelineViewLayoutKey::DEPTH_PREPASS) {
result.push(
// Depth texture
if multisampled {
texture_depth_2d_multisampled()
} else {
texture_depth_2d()
},
);
// Depth texture
entries[0] = if multisampled {
Some(texture_depth_2d_multisampled())
} else {
Some(texture_depth_2d())
};
}

if layout_key.contains(MeshPipelineViewLayoutKey::NORMAL_PREPASS) {
result.push(
// Normal texture
if multisampled {
texture_2d_multisampled(TextureSampleType::Float { filterable: false })
} else {
texture_2d(TextureSampleType::Float { filterable: false })
},
);
// Normal texture
entries[1] = if multisampled {
Some(texture_2d_multisampled(TextureSampleType::Float {
filterable: false,
}))
} else {
Some(texture_2d(TextureSampleType::Float { filterable: false }))
};
}

if layout_key.contains(MeshPipelineViewLayoutKey::MOTION_VECTOR_PREPASS) {
result.push(
// Motion Vectors texture
if multisampled {
texture_2d_multisampled(TextureSampleType::Float { filterable: false })
} else {
texture_2d(TextureSampleType::Float { filterable: false })
},
);
// Motion Vectors texture
entries[2] = if multisampled {
Some(texture_2d_multisampled(TextureSampleType::Float {
filterable: false,
}))
} else {
Some(texture_2d(TextureSampleType::Float { filterable: false }))
};
}

if layout_key.contains(MeshPipelineViewLayoutKey::DEFERRED_PREPASS) {
result.push(
// Deferred texture
texture_2d(TextureSampleType::Uint),
);
// Deferred texture
entries[3] = Some(texture_2d(TextureSampleType::Uint));
}

result
entries
}

pub fn get_bindings(prepass_textures: Option<&ViewPrepassTextures>) -> [Option<TextureView>; 4] {
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_pbr/src/render/mesh_view_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,9 @@ fn layout_entries(
.iter()
.zip([17, 18, 19, 20])
{
entries = entries.extend_with_indices(((binding as u32, *entry),));
if let Some(entry) = entry {
entries = entries.extend_with_indices(((binding as u32, *entry),));
}
}
}

Expand Down

0 comments on commit 0f5d812

Please sign in to comment.