mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
Bind group entries (#9694)
# Objective Simplify bind group creation code. alternative to (and based on) #9476 ## Solution - Add a `BindGroupEntries` struct that can transparently be used where `&[BindGroupEntry<'b>]` is required in BindGroupDescriptors. Allows constructing the descriptor's entries as: ```rust render_device.create_bind_group( "my_bind_group", &my_layout, &BindGroupEntries::with_indexes(( (2, &my_sampler), (3, my_uniform), )), ); ``` instead of ```rust render_device.create_bind_group( "my_bind_group", &my_layout, &[ BindGroupEntry { binding: 2, resource: BindingResource::Sampler(&my_sampler), }, BindGroupEntry { binding: 3, resource: my_uniform, }, ], ); ``` or ```rust render_device.create_bind_group( "my_bind_group", &my_layout, &BindGroupEntries::sequential((&my_sampler, my_uniform)), ); ``` instead of ```rust render_device.create_bind_group( "my_bind_group", &my_layout, &[ BindGroupEntry { binding: 0, resource: BindingResource::Sampler(&my_sampler), }, BindGroupEntry { binding: 1, resource: my_uniform, }, ], ); ``` the structs has no user facing macros, is tuple-type-based so stack allocated, and has no noticeable impact on compile time. - Also adds a `DynamicBindGroupEntries` struct with a similar api that uses a `Vec` under the hood and allows extending the entries. - Modifies `RenderDevice::create_bind_group` to take separate arguments `label`, `layout` and `entries` instead of a `BindGroupDescriptor` struct. The struct can't be stored due to the internal references, and with only 3 members arguably does not add enough context to justify itself. - Modify the codebase to use the new api and the `BindGroupEntries` / `DynamicBindGroupEntries` structs where appropriate (whenever the entries slice contains more than 1 member). ## Migration Guide - Calls to `RenderDevice::create_bind_group({BindGroupDescriptor { label, layout, entries })` must be amended to `RenderDevice::create_bind_group(label, layout, entries)`. - If `label`s have been specified as `"bind_group_name".into()`, they need to change to just `"bind_group_name"`. `Some("bind_group_name")` and `None` will still work, but `Some("bind_group_name")` can optionally be simplified to just `"bind_group_name"`. --------- Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
This commit is contained in:
parent
61bad4eb57
commit
6f2a5cb862
31 changed files with 701 additions and 830 deletions
|
@ -170,30 +170,16 @@ impl ViewNode for BloomNode {
|
|||
|
||||
// First downsample pass
|
||||
{
|
||||
let downsampling_first_bind_group =
|
||||
render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("bloom_downsampling_first_bind_group"),
|
||||
layout: &downsampling_pipeline_res.bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
// Read from main texture directly
|
||||
resource: BindingResource::TextureView(
|
||||
view_target.main_texture_view(),
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(&bind_groups.sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: uniforms.clone(),
|
||||
},
|
||||
],
|
||||
});
|
||||
let downsampling_first_bind_group = render_context.render_device().create_bind_group(
|
||||
"bloom_downsampling_first_bind_group",
|
||||
&downsampling_pipeline_res.bind_group_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
// Read from main texture directly
|
||||
view_target.main_texture_view(),
|
||||
&bind_groups.sampler,
|
||||
uniforms.clone(),
|
||||
)),
|
||||
);
|
||||
|
||||
let view = &bloom_texture.view(0);
|
||||
let mut downsampling_first_pass =
|
||||
|
@ -416,46 +402,28 @@ fn prepare_bloom_bind_groups(
|
|||
|
||||
let mut downsampling_bind_groups = Vec::with_capacity(bind_group_count);
|
||||
for mip in 1..bloom_texture.mip_count {
|
||||
downsampling_bind_groups.push(render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("bloom_downsampling_bind_group"),
|
||||
layout: &downsampling_pipeline.bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(&bloom_texture.view(mip - 1)),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: uniforms.binding().unwrap(),
|
||||
},
|
||||
],
|
||||
}));
|
||||
downsampling_bind_groups.push(render_device.create_bind_group(
|
||||
"bloom_downsampling_bind_group",
|
||||
&downsampling_pipeline.bind_group_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
&bloom_texture.view(mip - 1),
|
||||
sampler,
|
||||
uniforms.binding().unwrap(),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
let mut upsampling_bind_groups = Vec::with_capacity(bind_group_count);
|
||||
for mip in (0..bloom_texture.mip_count).rev() {
|
||||
upsampling_bind_groups.push(render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("bloom_upsampling_bind_group"),
|
||||
layout: &upsampling_pipeline.bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(&bloom_texture.view(mip)),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: uniforms.binding().unwrap(),
|
||||
},
|
||||
],
|
||||
}));
|
||||
upsampling_bind_groups.push(render_device.create_bind_group(
|
||||
"bloom_upsampling_bind_group",
|
||||
&upsampling_pipeline.bind_group_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
&bloom_texture.view(mip),
|
||||
sampler,
|
||||
uniforms.binding().unwrap(),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
commands.entity(entity).insert(BloomBindGroups {
|
||||
|
|
|
@ -7,8 +7,8 @@ use bevy_render::{
|
|||
extract_component::{ComponentUniforms, DynamicUniformIndex},
|
||||
render_graph::{Node, NodeRunError, RenderGraphContext},
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferId, Operations,
|
||||
PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, TextureViewId,
|
||||
BindGroup, BindGroupEntries, BufferId, Operations, PipelineCache,
|
||||
RenderPassColorAttachment, RenderPassDescriptor, TextureViewId,
|
||||
},
|
||||
renderer::RenderContext,
|
||||
view::{ExtractedView, ViewTarget},
|
||||
|
@ -77,29 +77,15 @@ impl Node for CASNode {
|
|||
bind_group
|
||||
}
|
||||
cached_bind_group => {
|
||||
let bind_group =
|
||||
render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("cas_bind_group"),
|
||||
layout: &sharpening_pipeline.texture_bind_group,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(view_target.source),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(
|
||||
&sharpening_pipeline.sampler,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: uniforms,
|
||||
},
|
||||
],
|
||||
});
|
||||
let bind_group = render_context.render_device().create_bind_group(
|
||||
"cas_bind_group",
|
||||
&sharpening_pipeline.texture_bind_group,
|
||||
&BindGroupEntries::sequential((
|
||||
view_target.source,
|
||||
&sharpening_pipeline.sampler,
|
||||
uniforms,
|
||||
)),
|
||||
);
|
||||
|
||||
let (_, _, bind_group) =
|
||||
cached_bind_group.insert((uniforms_id, source.id(), bind_group));
|
||||
|
|
|
@ -18,10 +18,7 @@ use bevy_render::{
|
|||
use bevy_ecs::query::QueryItem;
|
||||
use bevy_render::{
|
||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||
render_resource::{
|
||||
BindGroupDescriptor, BindGroupEntry, BindingResource, Operations, PipelineCache,
|
||||
RenderPassDescriptor,
|
||||
},
|
||||
render_resource::{Operations, PipelineCache, RenderPassDescriptor},
|
||||
renderer::RenderContext,
|
||||
};
|
||||
|
||||
|
@ -94,18 +91,11 @@ impl ViewNode for CopyDeferredLightingIdNode {
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
let bind_group = render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("copy_deferred_lighting_id_bind_group"),
|
||||
layout: ©_deferred_lighting_id_pipeline.layout,
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(
|
||||
&deferred_lighting_pass_id_texture.default_view,
|
||||
),
|
||||
}],
|
||||
});
|
||||
let bind_group = render_context.render_device().create_bind_group(
|
||||
"copy_deferred_lighting_id_bind_group",
|
||||
©_deferred_lighting_id_pipeline.layout,
|
||||
&BindGroupEntries::single(&deferred_lighting_pass_id_texture.default_view),
|
||||
);
|
||||
|
||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
label: Some("copy_deferred_lighting_id_pass"),
|
||||
|
|
|
@ -6,9 +6,8 @@ use bevy_ecs::query::QueryItem;
|
|||
use bevy_render::{
|
||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, FilterMode, Operations,
|
||||
PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor,
|
||||
TextureViewId,
|
||||
BindGroup, BindGroupEntries, FilterMode, Operations, PipelineCache,
|
||||
RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor, TextureViewId,
|
||||
},
|
||||
renderer::RenderContext,
|
||||
view::ViewTarget,
|
||||
|
@ -61,23 +60,11 @@ impl ViewNode for FxaaNode {
|
|||
..default()
|
||||
});
|
||||
|
||||
let bind_group =
|
||||
render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: &fxaa_pipeline.texture_bind_group,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(source),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(&sampler),
|
||||
},
|
||||
],
|
||||
});
|
||||
let bind_group = render_context.render_device().create_bind_group(
|
||||
None,
|
||||
&fxaa_pipeline.texture_bind_group,
|
||||
&BindGroupEntries::sequential((source, &sampler)),
|
||||
);
|
||||
|
||||
let (_, bind_group) = cached_bind_group.insert((source.id(), bind_group));
|
||||
bind_group
|
||||
|
|
|
@ -8,6 +8,7 @@ use bevy_ecs::prelude::*;
|
|||
use bevy_render::{
|
||||
camera::ExtractedCamera,
|
||||
render_graph::{Node, NodeRunError, RenderGraphApp, RenderGraphContext},
|
||||
render_resource::BindGroupEntries,
|
||||
renderer::RenderContext,
|
||||
view::{Msaa, ViewTarget},
|
||||
Render, RenderSet,
|
||||
|
@ -90,23 +91,11 @@ impl Node for MsaaWritebackNode {
|
|||
depth_stencil_attachment: None,
|
||||
};
|
||||
|
||||
let bind_group =
|
||||
render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: &blit_pipeline.texture_bind_group,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(post_process.source),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(&blit_pipeline.sampler),
|
||||
},
|
||||
],
|
||||
});
|
||||
let bind_group = render_context.render_device().create_bind_group(
|
||||
None,
|
||||
&blit_pipeline.texture_bind_group,
|
||||
&BindGroupEntries::sequential((post_process.source, &blit_pipeline.sampler)),
|
||||
);
|
||||
|
||||
let mut render_pass = render_context
|
||||
.command_encoder()
|
||||
|
|
|
@ -10,13 +10,13 @@ use bevy_render::{
|
|||
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
||||
render_asset::RenderAssets,
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroupLayoutEntry, BindingResource, BindingType, BufferBindingType,
|
||||
CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState,
|
||||
DepthStencilState, FragmentState, MultisampleState, PipelineCache, PrimitiveState,
|
||||
RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderStages, ShaderType,
|
||||
SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilState,
|
||||
TextureFormat, TextureSampleType, TextureViewDimension, VertexState,
|
||||
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroupLayoutEntry, BindingType, BufferBindingType, CachedRenderPipelineId,
|
||||
ColorTargetState, ColorWrites, CompareFunction, DepthBiasState, DepthStencilState,
|
||||
FragmentState, MultisampleState, PipelineCache, PrimitiveState, RenderPipelineDescriptor,
|
||||
SamplerBindingType, Shader, ShaderStages, ShaderType, SpecializedRenderPipeline,
|
||||
SpecializedRenderPipelines, StencilFaceState, StencilState, TextureFormat,
|
||||
TextureSampleType, TextureViewDimension, VertexState,
|
||||
},
|
||||
renderer::RenderDevice,
|
||||
texture::{BevyDefault, Image},
|
||||
|
@ -224,24 +224,15 @@ fn prepare_skybox_bind_groups(
|
|||
if let (Some(skybox), Some(view_uniforms)) =
|
||||
(images.get(&skybox.0), view_uniforms.uniforms.binding())
|
||||
{
|
||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("skybox_bind_group"),
|
||||
layout: &pipeline.bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(&skybox.texture_view),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(&skybox.sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: view_uniforms,
|
||||
},
|
||||
],
|
||||
});
|
||||
let bind_group = render_device.create_bind_group(
|
||||
"skybox_bind_group",
|
||||
&pipeline.bind_group_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
&skybox.texture_view,
|
||||
&skybox.sampler,
|
||||
view_uniforms,
|
||||
)),
|
||||
);
|
||||
|
||||
commands.entity(entity).insert(SkyboxBindGroup(bind_group));
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@ use bevy_render::{
|
|||
prelude::{Camera, Projection},
|
||||
render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner},
|
||||
render_resource::{
|
||||
BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroupLayoutEntry, BindingResource, BindingType, CachedRenderPipelineId,
|
||||
ColorTargetState, ColorWrites, Extent3d, FilterMode, FragmentState, MultisampleState,
|
||||
Operations, PipelineCache, PrimitiveState, RenderPassColorAttachment, RenderPassDescriptor,
|
||||
RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, Shader,
|
||||
ShaderStages, SpecializedRenderPipeline, SpecializedRenderPipelines, TextureDescriptor,
|
||||
TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureViewDimension,
|
||||
BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
|
||||
BindingType, CachedRenderPipelineId, ColorTargetState, ColorWrites, Extent3d, FilterMode,
|
||||
FragmentState, MultisampleState, Operations, PipelineCache, PrimitiveState,
|
||||
RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, Sampler,
|
||||
SamplerBindingType, SamplerDescriptor, Shader, ShaderStages, SpecializedRenderPipeline,
|
||||
SpecializedRenderPipelines, TextureDescriptor, TextureDimension, TextureFormat,
|
||||
TextureSampleType, TextureUsages, TextureViewDimension,
|
||||
},
|
||||
renderer::{RenderContext, RenderDevice},
|
||||
texture::{BevyDefault, CachedTexture, TextureCache},
|
||||
|
@ -197,45 +197,18 @@ impl ViewNode for TAANode {
|
|||
};
|
||||
let view_target = view_target.post_process_write();
|
||||
|
||||
let taa_bind_group =
|
||||
render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("taa_bind_group"),
|
||||
layout: &pipelines.taa_bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(view_target.source),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::TextureView(
|
||||
&taa_history_textures.read.default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: BindingResource::TextureView(
|
||||
&prepass_motion_vectors_texture.default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 3,
|
||||
resource: BindingResource::TextureView(
|
||||
&prepass_depth_texture.default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 4,
|
||||
resource: BindingResource::Sampler(&pipelines.nearest_sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 5,
|
||||
resource: BindingResource::Sampler(&pipelines.linear_sampler),
|
||||
},
|
||||
],
|
||||
});
|
||||
let taa_bind_group = render_context.render_device().create_bind_group(
|
||||
"taa_bind_group",
|
||||
&pipelines.taa_bind_group_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
view_target.source,
|
||||
&taa_history_textures.read.default_view,
|
||||
&prepass_motion_vectors_texture.default_view,
|
||||
&prepass_depth_texture.default_view,
|
||||
&pipelines.nearest_sampler,
|
||||
&pipelines.linear_sampler,
|
||||
)),
|
||||
);
|
||||
|
||||
{
|
||||
let mut taa_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
|
|
|
@ -306,8 +306,7 @@ pub fn get_lut_bindings<'a>(
|
|||
images: &'a RenderAssets<Image>,
|
||||
tonemapping_luts: &'a TonemappingLuts,
|
||||
tonemapping: &Tonemapping,
|
||||
bindings: [u32; 2],
|
||||
) -> [BindGroupEntry<'a>; 2] {
|
||||
) -> (&'a TextureView, &'a Sampler) {
|
||||
let image = match tonemapping {
|
||||
// AgX lut texture used when tonemapping doesn't need a texture since it's very small (32x32x32)
|
||||
Tonemapping::None
|
||||
|
@ -320,16 +319,7 @@ pub fn get_lut_bindings<'a>(
|
|||
Tonemapping::BlenderFilmic => &tonemapping_luts.blender_filmic,
|
||||
};
|
||||
let lut_image = images.get(image).unwrap();
|
||||
[
|
||||
BindGroupEntry {
|
||||
binding: bindings[0],
|
||||
resource: BindingResource::TextureView(&lut_image.texture_view),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: bindings[1],
|
||||
resource: BindingResource::Sampler(&lut_image.sampler),
|
||||
},
|
||||
]
|
||||
(&lut_image.texture_view, &lut_image.sampler)
|
||||
}
|
||||
|
||||
pub fn get_lut_bind_group_layout_entries(bindings: [u32; 2]) -> [BindGroupLayoutEntry; 2] {
|
||||
|
|
|
@ -7,9 +7,8 @@ use bevy_render::{
|
|||
render_asset::RenderAssets,
|
||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferId, LoadOp,
|
||||
Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor,
|
||||
SamplerDescriptor, TextureViewId,
|
||||
BindGroup, BindGroupEntries, BufferId, LoadOp, Operations, PipelineCache,
|
||||
RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor, TextureViewId,
|
||||
},
|
||||
renderer::RenderContext,
|
||||
texture::Image,
|
||||
|
@ -88,36 +87,19 @@ impl ViewNode for TonemappingNode {
|
|||
|
||||
let tonemapping_luts = world.resource::<TonemappingLuts>();
|
||||
|
||||
let mut entries = vec![
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: view_uniforms.binding().unwrap(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::TextureView(source),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: BindingResource::Sampler(&sampler),
|
||||
},
|
||||
];
|
||||
let lut_bindings = get_lut_bindings(gpu_images, tonemapping_luts, tonemapping);
|
||||
|
||||
entries.extend(get_lut_bindings(
|
||||
gpu_images,
|
||||
tonemapping_luts,
|
||||
tonemapping,
|
||||
[3, 4],
|
||||
));
|
||||
|
||||
let bind_group =
|
||||
render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: &tonemapping_pipeline.texture_bind_group,
|
||||
entries: &entries,
|
||||
});
|
||||
let bind_group = render_context.render_device().create_bind_group(
|
||||
None,
|
||||
&tonemapping_pipeline.texture_bind_group,
|
||||
&BindGroupEntries::sequential((
|
||||
view_uniforms,
|
||||
source,
|
||||
&sampler,
|
||||
lut_bindings.0,
|
||||
lut_bindings.1,
|
||||
)),
|
||||
);
|
||||
|
||||
let (_, _, bind_group) =
|
||||
cached_bind_group.insert((view_uniforms_id, source.id(), bind_group));
|
||||
|
|
|
@ -4,9 +4,8 @@ use bevy_render::{
|
|||
camera::{CameraOutputMode, ExtractedCamera},
|
||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, LoadOp, Operations,
|
||||
PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor,
|
||||
TextureViewId,
|
||||
BindGroup, BindGroupEntries, LoadOp, Operations, PipelineCache, RenderPassColorAttachment,
|
||||
RenderPassDescriptor, SamplerDescriptor, TextureViewId,
|
||||
},
|
||||
renderer::RenderContext,
|
||||
view::ViewTarget,
|
||||
|
@ -57,23 +56,11 @@ impl ViewNode for UpscalingNode {
|
|||
.render_device()
|
||||
.create_sampler(&SamplerDescriptor::default());
|
||||
|
||||
let bind_group =
|
||||
render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: &blit_pipeline.texture_bind_group,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(upscaled_texture),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(&sampler),
|
||||
},
|
||||
],
|
||||
});
|
||||
let bind_group = render_context.render_device().create_bind_group(
|
||||
None,
|
||||
&blit_pipeline.texture_bind_group,
|
||||
&BindGroupEntries::sequential((upscaled_texture, &sampler)),
|
||||
);
|
||||
|
||||
let (_, bind_group) = cached_bind_group.insert((upscaled_texture.id(), bind_group));
|
||||
bind_group
|
||||
|
|
|
@ -52,7 +52,7 @@ use bevy_render::{
|
|||
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
|
||||
render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass},
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroupLayoutEntry, BindingType, Buffer, BufferBindingType, BufferInitDescriptor,
|
||||
BufferUsages, Shader, ShaderStages, ShaderType, VertexAttribute, VertexBufferLayout,
|
||||
VertexFormat, VertexStepMode,
|
||||
|
@ -422,14 +422,11 @@ fn prepare_line_gizmo_bind_group(
|
|||
) {
|
||||
if let Some(binding) = line_gizmo_uniforms.uniforms().binding() {
|
||||
commands.insert_resource(LineGizmoUniformBindgroup {
|
||||
bindgroup: render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: binding,
|
||||
}],
|
||||
label: Some("LineGizmoUniform bindgroup"),
|
||||
layout: &line_gizmo_uniform_layout.layout,
|
||||
}),
|
||||
bindgroup: render_device.create_bind_group(
|
||||
"LineGizmoUniform bindgroup",
|
||||
&line_gizmo_uniform_layout.layout,
|
||||
&BindGroupEntries::single(binding),
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,16 +191,11 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode {
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
let bind_group_1 = render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("deferred_lighting_layout_group_1"),
|
||||
layout: &deferred_lighting_layout.bind_group_layout_1,
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: deferred_lighting_pass_id_binding.clone(),
|
||||
}],
|
||||
});
|
||||
let bind_group_1 = render_context.render_device().create_bind_group(
|
||||
"deferred_lighting_layout_group_1",
|
||||
&deferred_lighting_layout.bind_group_layout_1,
|
||||
&BindGroupEntries::single(deferred_lighting_pass_id_binding),
|
||||
);
|
||||
|
||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
label: Some("deferred_lighting_pass"),
|
||||
|
|
|
@ -7,8 +7,8 @@ use bevy_render::{
|
|||
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
||||
render_asset::RenderAssets,
|
||||
render_resource::{
|
||||
BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, SamplerBindingType,
|
||||
Shader, ShaderStages, TextureSampleType, TextureViewDimension,
|
||||
BindGroupLayoutEntry, BindingType, Sampler, SamplerBindingType, Shader, ShaderStages,
|
||||
TextureSampleType, TextureView, TextureViewDimension,
|
||||
},
|
||||
texture::{FallbackImageCubemap, Image},
|
||||
};
|
||||
|
@ -65,8 +65,7 @@ pub fn get_bindings<'a>(
|
|||
environment_map_light: Option<&EnvironmentMapLight>,
|
||||
images: &'a RenderAssets<Image>,
|
||||
fallback_image_cubemap: &'a FallbackImageCubemap,
|
||||
bindings: [u32; 3],
|
||||
) -> [BindGroupEntry<'a>; 3] {
|
||||
) -> (&'a TextureView, &'a TextureView, &'a Sampler) {
|
||||
let (diffuse_map, specular_map) = match (
|
||||
environment_map_light.and_then(|env_map| images.get(&env_map.diffuse_map)),
|
||||
environment_map_light.and_then(|env_map| images.get(&env_map.specular_map)),
|
||||
|
@ -80,20 +79,7 @@ pub fn get_bindings<'a>(
|
|||
),
|
||||
};
|
||||
|
||||
[
|
||||
BindGroupEntry {
|
||||
binding: bindings[0],
|
||||
resource: BindingResource::TextureView(diffuse_map),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: bindings[1],
|
||||
resource: BindingResource::TextureView(specular_map),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: bindings[2],
|
||||
resource: BindingResource::Sampler(&fallback_image_cubemap.sampler),
|
||||
},
|
||||
]
|
||||
(diffuse_map, specular_map, &fallback_image_cubemap.sampler)
|
||||
}
|
||||
|
||||
pub fn get_bind_group_layout_entries(bindings: [u32; 3]) -> [BindGroupLayoutEntry; 3] {
|
||||
|
|
|
@ -35,7 +35,7 @@ use bevy_render::{
|
|||
RenderPhase, SetItemPipeline, TrackedRenderPass,
|
||||
},
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroupLayoutEntry, BindingType, BufferBindingType, ColorTargetState, ColorWrites,
|
||||
CompareFunction, DepthBiasState, DepthStencilState, DynamicUniformBuffer, FragmentState,
|
||||
FrontFace, MultisampleState, PipelineCache, PolygonMode, PrimitiveState, PushConstantRange,
|
||||
|
@ -713,42 +713,22 @@ pub fn prepare_prepass_view_bind_group<M: Material>(
|
|||
view_uniforms.uniforms.binding(),
|
||||
globals_buffer.buffer.binding(),
|
||||
) {
|
||||
prepass_view_bind_group.no_motion_vectors =
|
||||
Some(render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: view_binding.clone(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: globals_binding.clone(),
|
||||
},
|
||||
],
|
||||
label: Some("prepass_view_no_motion_vectors_bind_group"),
|
||||
layout: &prepass_pipeline.view_layout_no_motion_vectors,
|
||||
}));
|
||||
prepass_view_bind_group.no_motion_vectors = Some(render_device.create_bind_group(
|
||||
"prepass_view_no_motion_vectors_bind_group",
|
||||
&prepass_pipeline.view_layout_no_motion_vectors,
|
||||
&BindGroupEntries::sequential((view_binding.clone(), globals_binding.clone())),
|
||||
));
|
||||
|
||||
if let Some(previous_view_proj_binding) = previous_view_proj_uniforms.uniforms.binding() {
|
||||
prepass_view_bind_group.motion_vectors =
|
||||
Some(render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: view_binding,
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: globals_binding,
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: previous_view_proj_binding,
|
||||
},
|
||||
],
|
||||
label: Some("prepass_view_motion_vectors_bind_group"),
|
||||
layout: &prepass_pipeline.view_layout_motion_vectors,
|
||||
}));
|
||||
prepass_view_bind_group.motion_vectors = Some(render_device.create_bind_group(
|
||||
"prepass_view_motion_vectors_bind_group",
|
||||
&prepass_pipeline.view_layout_motion_vectors,
|
||||
&BindGroupEntries::sequential((
|
||||
view_binding,
|
||||
globals_binding,
|
||||
previous_view_proj_binding,
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy_core_pipeline::prepass::ViewPrepassTextures;
|
||||
use bevy_render::render_resource::{
|
||||
BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, ShaderStages,
|
||||
TextureAspect, TextureSampleType, TextureView, TextureViewDescriptor, TextureViewDimension,
|
||||
BindGroupLayoutEntry, BindingType, ShaderStages, TextureAspect, TextureSampleType, TextureView,
|
||||
TextureViewDescriptor, TextureViewDimension,
|
||||
};
|
||||
use bevy_utils::default;
|
||||
use smallvec::SmallVec;
|
||||
|
@ -83,51 +83,7 @@ pub fn get_bind_group_layout_entries(
|
|||
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 {
|
||||
pub fn get_bindings(prepass_textures: Option<&ViewPrepassTextures>) -> [Option<TextureView>; 4] {
|
||||
let depth_desc = TextureViewDescriptor {
|
||||
label: Some("prepass_depth"),
|
||||
aspect: TextureAspect::DepthOnly,
|
||||
|
@ -149,10 +105,5 @@ pub fn get_bindings(prepass_textures: Option<&ViewPrepassTextures>) -> PrepassBi
|
|||
.and_then(|x| x.deferred.as_ref())
|
||||
.map(|texture| texture.default_view.clone());
|
||||
|
||||
PrepassBindingsSet {
|
||||
depth_view,
|
||||
normal_view,
|
||||
motion_vectors_view,
|
||||
deferred_view,
|
||||
}
|
||||
[depth_view, normal_view, motion_vectors_view, deferred_view]
|
||||
}
|
||||
|
|
|
@ -4,8 +4,7 @@ use bevy_math::Mat4;
|
|||
use bevy_render::{
|
||||
mesh::morph::MAX_MORPH_WEIGHTS,
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindingResource, Buffer, TextureView,
|
||||
BindGroup, BindGroupLayout, BindGroupLayoutDescriptor, BindingResource, Buffer, TextureView,
|
||||
},
|
||||
renderer::RenderDevice,
|
||||
};
|
||||
|
@ -179,11 +178,11 @@ impl MeshLayouts {
|
|||
// ---------- BindGroup methods ----------
|
||||
|
||||
pub fn model_only(&self, render_device: &RenderDevice, model: &BindingResource) -> BindGroup {
|
||||
render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[entry::model(0, model.clone())],
|
||||
layout: &self.model_only,
|
||||
label: Some("model_only_mesh_bind_group"),
|
||||
})
|
||||
render_device.create_bind_group(
|
||||
"model_only_mesh_bind_group",
|
||||
&self.model_only,
|
||||
&[entry::model(0, model.clone())],
|
||||
)
|
||||
}
|
||||
pub fn skinned(
|
||||
&self,
|
||||
|
@ -191,11 +190,11 @@ impl MeshLayouts {
|
|||
model: &BindingResource,
|
||||
skin: &Buffer,
|
||||
) -> BindGroup {
|
||||
render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[entry::model(0, model.clone()), entry::skinning(1, skin)],
|
||||
layout: &self.skinned,
|
||||
label: Some("skinned_mesh_bind_group"),
|
||||
})
|
||||
render_device.create_bind_group(
|
||||
"skinned_mesh_bind_group",
|
||||
&self.skinned,
|
||||
&[entry::model(0, model.clone()), entry::skinning(1, skin)],
|
||||
)
|
||||
}
|
||||
pub fn morphed(
|
||||
&self,
|
||||
|
@ -204,15 +203,15 @@ impl MeshLayouts {
|
|||
weights: &Buffer,
|
||||
targets: &TextureView,
|
||||
) -> BindGroup {
|
||||
render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[
|
||||
render_device.create_bind_group(
|
||||
"morphed_mesh_bind_group",
|
||||
&self.morphed,
|
||||
&[
|
||||
entry::model(0, model.clone()),
|
||||
entry::weights(2, weights),
|
||||
entry::targets(3, targets),
|
||||
],
|
||||
layout: &self.morphed,
|
||||
label: Some("morphed_mesh_bind_group"),
|
||||
})
|
||||
)
|
||||
}
|
||||
pub fn morphed_skinned(
|
||||
&self,
|
||||
|
@ -222,15 +221,15 @@ impl MeshLayouts {
|
|||
weights: &Buffer,
|
||||
targets: &TextureView,
|
||||
) -> BindGroup {
|
||||
render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[
|
||||
render_device.create_bind_group(
|
||||
"morphed_skinned_mesh_bind_group",
|
||||
&self.morphed_skinned,
|
||||
&[
|
||||
entry::model(0, model.clone()),
|
||||
entry::skinning(1, skin),
|
||||
entry::weights(2, weights),
|
||||
entry::targets(3, targets),
|
||||
],
|
||||
layout: &self.morphed_skinned,
|
||||
label: Some("morphed_skinned_mesh_bind_group"),
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ use bevy_render::{
|
|||
globals::{GlobalsBuffer, GlobalsUniform},
|
||||
render_asset::RenderAssets,
|
||||
render_resource::{
|
||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroupLayoutEntry, BindingResource, BindingType, BufferBindingType, SamplerBindingType,
|
||||
ShaderStages, ShaderType, TextureFormat, TextureSampleType, TextureViewDimension,
|
||||
BindGroup, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType,
|
||||
BufferBindingType, DynamicBindGroupEntries, SamplerBindingType, ShaderStages, ShaderType,
|
||||
TextureFormat, TextureSampleType, TextureViewDimension,
|
||||
},
|
||||
renderer::RenderDevice,
|
||||
texture::{BevyDefault, FallbackImageCubemap, FallbackImageMsaa, Image},
|
||||
|
@ -383,8 +383,8 @@ pub fn prepare_mesh_view_bind_groups(
|
|||
) {
|
||||
for (
|
||||
entity,
|
||||
view_shadow_bindings,
|
||||
view_cluster_bindings,
|
||||
shadow_bindings,
|
||||
cluster_bindings,
|
||||
ssao_textures,
|
||||
prepass_textures,
|
||||
environment_map,
|
||||
|
@ -395,108 +395,58 @@ pub fn prepare_mesh_view_bind_groups(
|
|||
.image_for_samplecount(1, TextureFormat::bevy_default())
|
||||
.texture_view
|
||||
.clone();
|
||||
let ssao_view = ssao_textures
|
||||
.map(|t| &t.screen_space_ambient_occlusion_texture.default_view)
|
||||
.unwrap_or(&fallback_ssao);
|
||||
|
||||
let layout = &mesh_pipeline.get_view_layout(
|
||||
MeshPipelineViewLayoutKey::from(*msaa)
|
||||
| MeshPipelineViewLayoutKey::from(prepass_textures),
|
||||
);
|
||||
|
||||
let mut entries = vec![
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: view_binding.clone(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: light_binding.clone(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: BindingResource::TextureView(
|
||||
&view_shadow_bindings.point_light_depth_texture_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 3,
|
||||
resource: BindingResource::Sampler(&shadow_samplers.point_light_sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 4,
|
||||
resource: BindingResource::TextureView(
|
||||
&view_shadow_bindings.directional_light_depth_texture_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 5,
|
||||
resource: BindingResource::Sampler(&shadow_samplers.directional_light_sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 6,
|
||||
resource: point_light_binding.clone(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 7,
|
||||
resource: view_cluster_bindings.light_index_lists_binding().unwrap(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 8,
|
||||
resource: view_cluster_bindings.offsets_and_counts_binding().unwrap(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 9,
|
||||
resource: globals.clone(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 10,
|
||||
resource: fog_binding.clone(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 11,
|
||||
resource: BindingResource::TextureView(
|
||||
ssao_textures
|
||||
.map(|t| &t.screen_space_ambient_occlusion_texture.default_view)
|
||||
.unwrap_or(&fallback_ssao),
|
||||
),
|
||||
},
|
||||
];
|
||||
let mut entries = DynamicBindGroupEntries::new_with_indices((
|
||||
(0, view_binding.clone()),
|
||||
(1, light_binding.clone()),
|
||||
(2, &shadow_bindings.point_light_depth_texture_view),
|
||||
(3, &shadow_samplers.point_light_sampler),
|
||||
(4, &shadow_bindings.directional_light_depth_texture_view),
|
||||
(5, &shadow_samplers.directional_light_sampler),
|
||||
(6, point_light_binding.clone()),
|
||||
(7, cluster_bindings.light_index_lists_binding().unwrap()),
|
||||
(8, cluster_bindings.offsets_and_counts_binding().unwrap()),
|
||||
(9, globals.clone()),
|
||||
(10, fog_binding.clone()),
|
||||
(11, ssao_view),
|
||||
));
|
||||
|
||||
let env_map = environment_map::get_bindings(
|
||||
environment_map,
|
||||
&images,
|
||||
&fallback_cubemap,
|
||||
[12, 13, 14],
|
||||
);
|
||||
entries.extend_from_slice(&env_map);
|
||||
let env_map_bindings =
|
||||
environment_map::get_bindings(environment_map, &images, &fallback_cubemap);
|
||||
entries = entries.extend_with_indices((
|
||||
(12, env_map_bindings.0),
|
||||
(13, env_map_bindings.1),
|
||||
(14, env_map_bindings.2),
|
||||
));
|
||||
|
||||
let tonemapping_luts =
|
||||
get_lut_bindings(&images, &tonemapping_luts, tonemapping, [15, 16]);
|
||||
entries.extend_from_slice(&tonemapping_luts);
|
||||
|
||||
let label = Some("mesh_view_bind_group");
|
||||
let lut_bindings = get_lut_bindings(&images, &tonemapping_luts, tonemapping);
|
||||
entries = entries.extend_with_indices(((15, lut_bindings.0), (16, lut_bindings.1)));
|
||||
|
||||
// When using WebGL, we can't have a depth texture with multisampling
|
||||
let prepass_bindings = if cfg!(any(not(feature = "webgl"), not(target_arch = "wasm32")))
|
||||
|| (cfg!(all(feature = "webgl", target_arch = "wasm32")) && msaa.samples() == 1)
|
||||
let prepass_bindings;
|
||||
if cfg!(any(not(feature = "webgl"), not(target_arch = "wasm32"))) || msaa.samples() == 1
|
||||
{
|
||||
Some(prepass::get_bindings(prepass_textures))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// This if statement is here to make the borrow checker happy.
|
||||
// Ideally we could just have `entries.extend_from_slice(&prepass_bindings.get_entries([17, 18, 19, 20]));`
|
||||
// in the existing if statement above, but that either doesn't allow `prepass_bindings` to live long enough,
|
||||
// as its used when creating the bind group at the end of the function, or causes a `cannot move out of` error.
|
||||
if let Some(prepass_bindings) = &prepass_bindings {
|
||||
entries.extend_from_slice(&prepass_bindings.get_entries([17, 18, 19, 20]));
|
||||
prepass_bindings = prepass::get_bindings(prepass_textures);
|
||||
for (binding, index) in prepass_bindings
|
||||
.iter()
|
||||
.map(Option::as_ref)
|
||||
.zip([17, 18, 19, 20])
|
||||
.flat_map(|(b, i)| b.map(|b| (b, i)))
|
||||
{
|
||||
entries = entries.extend_with_indices(((index, binding),));
|
||||
}
|
||||
}
|
||||
|
||||
commands.entity(entity).insert(MeshViewBindGroup {
|
||||
value: render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &entries,
|
||||
label,
|
||||
layout,
|
||||
}),
|
||||
value: render_device.create_bind_group("mesh_view_bind_group", layout, &entries),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,11 @@ use bevy_render::{
|
|||
prelude::Camera,
|
||||
render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner},
|
||||
render_resource::{
|
||||
AddressMode, BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout,
|
||||
BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType,
|
||||
BufferBindingType, CachedComputePipelineId, ComputePassDescriptor,
|
||||
ComputePipelineDescriptor, Extent3d, FilterMode, PipelineCache, Sampler,
|
||||
SamplerBindingType, SamplerDescriptor, Shader, ShaderDefVal, ShaderStages, ShaderType,
|
||||
SpecializedComputePipeline, SpecializedComputePipelines, StorageTextureAccess,
|
||||
AddressMode, BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroupLayoutEntry, BindingType, BufferBindingType, CachedComputePipelineId,
|
||||
ComputePassDescriptor, ComputePipelineDescriptor, Extent3d, FilterMode, PipelineCache,
|
||||
Sampler, SamplerBindingType, SamplerDescriptor, Shader, ShaderDefVal, ShaderStages,
|
||||
ShaderType, SpecializedComputePipeline, SpecializedComputePipelines, StorageTextureAccess,
|
||||
TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages,
|
||||
TextureView, TextureViewDescriptor, TextureViewDimension,
|
||||
},
|
||||
|
@ -776,171 +775,63 @@ fn prepare_ssao_bind_groups(
|
|||
};
|
||||
|
||||
for (entity, ssao_textures, prepass_textures) in &views {
|
||||
let common_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("ssao_common_bind_group"),
|
||||
layout: &pipelines.common_bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::Sampler(&pipelines.point_clamp_sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: view_uniforms.clone(),
|
||||
},
|
||||
],
|
||||
});
|
||||
let common_bind_group = render_device.create_bind_group(
|
||||
"ssao_common_bind_group",
|
||||
&pipelines.common_bind_group_layout,
|
||||
&BindGroupEntries::sequential((&pipelines.point_clamp_sampler, view_uniforms.clone())),
|
||||
);
|
||||
|
||||
let preprocess_depth_mip_view_descriptor = TextureViewDescriptor {
|
||||
format: Some(TextureFormat::R16Float),
|
||||
dimension: Some(TextureViewDimension::D2),
|
||||
mip_level_count: Some(1),
|
||||
..default()
|
||||
let create_depth_view = |mip_level| {
|
||||
ssao_textures
|
||||
.preprocessed_depth_texture
|
||||
.texture
|
||||
.create_view(&TextureViewDescriptor {
|
||||
label: Some("ssao_preprocessed_depth_texture_mip_view"),
|
||||
base_mip_level: mip_level,
|
||||
format: Some(TextureFormat::R16Float),
|
||||
dimension: Some(TextureViewDimension::D2),
|
||||
mip_level_count: Some(1),
|
||||
..default()
|
||||
})
|
||||
};
|
||||
|
||||
let preprocess_depth_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("ssao_preprocess_depth_bind_group"),
|
||||
layout: &pipelines.preprocess_depth_bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(
|
||||
&prepass_textures.depth.as_ref().unwrap().default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures
|
||||
.preprocessed_depth_texture
|
||||
.texture
|
||||
.create_view(&TextureViewDescriptor {
|
||||
label: Some("ssao_preprocessed_depth_texture_mip_view_0"),
|
||||
base_mip_level: 0,
|
||||
..preprocess_depth_mip_view_descriptor
|
||||
}),
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures
|
||||
.preprocessed_depth_texture
|
||||
.texture
|
||||
.create_view(&TextureViewDescriptor {
|
||||
label: Some("ssao_preprocessed_depth_texture_mip_view_1"),
|
||||
base_mip_level: 1,
|
||||
..preprocess_depth_mip_view_descriptor
|
||||
}),
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 3,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures
|
||||
.preprocessed_depth_texture
|
||||
.texture
|
||||
.create_view(&TextureViewDescriptor {
|
||||
label: Some("ssao_preprocessed_depth_texture_mip_view_2"),
|
||||
base_mip_level: 2,
|
||||
..preprocess_depth_mip_view_descriptor
|
||||
}),
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 4,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures
|
||||
.preprocessed_depth_texture
|
||||
.texture
|
||||
.create_view(&TextureViewDescriptor {
|
||||
label: Some("ssao_preprocessed_depth_texture_mip_view_3"),
|
||||
base_mip_level: 3,
|
||||
..preprocess_depth_mip_view_descriptor
|
||||
}),
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 5,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures
|
||||
.preprocessed_depth_texture
|
||||
.texture
|
||||
.create_view(&TextureViewDescriptor {
|
||||
label: Some("ssao_preprocessed_depth_texture_mip_view_4"),
|
||||
base_mip_level: 4,
|
||||
..preprocess_depth_mip_view_descriptor
|
||||
}),
|
||||
),
|
||||
},
|
||||
],
|
||||
});
|
||||
let preprocess_depth_bind_group = render_device.create_bind_group(
|
||||
"ssao_preprocess_depth_bind_group",
|
||||
&pipelines.preprocess_depth_bind_group_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
&prepass_textures.depth.as_ref().unwrap().default_view,
|
||||
&create_depth_view(0),
|
||||
&create_depth_view(1),
|
||||
&create_depth_view(2),
|
||||
&create_depth_view(3),
|
||||
&create_depth_view(4),
|
||||
)),
|
||||
);
|
||||
|
||||
let gtao_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("ssao_gtao_bind_group"),
|
||||
layout: &pipelines.gtao_bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures.preprocessed_depth_texture.default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::TextureView(
|
||||
&prepass_textures.normal.as_ref().unwrap().default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: BindingResource::TextureView(&pipelines.hilbert_index_lut),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 3,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures.ssao_noisy_texture.default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 4,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures.depth_differences_texture.default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 5,
|
||||
resource: globals_uniforms.clone(),
|
||||
},
|
||||
],
|
||||
});
|
||||
let gtao_bind_group = render_device.create_bind_group(
|
||||
"ssao_gtao_bind_group",
|
||||
&pipelines.gtao_bind_group_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
&ssao_textures.preprocessed_depth_texture.default_view,
|
||||
&prepass_textures.normal.as_ref().unwrap().default_view,
|
||||
&pipelines.hilbert_index_lut,
|
||||
&ssao_textures.ssao_noisy_texture.default_view,
|
||||
&ssao_textures.depth_differences_texture.default_view,
|
||||
globals_uniforms.clone(),
|
||||
)),
|
||||
);
|
||||
|
||||
let spatial_denoise_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("ssao_spatial_denoise_bind_group"),
|
||||
layout: &pipelines.spatial_denoise_bind_group_layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures.ssao_noisy_texture.default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures.depth_differences_texture.default_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
resource: BindingResource::TextureView(
|
||||
&ssao_textures
|
||||
.screen_space_ambient_occlusion_texture
|
||||
.default_view,
|
||||
),
|
||||
},
|
||||
],
|
||||
});
|
||||
let spatial_denoise_bind_group = render_device.create_bind_group(
|
||||
"ssao_spatial_denoise_bind_group",
|
||||
&pipelines.spatial_denoise_bind_group_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
&ssao_textures.ssao_noisy_texture.default_view,
|
||||
&ssao_textures.depth_differences_texture.default_view,
|
||||
&ssao_textures
|
||||
.screen_space_ambient_occlusion_texture
|
||||
.default_view,
|
||||
)),
|
||||
);
|
||||
|
||||
commands.entity(entity).insert(SsaoBindGroups {
|
||||
common_bind_group,
|
||||
|
|
|
@ -9,10 +9,7 @@ use crate::{
|
|||
pub use bevy_render_macros::AsBindGroup;
|
||||
use encase::ShaderType;
|
||||
use std::ops::Deref;
|
||||
use wgpu::{
|
||||
BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
|
||||
BindingResource,
|
||||
};
|
||||
use wgpu::{BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource};
|
||||
|
||||
define_atomic_id!(BindGroupId);
|
||||
render_resource_wrapper!(ErasedBindGroup, wgpu::BindGroup);
|
||||
|
@ -289,11 +286,7 @@ pub trait AsBindGroup {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: Self::label(),
|
||||
layout,
|
||||
entries: &entries,
|
||||
});
|
||||
let bind_group = render_device.create_bind_group(Self::label(), layout, &entries);
|
||||
|
||||
Ok(PreparedBindGroup {
|
||||
bindings,
|
||||
|
|
282
crates/bevy_render/src/render_resource/bind_group_entries.rs
Normal file
282
crates/bevy_render/src/render_resource/bind_group_entries.rs
Normal file
|
@ -0,0 +1,282 @@
|
|||
use bevy_utils::all_tuples_with_size;
|
||||
use wgpu::{BindGroupEntry, BindingResource};
|
||||
|
||||
use super::{Sampler, TextureView};
|
||||
|
||||
/// Helper for constructing bindgroups.
|
||||
///
|
||||
/// Allows constructing the descriptor's entries as:
|
||||
/// ```ignore
|
||||
/// render_device.create_bind_group(
|
||||
/// "my_bind_group",
|
||||
/// &my_layout,
|
||||
/// &BindGroupEntries::with_indices((
|
||||
/// (2, &my_sampler),
|
||||
/// (3, my_uniform),
|
||||
/// )),
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// instead of
|
||||
///
|
||||
/// ```ignore
|
||||
/// render_device.create_bind_group(
|
||||
/// "my_bind_group",
|
||||
/// &my_layout,
|
||||
/// &[
|
||||
/// BindGroupEntry {
|
||||
/// binding: 2,
|
||||
/// resource: BindingResource::Sampler(&my_sampler),
|
||||
/// },
|
||||
/// BindGroupEntry {
|
||||
/// binding: 3,
|
||||
/// resource: my_uniform,
|
||||
/// },
|
||||
/// ],
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// or
|
||||
///
|
||||
/// ```ignore
|
||||
/// render_device.create_bind_group(
|
||||
/// "my_bind_group",
|
||||
/// &my_layout,
|
||||
/// &BindGroupEntries::sequential((
|
||||
/// &my_sampler,
|
||||
/// my_uniform,
|
||||
/// )),
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// instead of
|
||||
///
|
||||
/// ```ignore
|
||||
/// render_device.create_bind_group(
|
||||
/// "my_bind_group",
|
||||
/// &my_layout,
|
||||
/// &[
|
||||
/// BindGroupEntry {
|
||||
/// binding: 0,
|
||||
/// resource: BindingResource::Sampler(&my_sampler),
|
||||
/// },
|
||||
/// BindGroupEntry {
|
||||
/// binding: 1,
|
||||
/// resource: my_uniform,
|
||||
/// },
|
||||
/// ],
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// or
|
||||
///
|
||||
/// ```ignore
|
||||
/// render_device.create_bind_group(
|
||||
/// "my_bind_group",
|
||||
/// &my_layout,
|
||||
/// &BindGroupEntries::single(my_uniform),
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// instead of
|
||||
///
|
||||
/// ```ignore
|
||||
/// render_device.create_bind_group(
|
||||
/// "my_bind_group",
|
||||
/// &my_layout,
|
||||
/// &[
|
||||
/// BindGroupEntry {
|
||||
/// binding: 0,
|
||||
/// resource: my_uniform,
|
||||
/// },
|
||||
/// ],
|
||||
/// );
|
||||
/// ```
|
||||
|
||||
pub struct BindGroupEntries<'b, const N: usize = 1> {
|
||||
entries: [BindGroupEntry<'b>; N],
|
||||
}
|
||||
|
||||
impl<'b, const N: usize> BindGroupEntries<'b, N> {
|
||||
#[inline]
|
||||
pub fn sequential(resources: impl IntoBindingArray<'b, N>) -> Self {
|
||||
let mut i = 0;
|
||||
Self {
|
||||
entries: resources.into_array().map(|resource| {
|
||||
let binding = i;
|
||||
i += 1;
|
||||
BindGroupEntry { binding, resource }
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn with_indices(indexed_resources: impl IntoIndexedBindingArray<'b, N>) -> Self {
|
||||
Self {
|
||||
entries: indexed_resources
|
||||
.into_array()
|
||||
.map(|(binding, resource)| BindGroupEntry { binding, resource }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> BindGroupEntries<'b, 1> {
|
||||
pub fn single(resource: impl IntoBinding<'b>) -> [BindGroupEntry<'b>; 1] {
|
||||
[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: resource.into_binding(),
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, const N: usize> std::ops::Deref for BindGroupEntries<'b, N> {
|
||||
type Target = [BindGroupEntry<'b>];
|
||||
|
||||
fn deref(&self) -> &[BindGroupEntry<'b>] {
|
||||
&self.entries
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoBinding<'a> {
|
||||
fn into_binding(self) -> BindingResource<'a>;
|
||||
}
|
||||
|
||||
impl<'a> IntoBinding<'a> for &'a TextureView {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
BindingResource::TextureView(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBinding<'a> for &'a [&'a wgpu::TextureView] {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
BindingResource::TextureViewArray(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBinding<'a> for &'a Sampler {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
BindingResource::Sampler(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBinding<'a> for BindingResource<'a> {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoBinding<'a> for wgpu::BufferBinding<'a> {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
BindingResource::Buffer(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoBindingArray<'b, const N: usize> {
|
||||
fn into_array(self) -> [BindingResource<'b>; N];
|
||||
}
|
||||
|
||||
macro_rules! impl_to_binding_slice {
|
||||
($N: expr, $(($T: ident, $I: ident)),*) => {
|
||||
impl<'b, $($T: IntoBinding<'b>),*> IntoBindingArray<'b, $N> for ($($T,)*) {
|
||||
#[inline]
|
||||
fn into_array(self) -> [BindingResource<'b>; $N] {
|
||||
let ($($I,)*) = self;
|
||||
[$($I.into_binding(), )*]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
all_tuples_with_size!(impl_to_binding_slice, 1, 32, T, s);
|
||||
|
||||
pub trait IntoIndexedBindingArray<'b, const N: usize> {
|
||||
fn into_array(self) -> [(u32, BindingResource<'b>); N];
|
||||
}
|
||||
|
||||
macro_rules! impl_to_indexed_binding_slice {
|
||||
($N: expr, $(($T: ident, $S: ident, $I: ident)),*) => {
|
||||
impl<'b, $($T: IntoBinding<'b>),*> IntoIndexedBindingArray<'b, $N> for ($((u32, $T),)*) {
|
||||
#[inline]
|
||||
fn into_array(self) -> [(u32, BindingResource<'b>); $N] {
|
||||
let ($(($S, $I),)*) = self;
|
||||
[$(($S, $I.into_binding())), *]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
all_tuples_with_size!(impl_to_indexed_binding_slice, 1, 32, T, n, s);
|
||||
|
||||
pub struct DynamicBindGroupEntries<'b> {
|
||||
entries: Vec<BindGroupEntry<'b>>,
|
||||
}
|
||||
|
||||
impl<'b> DynamicBindGroupEntries<'b> {
|
||||
pub fn sequential<const N: usize>(entries: impl IntoBindingArray<'b, N>) -> Self {
|
||||
Self {
|
||||
entries: entries
|
||||
.into_array()
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(ix, resource)| BindGroupEntry {
|
||||
binding: ix as u32,
|
||||
resource,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend_sequential<const N: usize>(
|
||||
mut self,
|
||||
entries: impl IntoBindingArray<'b, N>,
|
||||
) -> Self {
|
||||
let start = self.entries.last().unwrap().binding + 1;
|
||||
self.entries.extend(
|
||||
entries
|
||||
.into_array()
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(ix, resource)| BindGroupEntry {
|
||||
binding: start + ix as u32,
|
||||
resource,
|
||||
}),
|
||||
);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn new_with_indices<const N: usize>(entries: impl IntoIndexedBindingArray<'b, N>) -> Self {
|
||||
Self {
|
||||
entries: entries
|
||||
.into_array()
|
||||
.into_iter()
|
||||
.map(|(binding, resource)| BindGroupEntry { binding, resource })
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend_with_indices<const N: usize>(
|
||||
mut self,
|
||||
entries: impl IntoIndexedBindingArray<'b, N>,
|
||||
) -> Self {
|
||||
self.entries.extend(
|
||||
entries
|
||||
.into_array()
|
||||
.into_iter()
|
||||
.map(|(binding, resource)| BindGroupEntry { binding, resource }),
|
||||
);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> std::ops::Deref for DynamicBindGroupEntries<'b> {
|
||||
type Target = [BindGroupEntry<'b>];
|
||||
|
||||
fn deref(&self) -> &[BindGroupEntry<'b>] {
|
||||
&self.entries
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
mod batched_uniform_buffer;
|
||||
mod bind_group;
|
||||
mod bind_group_entries;
|
||||
mod bind_group_layout;
|
||||
mod buffer;
|
||||
mod buffer_vec;
|
||||
|
@ -14,6 +15,7 @@ mod texture;
|
|||
mod uniform_buffer;
|
||||
|
||||
pub use bind_group::*;
|
||||
pub use bind_group_entries::*;
|
||||
pub use bind_group_layout::*;
|
||||
pub use buffer::*;
|
||||
pub use buffer_vec::*;
|
||||
|
|
|
@ -13,6 +13,8 @@ use wgpu::{
|
|||
util::BufferInitDescriptor, BindingResource, BufferBinding, BufferDescriptor, BufferUsages,
|
||||
};
|
||||
|
||||
use super::IntoBinding;
|
||||
|
||||
/// Stores data to be transferred to the GPU and made accessible to shaders as a uniform buffer.
|
||||
///
|
||||
/// Uniform buffers are available to shaders on a read-only basis. Uniform buffers are commonly used to make available to shaders
|
||||
|
@ -139,6 +141,16 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ShaderType + WriteInto> IntoBinding<'a> for &'a UniformBuffer<T> {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
self.buffer()
|
||||
.expect("Failed to get buffer")
|
||||
.as_entire_buffer_binding()
|
||||
.into_binding()
|
||||
}
|
||||
}
|
||||
|
||||
/// Stores data to be transferred to the GPU and made accessible to shaders as a dynamic uniform buffer.
|
||||
///
|
||||
/// Dynamic uniform buffers are available to shaders on a read-only basis. Dynamic uniform buffers are commonly used to make
|
||||
|
@ -367,3 +379,10 @@ impl<'a> BufferMut for QueueWriteBufferViewWrapper<'a> {
|
|||
self.buffer_view.write(offset, val);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ShaderType + WriteInto> IntoBinding<'a> for &'a DynamicUniformBuffer<T> {
|
||||
#[inline]
|
||||
fn into_binding(self) -> BindingResource<'a> {
|
||||
self.binding().unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ use crate::render_resource::{
|
|||
RenderPipeline, Sampler, Texture,
|
||||
};
|
||||
use bevy_ecs::system::Resource;
|
||||
use wgpu::{util::DeviceExt, BufferAsyncError, BufferBindingType};
|
||||
use wgpu::{
|
||||
util::DeviceExt, BindGroupDescriptor, BindGroupEntry, BufferAsyncError, BufferBindingType,
|
||||
};
|
||||
|
||||
use super::RenderQueue;
|
||||
|
||||
|
@ -82,8 +84,17 @@ impl RenderDevice {
|
|||
|
||||
/// Creates a new [`BindGroup`](wgpu::BindGroup).
|
||||
#[inline]
|
||||
pub fn create_bind_group(&self, desc: &wgpu::BindGroupDescriptor) -> BindGroup {
|
||||
let wgpu_bind_group = self.device.create_bind_group(desc);
|
||||
pub fn create_bind_group<'a>(
|
||||
&self,
|
||||
label: impl Into<wgpu::Label<'a>>,
|
||||
layout: &'a BindGroupLayout,
|
||||
entries: &'a [BindGroupEntry<'a>],
|
||||
) -> BindGroup {
|
||||
let wgpu_bind_group = self.device.create_bind_group(&BindGroupDescriptor {
|
||||
label: label.into(),
|
||||
layout,
|
||||
entries,
|
||||
});
|
||||
BindGroup::from(wgpu_bind_group)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use crate::{
|
||||
render_resource::{PipelineCache, SpecializedRenderPipelines, SurfaceTexture, TextureView},
|
||||
render_resource::{
|
||||
BindGroupEntries, PipelineCache, SpecializedRenderPipelines, SurfaceTexture, TextureView,
|
||||
},
|
||||
renderer::{RenderAdapter, RenderDevice, RenderInstance},
|
||||
texture::TextureFormatPixelInfo,
|
||||
Extract, ExtractSchedule, Render, RenderApp, RenderSet,
|
||||
|
@ -413,14 +415,11 @@ pub fn prepare_windows(
|
|||
usage: BufferUsages::MAP_READ | BufferUsages::COPY_DST,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
let bind_group = render_device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("screenshot-to-screen-bind-group"),
|
||||
layout: &screenshot_pipeline.bind_group_layout,
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::TextureView(&texture_view),
|
||||
}],
|
||||
});
|
||||
let bind_group = render_device.create_bind_group(
|
||||
"screenshot-to-screen-bind-group",
|
||||
&screenshot_pipeline.bind_group_layout,
|
||||
&BindGroupEntries::single(&texture_view),
|
||||
);
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&screenshot_pipeline,
|
||||
|
|
|
@ -596,14 +596,11 @@ pub fn prepare_mesh2d_bind_group(
|
|||
) {
|
||||
if let Some(binding) = mesh2d_uniforms.binding() {
|
||||
commands.insert_resource(Mesh2dBindGroup {
|
||||
value: render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: binding,
|
||||
}],
|
||||
label: Some("mesh2d_bind_group"),
|
||||
layout: &mesh2d_pipeline.mesh_layout,
|
||||
}),
|
||||
value: render_device.create_bind_group(
|
||||
"mesh2d_bind_group",
|
||||
&mesh2d_pipeline.mesh_layout,
|
||||
&BindGroupEntries::single(binding),
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -626,20 +623,11 @@ pub fn prepare_mesh2d_view_bind_groups(
|
|||
globals_buffer.buffer.binding(),
|
||||
) {
|
||||
for entity in &views {
|
||||
let view_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: view_binding.clone(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: globals.clone(),
|
||||
},
|
||||
],
|
||||
label: Some("mesh2d_view_bind_group"),
|
||||
layout: &mesh2d_pipeline.view_layout,
|
||||
});
|
||||
let view_bind_group = render_device.create_bind_group(
|
||||
"mesh2d_view_bind_group",
|
||||
&mesh2d_pipeline.view_layout,
|
||||
&BindGroupEntries::sequential((view_binding.clone(), globals.clone())),
|
||||
);
|
||||
|
||||
commands.entity(entity).insert(Mesh2dViewBindGroup {
|
||||
value: view_bind_group,
|
||||
|
|
|
@ -21,7 +21,7 @@ use bevy_render::{
|
|||
DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, RenderPhase, SetItemPipeline,
|
||||
TrackedRenderPass,
|
||||
},
|
||||
render_resource::*,
|
||||
render_resource::{BindGroupEntries, *},
|
||||
renderer::{RenderDevice, RenderQueue},
|
||||
texture::{
|
||||
BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
|
||||
|
@ -623,14 +623,11 @@ pub fn prepare_sprites(
|
|||
// Clear the sprite instances
|
||||
sprite_meta.sprite_instance_buffer.clear();
|
||||
|
||||
sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: view_binding,
|
||||
}],
|
||||
label: Some("sprite_view_bind_group"),
|
||||
layout: &sprite_pipeline.view_layout,
|
||||
}));
|
||||
sprite_meta.view_bind_group = Some(render_device.create_bind_group(
|
||||
"sprite_view_bind_group",
|
||||
&sprite_pipeline.view_layout,
|
||||
&BindGroupEntries::single(view_binding),
|
||||
));
|
||||
|
||||
// Index buffer indices
|
||||
let mut index = 0;
|
||||
|
@ -667,22 +664,14 @@ pub fn prepare_sprites(
|
|||
.values
|
||||
.entry(batch_image_handle)
|
||||
.or_insert_with(|| {
|
||||
render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(
|
||||
&gpu_image.texture_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(&gpu_image.sampler),
|
||||
},
|
||||
],
|
||||
label: Some("sprite_material_bind_group"),
|
||||
layout: &sprite_pipeline.material_layout,
|
||||
})
|
||||
render_device.create_bind_group(
|
||||
"sprite_material_bind_group",
|
||||
&sprite_pipeline.material_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
&gpu_image.texture_view,
|
||||
&gpu_image.sampler,
|
||||
)),
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d};
|
|||
use bevy_hierarchy::Parent;
|
||||
use bevy_render::render_phase::PhaseItem;
|
||||
use bevy_render::view::ViewVisibility;
|
||||
use bevy_render::{ExtractSchedule, Render};
|
||||
use bevy_render::{render_resource::BindGroupEntries, ExtractSchedule, Render};
|
||||
use bevy_window::{PrimaryWindow, Window};
|
||||
pub use pipeline::*;
|
||||
pub use render_pass::*;
|
||||
|
@ -812,14 +812,11 @@ pub fn prepare_uinodes(
|
|||
let mut batches: Vec<(Entity, UiBatch)> = Vec::with_capacity(*previous_len);
|
||||
|
||||
ui_meta.vertices.clear();
|
||||
ui_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: view_binding,
|
||||
}],
|
||||
label: Some("ui_view_bind_group"),
|
||||
layout: &ui_pipeline.view_layout,
|
||||
}));
|
||||
ui_meta.view_bind_group = Some(render_device.create_bind_group(
|
||||
"ui_view_bind_group",
|
||||
&ui_pipeline.view_layout,
|
||||
&BindGroupEntries::single(view_binding),
|
||||
));
|
||||
|
||||
// Vertex buffer index
|
||||
let mut index = 0;
|
||||
|
@ -851,24 +848,14 @@ pub fn prepare_uinodes(
|
|||
.values
|
||||
.entry(batch_image_handle)
|
||||
.or_insert_with(|| {
|
||||
render_device.create_bind_group(&BindGroupDescriptor {
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(
|
||||
&gpu_image.texture_view,
|
||||
),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(
|
||||
&gpu_image.sampler,
|
||||
),
|
||||
},
|
||||
],
|
||||
label: Some("ui_material_bind_group"),
|
||||
layout: &ui_pipeline.image_layout,
|
||||
})
|
||||
render_device.create_bind_group(
|
||||
"ui_material_bind_group",
|
||||
&ui_pipeline.image_layout,
|
||||
&BindGroupEntries::sequential((
|
||||
&gpu_image.texture_view,
|
||||
&gpu_image.sampler,
|
||||
)),
|
||||
)
|
||||
});
|
||||
|
||||
existing_batch = batches.last_mut();
|
||||
|
|
|
@ -136,3 +136,38 @@ pub fn all_tuples(input: TokenStream) -> TokenStream {
|
|||
)*
|
||||
})
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn all_tuples_with_size(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as AllTuples);
|
||||
let len = 1 + input.end - input.start;
|
||||
let mut ident_tuples = Vec::with_capacity(len);
|
||||
for i in 0..=len {
|
||||
let idents = input
|
||||
.idents
|
||||
.iter()
|
||||
.map(|ident| format_ident!("{}{}", ident, i));
|
||||
if input.idents.len() < 2 {
|
||||
ident_tuples.push(quote! {
|
||||
#(#idents)*
|
||||
});
|
||||
} else {
|
||||
ident_tuples.push(quote! {
|
||||
(#(#idents),*)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let macro_ident = &input.macro_ident;
|
||||
let invocations = (input.start..=input.end).map(|i| {
|
||||
let ident_tuples = &ident_tuples[..i];
|
||||
quote! {
|
||||
#macro_ident!(#i, #(#ident_tuples),*);
|
||||
}
|
||||
});
|
||||
TokenStream::from(quote! {
|
||||
#(
|
||||
#invocations
|
||||
)*
|
||||
})
|
||||
}
|
||||
|
|
|
@ -107,14 +107,11 @@ fn prepare_bind_group(
|
|||
render_device: Res<RenderDevice>,
|
||||
) {
|
||||
let view = gpu_images.get(&game_of_life_image.0).unwrap();
|
||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: &pipeline.texture_bind_group_layout,
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureView(&view.texture_view),
|
||||
}],
|
||||
});
|
||||
let bind_group = render_device.create_bind_group(
|
||||
None,
|
||||
&pipeline.texture_bind_group_layout,
|
||||
&BindGroupEntries::single(&view.texture_view),
|
||||
);
|
||||
commands.insert_resource(GameOfLifeImageBindGroup(bind_group));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,12 +20,12 @@ use bevy::{
|
|||
NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner,
|
||||
},
|
||||
render_resource::{
|
||||
BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||
BindGroupLayoutEntry, BindingResource, BindingType, CachedRenderPipelineId,
|
||||
ColorTargetState, ColorWrites, FragmentState, MultisampleState, Operations,
|
||||
PipelineCache, PrimitiveState, RenderPassColorAttachment, RenderPassDescriptor,
|
||||
RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages,
|
||||
ShaderType, TextureFormat, TextureSampleType, TextureViewDimension,
|
||||
BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
|
||||
BindingType, CachedRenderPipelineId, ColorTargetState, ColorWrites, FragmentState,
|
||||
MultisampleState, Operations, PipelineCache, PrimitiveState, RenderPassColorAttachment,
|
||||
RenderPassDescriptor, RenderPipelineDescriptor, Sampler, SamplerBindingType,
|
||||
SamplerDescriptor, ShaderStages, ShaderType, TextureFormat, TextureSampleType,
|
||||
TextureViewDimension,
|
||||
},
|
||||
renderer::{RenderContext, RenderDevice},
|
||||
texture::BevyDefault,
|
||||
|
@ -176,30 +176,19 @@ impl ViewNode for PostProcessNode {
|
|||
// The reason it doesn't work is because each post_process_write will alternate the source/destination.
|
||||
// The only way to have the correct source/destination for the bind_group
|
||||
// is to make sure you get it during the node execution.
|
||||
let bind_group = render_context
|
||||
.render_device()
|
||||
.create_bind_group(&BindGroupDescriptor {
|
||||
label: Some("post_process_bind_group"),
|
||||
layout: &post_process_pipeline.layout,
|
||||
// It's important for this to match the BindGroupLayout defined in the PostProcessPipeline
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
// Make sure to use the source view
|
||||
resource: BindingResource::TextureView(post_process.source),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
// Use the sampler created for the pipeline
|
||||
resource: BindingResource::Sampler(&post_process_pipeline.sampler),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 2,
|
||||
// Set the settings binding
|
||||
resource: settings_binding.clone(),
|
||||
},
|
||||
],
|
||||
});
|
||||
let bind_group = render_context.render_device().create_bind_group(
|
||||
"post_process_bind_group",
|
||||
&post_process_pipeline.layout,
|
||||
// It's important for this to match the BindGroupLayout defined in the PostProcessPipeline
|
||||
&BindGroupEntries::sequential((
|
||||
// Make sure to use the source view
|
||||
post_process.source,
|
||||
// Use the sampler created for the pipeline
|
||||
&post_process_pipeline.sampler,
|
||||
// Set the settings binding
|
||||
settings_binding.clone(),
|
||||
)),
|
||||
);
|
||||
|
||||
// Begin the render pass
|
||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||
|
|
|
@ -5,11 +5,8 @@ use bevy::{
|
|||
prelude::*,
|
||||
reflect::TypePath,
|
||||
render::{
|
||||
render_asset::RenderAssets,
|
||||
render_resource::{AsBindGroupError, PreparedBindGroup, *},
|
||||
renderer::RenderDevice,
|
||||
texture::FallbackImage,
|
||||
RenderApp,
|
||||
render_asset::RenderAssets, render_resource::*, renderer::RenderDevice,
|
||||
texture::FallbackImage, RenderApp,
|
||||
},
|
||||
};
|
||||
use std::{num::NonZeroU32, process::exit};
|
||||
|
@ -119,20 +116,11 @@ impl AsBindGroup for BindlessMaterial {
|
|||
textures[id] = &*image.texture_view;
|
||||
}
|
||||
|
||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
||||
label: "bindless_material_bind_group".into(),
|
||||
let bind_group = render_device.create_bind_group(
|
||||
"bindless_material_bind_group",
|
||||
layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: BindingResource::TextureViewArray(&textures[..]),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: BindingResource::Sampler(&fallback_image.sampler),
|
||||
},
|
||||
],
|
||||
});
|
||||
&BindGroupEntries::sequential((&textures[..], &fallback_image.sampler)),
|
||||
);
|
||||
|
||||
Ok(PreparedBindGroup {
|
||||
bindings: vec![],
|
||||
|
|
Loading…
Add table
Reference in a new issue