Fix prepass binding issues causing crashes when not all prepass bindings are used (#10788)

# Objective

Fixes https://github.com/bevyengine/bevy/issues/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.
This commit is contained in:
Elabajaba 2023-11-29 18:11:12 -05:00 committed by GitHub
parent 47447beb93
commit 0f5d8128c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 33 deletions

View File

@ -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()
entries[0] = if multisampled {
Some(texture_depth_2d_multisampled())
} else {
texture_depth_2d()
},
);
Some(texture_depth_2d())
};
}
if layout_key.contains(MeshPipelineViewLayoutKey::NORMAL_PREPASS) {
result.push(
// Normal texture
if multisampled {
texture_2d_multisampled(TextureSampleType::Float { filterable: false })
entries[1] = if multisampled {
Some(texture_2d_multisampled(TextureSampleType::Float {
filterable: false,
}))
} else {
texture_2d(TextureSampleType::Float { filterable: false })
},
);
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 })
entries[2] = if multisampled {
Some(texture_2d_multisampled(TextureSampleType::Float {
filterable: false,
}))
} else {
texture_2d(TextureSampleType::Float { filterable: false })
},
);
Some(texture_2d(TextureSampleType::Float { filterable: false }))
};
}
if layout_key.contains(MeshPipelineViewLayoutKey::DEFERRED_PREPASS) {
result.push(
// Deferred texture
texture_2d(TextureSampleType::Uint),
);
entries[3] = Some(texture_2d(TextureSampleType::Uint));
}
result
entries
}
pub fn get_bindings(prepass_textures: Option<&ViewPrepassTextures>) -> [Option<TextureView>; 4] {

View File

@ -274,9 +274,11 @@ fn layout_entries(
.iter()
.zip([17, 18, 19, 20])
{
if let Some(entry) = entry {
entries = entries.extend_with_indices(((binding as u32, *entry),));
}
}
}
// View Transmission Texture
entries = entries.extend_with_indices((