Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variable MeshPipeline View Bind Group Layout #10156

Merged
merged 15 commits into from
Oct 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clippy.toml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
doc-valid-idents = ["sRGB", "NaN", "iOS", "glTF", "GitHub", "WebGPU", "GilRs"]
doc-valid-idents = ["sRGB", "NaN", "iOS", "glTF", "GitHub", "WebGL", "WebGPU", "GilRs"]
9 changes: 4 additions & 5 deletions crates/bevy_gizmos/src/pipeline_3d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,10 @@ impl SpecializedRenderPipeline for LineGizmoPipeline {
TextureFormat::bevy_default()
};

let view_layout = if key.mesh_key.msaa_samples() == 1 {
self.mesh_pipeline.view_layout.clone()
} else {
self.mesh_pipeline.view_layout_multisampled.clone()
};
let view_layout = self
.mesh_pipeline
.get_view_layout(key.mesh_key.into())
.clone();

let layout = vec![view_layout, self.uniform_layout.clone()];

Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_pbr/src/deferred/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode {

#[derive(Resource)]
pub struct DeferredLightingLayout {
bind_group_layout_0: BindGroupLayout,
mesh_pipeline: MeshPipeline,
bind_group_layout_1: BindGroupLayout,
}

Expand Down Expand Up @@ -332,7 +332,7 @@ impl SpecializedRenderPipeline for DeferredLightingLayout {
RenderPipelineDescriptor {
label: Some("deferred_lighting_pipeline".into()),
layout: vec![
self.bind_group_layout_0.clone(),
self.mesh_pipeline.get_view_layout(key.into()).clone(),
self.bind_group_layout_1.clone(),
],
vertex: VertexState {
Expand Down Expand Up @@ -395,7 +395,7 @@ impl FromWorld for DeferredLightingLayout {
}],
});
Self {
bind_group_layout_0: world.resource::<MeshPipeline>().view_layout.clone(),
mesh_pipeline: world.resource::<MeshPipeline>().clone(),
bind_group_layout_1: layout,
}
}
Expand Down
144 changes: 10 additions & 134 deletions crates/bevy_pbr/src/prepass/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
mod prepass_bindings;

pub use prepass_bindings::*;

use bevy_app::{Plugin, PreUpdate};
use bevy_asset::{load_internal_asset, AssetServer, Handle};
use bevy_core_pipeline::{
Expand All @@ -9,7 +13,7 @@ use bevy_core_pipeline::{
prelude::Camera3d,
prepass::{
AlphaMask3dPrepass, DeferredPrepass, DepthPrepass, MotionVectorPrepass, NormalPrepass,
Opaque3dPrepass, ViewPrepassTextures, MOTION_VECTOR_PREPASS_FORMAT, NORMAL_PREPASS_FORMAT,
Opaque3dPrepass, MOTION_VECTOR_PREPASS_FORMAT, NORMAL_PREPASS_FORMAT,
},
};
use bevy_ecs::{
Expand All @@ -32,21 +36,18 @@ use bevy_render::{
},
render_resource::{
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
BindGroupLayoutEntry, BindingResource, BindingType, BufferBindingType, ColorTargetState,
ColorWrites, CompareFunction, DepthBiasState, DepthStencilState, DynamicUniformBuffer,
FragmentState, FrontFace, MultisampleState, PipelineCache, PolygonMode, PrimitiveState,
PushConstantRange, RenderPipelineDescriptor, Shader, ShaderRef, ShaderStages, ShaderType,
BindGroupLayoutEntry, BindingType, BufferBindingType, ColorTargetState, ColorWrites,
CompareFunction, DepthBiasState, DepthStencilState, DynamicUniformBuffer, FragmentState,
FrontFace, MultisampleState, PipelineCache, PolygonMode, PrimitiveState, PushConstantRange,
RenderPipelineDescriptor, Shader, ShaderRef, ShaderStages, ShaderType,
SpecializedMeshPipeline, SpecializedMeshPipelineError, SpecializedMeshPipelines,
StencilFaceState, StencilState, TextureAspect, TextureFormat, TextureSampleType,
TextureView, TextureViewDescriptor, TextureViewDimension, VertexState,
StencilFaceState, StencilState, VertexState,
},
renderer::{RenderDevice, RenderQueue},
texture::{BevyDefault, FallbackImageMsaa},
view::{ExtractedView, Msaa, ViewUniform, ViewUniformOffset, ViewUniforms, VisibleEntities},
Extract, ExtractSchedule, Render, RenderApp, RenderSet,
};
use bevy_transform::prelude::GlobalTransform;
use bevy_utils::default;
use bevy_utils::tracing::error;

use crate::{
Expand Down Expand Up @@ -634,131 +635,6 @@ where
}
}

pub fn get_bind_group_layout_entries(
bindings: [u32; 4],
multisampled: bool,
) -> [BindGroupLayoutEntry; 4] {
[
// Depth texture
BindGroupLayoutEntry {
binding: bindings[0],
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled,
sample_type: TextureSampleType::Depth,
view_dimension: TextureViewDimension::D2,
},
count: None,
},
// Normal texture
BindGroupLayoutEntry {
binding: bindings[1],
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled,
sample_type: TextureSampleType::Float { filterable: false },
view_dimension: TextureViewDimension::D2,
},
count: None,
},
// Motion Vectors texture
BindGroupLayoutEntry {
binding: bindings[2],
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled,
sample_type: TextureSampleType::Float { filterable: false },
view_dimension: TextureViewDimension::D2,
},
count: None,
},
// Deferred texture
BindGroupLayoutEntry {
binding: bindings[3],
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Uint,
view_dimension: TextureViewDimension::D2,
},
count: None,
},
]
}

// Needed so the texture views can live long enough.
pub struct PrepassBindingsSet([TextureView; 4]);

impl PrepassBindingsSet {
pub fn get_entries(&self, bindings: [u32; 4]) -> [BindGroupEntry; 4] {
[
BindGroupEntry {
binding: bindings[0],
resource: BindingResource::TextureView(&self.0[0]),
},
BindGroupEntry {
binding: bindings[1],
resource: BindingResource::TextureView(&self.0[1]),
},
BindGroupEntry {
binding: bindings[2],
resource: BindingResource::TextureView(&self.0[2]),
},
BindGroupEntry {
binding: bindings[3],
resource: BindingResource::TextureView(&self.0[3]),
},
]
}
}

pub fn get_bindings(
prepass_textures: Option<&ViewPrepassTextures>,
fallback_images: &mut FallbackImageMsaa,
msaa: &Msaa,
) -> PrepassBindingsSet {
let depth_desc = TextureViewDescriptor {
label: Some("prepass_depth"),
aspect: TextureAspect::DepthOnly,
..default()
};
let depth_view = match prepass_textures.and_then(|x| x.depth.as_ref()) {
Some(texture) => texture.texture.create_view(&depth_desc),
None => fallback_images
.image_for_samplecount(msaa.samples(), CORE_3D_DEPTH_FORMAT)
.texture
.create_view(&depth_desc),
};

let normal_motion_vectors_fallback = &fallback_images
.image_for_samplecount(msaa.samples(), TextureFormat::bevy_default())
.texture_view;

let normal_view = match prepass_textures.and_then(|x| x.normal.as_ref()) {
Some(texture) => &texture.default_view,
None => normal_motion_vectors_fallback,
}
.clone();

let motion_vectors_view = match prepass_textures.and_then(|x| x.motion_vectors.as_ref()) {
Some(texture) => &texture.default_view,
None => normal_motion_vectors_fallback,
}
.clone();

let deferred_fallback = &fallback_images
.image_for_samplecount(1, TextureFormat::Rgba32Uint)
.texture_view;

let deferred_view = match prepass_textures.and_then(|x| x.deferred.as_ref()) {
Some(texture) => &texture.default_view,
None => deferred_fallback,
}
.clone();

PrepassBindingsSet([depth_view, normal_view, motion_vectors_view, deferred_view])
}

// Extract the render phases for the prepass
pub fn extract_camera_previous_view_projection(
mut commands: Commands,
Expand Down
158 changes: 158 additions & 0 deletions crates/bevy_pbr/src/prepass/prepass_bindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
use bevy_core_pipeline::prepass::ViewPrepassTextures;
use bevy_render::render_resource::{
BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, ShaderStages,
TextureAspect, TextureSampleType, TextureView, TextureViewDescriptor, TextureViewDimension,
};
use bevy_utils::default;
use smallvec::SmallVec;

use crate::MeshPipelineViewLayoutKey;

pub fn get_bind_group_layout_entries(
bindings: [u32; 4],
layout_key: MeshPipelineViewLayoutKey,
) -> SmallVec<[BindGroupLayoutEntry; 4]> {
let mut result = SmallVec::<[BindGroupLayoutEntry; 4]>::new();

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

if layout_key.contains(MeshPipelineViewLayoutKey::DEPTH_PREPASS) {
result.push(
// Depth texture
BindGroupLayoutEntry {
binding: bindings[0],
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled,
sample_type: TextureSampleType::Depth,
view_dimension: TextureViewDimension::D2,
},
count: None,
},
);
}

if layout_key.contains(MeshPipelineViewLayoutKey::NORMAL_PREPASS) {
result.push(
// Normal texture
BindGroupLayoutEntry {
binding: bindings[1],
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled,
sample_type: TextureSampleType::Float { filterable: false },
view_dimension: TextureViewDimension::D2,
},
count: None,
},
);
}

if layout_key.contains(MeshPipelineViewLayoutKey::MOTION_VECTOR_PREPASS) {
result.push(
// Motion Vectors texture
BindGroupLayoutEntry {
binding: bindings[2],
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled,
sample_type: TextureSampleType::Float { filterable: false },
view_dimension: TextureViewDimension::D2,
},
count: None,
},
);
}

if layout_key.contains(MeshPipelineViewLayoutKey::DEFERRED_PREPASS) {
result.push(
// Deferred texture
BindGroupLayoutEntry {
binding: bindings[3],
visibility: ShaderStages::FRAGMENT,
ty: BindingType::Texture {
multisampled: false,
sample_type: TextureSampleType::Uint,
view_dimension: TextureViewDimension::D2,
},
count: None,
},
);
}

result
}

// Needed so the texture views can live long enough.
pub struct PrepassBindingsSet {
depth_view: Option<TextureView>,
normal_view: Option<TextureView>,
motion_vectors_view: Option<TextureView>,
deferred_view: Option<TextureView>,
}

impl PrepassBindingsSet {
pub fn get_entries(&self, bindings: [u32; 4]) -> SmallVec<[BindGroupEntry; 4]> {
let mut result = SmallVec::<[BindGroupEntry; 4]>::new();

if let Some(ref depth_view) = self.depth_view {
result.push(BindGroupEntry {
binding: bindings[0],
resource: BindingResource::TextureView(depth_view),
});
}

if let Some(ref normal_view) = self.normal_view {
result.push(BindGroupEntry {
binding: bindings[1],
resource: BindingResource::TextureView(normal_view),
});
}

if let Some(ref motion_vectors_view) = self.motion_vectors_view {
result.push(BindGroupEntry {
binding: bindings[2],
resource: BindingResource::TextureView(motion_vectors_view),
});
}

if let Some(ref deferred_view) = self.deferred_view {
result.push(BindGroupEntry {
binding: bindings[3],
resource: BindingResource::TextureView(deferred_view),
});
}

result
}
}

pub fn get_bindings(prepass_textures: Option<&ViewPrepassTextures>) -> PrepassBindingsSet {
let depth_desc = TextureViewDescriptor {
label: Some("prepass_depth"),
aspect: TextureAspect::DepthOnly,
..default()
};
let depth_view = prepass_textures
.and_then(|x| x.depth.as_ref())
.map(|texture| texture.texture.create_view(&depth_desc));

let normal_view = prepass_textures
.and_then(|x| x.normal.as_ref())
.map(|texture| texture.default_view.clone());

let motion_vectors_view = prepass_textures
.and_then(|x| x.motion_vectors.as_ref())
.map(|texture| texture.default_view.clone());

let deferred_view = prepass_textures
.and_then(|x| x.deferred.as_ref())
.map(|texture| texture.default_view.clone());

PrepassBindingsSet {
depth_view,
normal_view,
motion_vectors_view,
deferred_view,
}
}
Loading