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
@ -170,30 +170,16 @@ impl ViewNode for BloomNode {
|
|||||||
|
|
||||||
// First downsample pass
|
// First downsample pass
|
||||||
{
|
{
|
||||||
let downsampling_first_bind_group =
|
let downsampling_first_bind_group = render_context.render_device().create_bind_group(
|
||||||
render_context
|
"bloom_downsampling_first_bind_group",
|
||||||
.render_device()
|
&downsampling_pipeline_res.bind_group_layout,
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
&BindGroupEntries::sequential((
|
||||||
label: Some("bloom_downsampling_first_bind_group"),
|
// Read from main texture directly
|
||||||
layout: &downsampling_pipeline_res.bind_group_layout,
|
view_target.main_texture_view(),
|
||||||
entries: &[
|
&bind_groups.sampler,
|
||||||
BindGroupEntry {
|
uniforms.clone(),
|
||||||
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 view = &bloom_texture.view(0);
|
let view = &bloom_texture.view(0);
|
||||||
let mut downsampling_first_pass =
|
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);
|
let mut downsampling_bind_groups = Vec::with_capacity(bind_group_count);
|
||||||
for mip in 1..bloom_texture.mip_count {
|
for mip in 1..bloom_texture.mip_count {
|
||||||
downsampling_bind_groups.push(render_device.create_bind_group(&BindGroupDescriptor {
|
downsampling_bind_groups.push(render_device.create_bind_group(
|
||||||
label: Some("bloom_downsampling_bind_group"),
|
"bloom_downsampling_bind_group",
|
||||||
layout: &downsampling_pipeline.bind_group_layout,
|
&downsampling_pipeline.bind_group_layout,
|
||||||
entries: &[
|
&BindGroupEntries::sequential((
|
||||||
BindGroupEntry {
|
&bloom_texture.view(mip - 1),
|
||||||
binding: 0,
|
sampler,
|
||||||
resource: BindingResource::TextureView(&bloom_texture.view(mip - 1)),
|
uniforms.binding().unwrap(),
|
||||||
},
|
)),
|
||||||
BindGroupEntry {
|
));
|
||||||
binding: 1,
|
|
||||||
resource: BindingResource::Sampler(sampler),
|
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: 2,
|
|
||||||
resource: uniforms.binding().unwrap(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut upsampling_bind_groups = Vec::with_capacity(bind_group_count);
|
let mut upsampling_bind_groups = Vec::with_capacity(bind_group_count);
|
||||||
for mip in (0..bloom_texture.mip_count).rev() {
|
for mip in (0..bloom_texture.mip_count).rev() {
|
||||||
upsampling_bind_groups.push(render_device.create_bind_group(&BindGroupDescriptor {
|
upsampling_bind_groups.push(render_device.create_bind_group(
|
||||||
label: Some("bloom_upsampling_bind_group"),
|
"bloom_upsampling_bind_group",
|
||||||
layout: &upsampling_pipeline.bind_group_layout,
|
&upsampling_pipeline.bind_group_layout,
|
||||||
entries: &[
|
&BindGroupEntries::sequential((
|
||||||
BindGroupEntry {
|
&bloom_texture.view(mip),
|
||||||
binding: 0,
|
sampler,
|
||||||
resource: BindingResource::TextureView(&bloom_texture.view(mip)),
|
uniforms.binding().unwrap(),
|
||||||
},
|
)),
|
||||||
BindGroupEntry {
|
));
|
||||||
binding: 1,
|
|
||||||
resource: BindingResource::Sampler(sampler),
|
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: 2,
|
|
||||||
resource: uniforms.binding().unwrap(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commands.entity(entity).insert(BloomBindGroups {
|
commands.entity(entity).insert(BloomBindGroups {
|
||||||
|
|||||||
@ -7,8 +7,8 @@ use bevy_render::{
|
|||||||
extract_component::{ComponentUniforms, DynamicUniformIndex},
|
extract_component::{ComponentUniforms, DynamicUniformIndex},
|
||||||
render_graph::{Node, NodeRunError, RenderGraphContext},
|
render_graph::{Node, NodeRunError, RenderGraphContext},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferId, Operations,
|
BindGroup, BindGroupEntries, BufferId, Operations, PipelineCache,
|
||||||
PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, TextureViewId,
|
RenderPassColorAttachment, RenderPassDescriptor, TextureViewId,
|
||||||
},
|
},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
view::{ExtractedView, ViewTarget},
|
view::{ExtractedView, ViewTarget},
|
||||||
@ -77,29 +77,15 @@ impl Node for CASNode {
|
|||||||
bind_group
|
bind_group
|
||||||
}
|
}
|
||||||
cached_bind_group => {
|
cached_bind_group => {
|
||||||
let bind_group =
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
render_context
|
"cas_bind_group",
|
||||||
.render_device()
|
&sharpening_pipeline.texture_bind_group,
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
&BindGroupEntries::sequential((
|
||||||
label: Some("cas_bind_group"),
|
view_target.source,
|
||||||
layout: &sharpening_pipeline.texture_bind_group,
|
&sharpening_pipeline.sampler,
|
||||||
entries: &[
|
uniforms,
|
||||||
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) =
|
let (_, _, bind_group) =
|
||||||
cached_bind_group.insert((uniforms_id, source.id(), 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_ecs::query::QueryItem;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||||
render_resource::{
|
render_resource::{Operations, PipelineCache, RenderPassDescriptor},
|
||||||
BindGroupDescriptor, BindGroupEntry, BindingResource, Operations, PipelineCache,
|
|
||||||
RenderPassDescriptor,
|
|
||||||
},
|
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,18 +91,11 @@ impl ViewNode for CopyDeferredLightingIdNode {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
let bind_group = render_context
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
.render_device()
|
"copy_deferred_lighting_id_bind_group",
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
©_deferred_lighting_id_pipeline.layout,
|
||||||
label: Some("copy_deferred_lighting_id_bind_group"),
|
&BindGroupEntries::single(&deferred_lighting_pass_id_texture.default_view),
|
||||||
layout: ©_deferred_lighting_id_pipeline.layout,
|
);
|
||||||
entries: &[BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: BindingResource::TextureView(
|
|
||||||
&deferred_lighting_pass_id_texture.default_view,
|
|
||||||
),
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||||
label: Some("copy_deferred_lighting_id_pass"),
|
label: Some("copy_deferred_lighting_id_pass"),
|
||||||
|
|||||||
@ -6,9 +6,8 @@ use bevy_ecs::query::QueryItem;
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, FilterMode, Operations,
|
BindGroup, BindGroupEntries, FilterMode, Operations, PipelineCache,
|
||||||
PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor,
|
RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor, TextureViewId,
|
||||||
TextureViewId,
|
|
||||||
},
|
},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
view::ViewTarget,
|
view::ViewTarget,
|
||||||
@ -61,23 +60,11 @@ impl ViewNode for FxaaNode {
|
|||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
|
||||||
let bind_group =
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
render_context
|
None,
|
||||||
.render_device()
|
&fxaa_pipeline.texture_bind_group,
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
&BindGroupEntries::sequential((source, &sampler)),
|
||||||
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) = cached_bind_group.insert((source.id(), bind_group));
|
let (_, bind_group) = cached_bind_group.insert((source.id(), bind_group));
|
||||||
bind_group
|
bind_group
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use bevy_ecs::prelude::*;
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
camera::ExtractedCamera,
|
camera::ExtractedCamera,
|
||||||
render_graph::{Node, NodeRunError, RenderGraphApp, RenderGraphContext},
|
render_graph::{Node, NodeRunError, RenderGraphApp, RenderGraphContext},
|
||||||
|
render_resource::BindGroupEntries,
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
view::{Msaa, ViewTarget},
|
view::{Msaa, ViewTarget},
|
||||||
Render, RenderSet,
|
Render, RenderSet,
|
||||||
@ -90,23 +91,11 @@ impl Node for MsaaWritebackNode {
|
|||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let bind_group =
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
render_context
|
None,
|
||||||
.render_device()
|
&blit_pipeline.texture_bind_group,
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
&BindGroupEntries::sequential((post_process.source, &blit_pipeline.sampler)),
|
||||||
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 mut render_pass = render_context
|
let mut render_pass = render_context
|
||||||
.command_encoder()
|
.command_encoder()
|
||||||
|
|||||||
@ -10,13 +10,13 @@ use bevy_render::{
|
|||||||
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||||
BindGroupLayoutEntry, BindingResource, BindingType, BufferBindingType,
|
BindGroupLayoutEntry, BindingType, BufferBindingType, CachedRenderPipelineId,
|
||||||
CachedRenderPipelineId, ColorTargetState, ColorWrites, CompareFunction, DepthBiasState,
|
ColorTargetState, ColorWrites, CompareFunction, DepthBiasState, DepthStencilState,
|
||||||
DepthStencilState, FragmentState, MultisampleState, PipelineCache, PrimitiveState,
|
FragmentState, MultisampleState, PipelineCache, PrimitiveState, RenderPipelineDescriptor,
|
||||||
RenderPipelineDescriptor, SamplerBindingType, Shader, ShaderStages, ShaderType,
|
SamplerBindingType, Shader, ShaderStages, ShaderType, SpecializedRenderPipeline,
|
||||||
SpecializedRenderPipeline, SpecializedRenderPipelines, StencilFaceState, StencilState,
|
SpecializedRenderPipelines, StencilFaceState, StencilState, TextureFormat,
|
||||||
TextureFormat, TextureSampleType, TextureViewDimension, VertexState,
|
TextureSampleType, TextureViewDimension, VertexState,
|
||||||
},
|
},
|
||||||
renderer::RenderDevice,
|
renderer::RenderDevice,
|
||||||
texture::{BevyDefault, Image},
|
texture::{BevyDefault, Image},
|
||||||
@ -224,24 +224,15 @@ fn prepare_skybox_bind_groups(
|
|||||||
if let (Some(skybox), Some(view_uniforms)) =
|
if let (Some(skybox), Some(view_uniforms)) =
|
||||||
(images.get(&skybox.0), view_uniforms.uniforms.binding())
|
(images.get(&skybox.0), view_uniforms.uniforms.binding())
|
||||||
{
|
{
|
||||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let bind_group = render_device.create_bind_group(
|
||||||
label: Some("skybox_bind_group"),
|
"skybox_bind_group",
|
||||||
layout: &pipeline.bind_group_layout,
|
&pipeline.bind_group_layout,
|
||||||
entries: &[
|
&BindGroupEntries::sequential((
|
||||||
BindGroupEntry {
|
&skybox.texture_view,
|
||||||
binding: 0,
|
&skybox.sampler,
|
||||||
resource: BindingResource::TextureView(&skybox.texture_view),
|
view_uniforms,
|
||||||
},
|
)),
|
||||||
BindGroupEntry {
|
);
|
||||||
binding: 1,
|
|
||||||
resource: BindingResource::Sampler(&skybox.sampler),
|
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: 2,
|
|
||||||
resource: view_uniforms,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
commands.entity(entity).insert(SkyboxBindGroup(bind_group));
|
commands.entity(entity).insert(SkyboxBindGroup(bind_group));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,13 +21,13 @@ use bevy_render::{
|
|||||||
prelude::{Camera, Projection},
|
prelude::{Camera, Projection},
|
||||||
render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner},
|
render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
|
||||||
BindGroupLayoutEntry, BindingResource, BindingType, CachedRenderPipelineId,
|
BindingType, CachedRenderPipelineId, ColorTargetState, ColorWrites, Extent3d, FilterMode,
|
||||||
ColorTargetState, ColorWrites, Extent3d, FilterMode, FragmentState, MultisampleState,
|
FragmentState, MultisampleState, Operations, PipelineCache, PrimitiveState,
|
||||||
Operations, PipelineCache, PrimitiveState, RenderPassColorAttachment, RenderPassDescriptor,
|
RenderPassColorAttachment, RenderPassDescriptor, RenderPipelineDescriptor, Sampler,
|
||||||
RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, Shader,
|
SamplerBindingType, SamplerDescriptor, Shader, ShaderStages, SpecializedRenderPipeline,
|
||||||
ShaderStages, SpecializedRenderPipeline, SpecializedRenderPipelines, TextureDescriptor,
|
SpecializedRenderPipelines, TextureDescriptor, TextureDimension, TextureFormat,
|
||||||
TextureDimension, TextureFormat, TextureSampleType, TextureUsages, TextureViewDimension,
|
TextureSampleType, TextureUsages, TextureViewDimension,
|
||||||
},
|
},
|
||||||
renderer::{RenderContext, RenderDevice},
|
renderer::{RenderContext, RenderDevice},
|
||||||
texture::{BevyDefault, CachedTexture, TextureCache},
|
texture::{BevyDefault, CachedTexture, TextureCache},
|
||||||
@ -197,45 +197,18 @@ impl ViewNode for TAANode {
|
|||||||
};
|
};
|
||||||
let view_target = view_target.post_process_write();
|
let view_target = view_target.post_process_write();
|
||||||
|
|
||||||
let taa_bind_group =
|
let taa_bind_group = render_context.render_device().create_bind_group(
|
||||||
render_context
|
"taa_bind_group",
|
||||||
.render_device()
|
&pipelines.taa_bind_group_layout,
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
&BindGroupEntries::sequential((
|
||||||
label: Some("taa_bind_group"),
|
view_target.source,
|
||||||
layout: &pipelines.taa_bind_group_layout,
|
&taa_history_textures.read.default_view,
|
||||||
entries: &[
|
&prepass_motion_vectors_texture.default_view,
|
||||||
BindGroupEntry {
|
&prepass_depth_texture.default_view,
|
||||||
binding: 0,
|
&pipelines.nearest_sampler,
|
||||||
resource: BindingResource::TextureView(view_target.source),
|
&pipelines.linear_sampler,
|
||||||
},
|
)),
|
||||||
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 mut taa_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
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>,
|
images: &'a RenderAssets<Image>,
|
||||||
tonemapping_luts: &'a TonemappingLuts,
|
tonemapping_luts: &'a TonemappingLuts,
|
||||||
tonemapping: &Tonemapping,
|
tonemapping: &Tonemapping,
|
||||||
bindings: [u32; 2],
|
) -> (&'a TextureView, &'a Sampler) {
|
||||||
) -> [BindGroupEntry<'a>; 2] {
|
|
||||||
let image = match tonemapping {
|
let image = match tonemapping {
|
||||||
// AgX lut texture used when tonemapping doesn't need a texture since it's very small (32x32x32)
|
// AgX lut texture used when tonemapping doesn't need a texture since it's very small (32x32x32)
|
||||||
Tonemapping::None
|
Tonemapping::None
|
||||||
@ -320,16 +319,7 @@ pub fn get_lut_bindings<'a>(
|
|||||||
Tonemapping::BlenderFilmic => &tonemapping_luts.blender_filmic,
|
Tonemapping::BlenderFilmic => &tonemapping_luts.blender_filmic,
|
||||||
};
|
};
|
||||||
let lut_image = images.get(image).unwrap();
|
let lut_image = images.get(image).unwrap();
|
||||||
[
|
(&lut_image.texture_view, &lut_image.sampler)
|
||||||
BindGroupEntry {
|
|
||||||
binding: bindings[0],
|
|
||||||
resource: BindingResource::TextureView(&lut_image.texture_view),
|
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: bindings[1],
|
|
||||||
resource: BindingResource::Sampler(&lut_image.sampler),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_lut_bind_group_layout_entries(bindings: [u32; 2]) -> [BindGroupLayoutEntry; 2] {
|
pub fn get_lut_bind_group_layout_entries(bindings: [u32; 2]) -> [BindGroupLayoutEntry; 2] {
|
||||||
|
|||||||
@ -7,9 +7,8 @@ use bevy_render::{
|
|||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, BufferId, LoadOp,
|
BindGroup, BindGroupEntries, BufferId, LoadOp, Operations, PipelineCache,
|
||||||
Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor,
|
RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor, TextureViewId,
|
||||||
SamplerDescriptor, TextureViewId,
|
|
||||||
},
|
},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
texture::Image,
|
texture::Image,
|
||||||
@ -88,36 +87,19 @@ impl ViewNode for TonemappingNode {
|
|||||||
|
|
||||||
let tonemapping_luts = world.resource::<TonemappingLuts>();
|
let tonemapping_luts = world.resource::<TonemappingLuts>();
|
||||||
|
|
||||||
let mut entries = vec![
|
let lut_bindings = get_lut_bindings(gpu_images, tonemapping_luts, tonemapping);
|
||||||
BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: view_uniforms.binding().unwrap(),
|
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: BindingResource::TextureView(source),
|
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: 2,
|
|
||||||
resource: BindingResource::Sampler(&sampler),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
entries.extend(get_lut_bindings(
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
gpu_images,
|
None,
|
||||||
tonemapping_luts,
|
&tonemapping_pipeline.texture_bind_group,
|
||||||
tonemapping,
|
&BindGroupEntries::sequential((
|
||||||
[3, 4],
|
view_uniforms,
|
||||||
));
|
source,
|
||||||
|
&sampler,
|
||||||
let bind_group =
|
lut_bindings.0,
|
||||||
render_context
|
lut_bindings.1,
|
||||||
.render_device()
|
)),
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
);
|
||||||
label: None,
|
|
||||||
layout: &tonemapping_pipeline.texture_bind_group,
|
|
||||||
entries: &entries,
|
|
||||||
});
|
|
||||||
|
|
||||||
let (_, _, bind_group) =
|
let (_, _, bind_group) =
|
||||||
cached_bind_group.insert((view_uniforms_id, source.id(), bind_group));
|
cached_bind_group.insert((view_uniforms_id, source.id(), bind_group));
|
||||||
|
|||||||
@ -4,9 +4,8 @@ use bevy_render::{
|
|||||||
camera::{CameraOutputMode, ExtractedCamera},
|
camera::{CameraOutputMode, ExtractedCamera},
|
||||||
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
render_graph::{NodeRunError, RenderGraphContext, ViewNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, LoadOp, Operations,
|
BindGroup, BindGroupEntries, LoadOp, Operations, PipelineCache, RenderPassColorAttachment,
|
||||||
PipelineCache, RenderPassColorAttachment, RenderPassDescriptor, SamplerDescriptor,
|
RenderPassDescriptor, SamplerDescriptor, TextureViewId,
|
||||||
TextureViewId,
|
|
||||||
},
|
},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
view::ViewTarget,
|
view::ViewTarget,
|
||||||
@ -57,23 +56,11 @@ impl ViewNode for UpscalingNode {
|
|||||||
.render_device()
|
.render_device()
|
||||||
.create_sampler(&SamplerDescriptor::default());
|
.create_sampler(&SamplerDescriptor::default());
|
||||||
|
|
||||||
let bind_group =
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
render_context
|
None,
|
||||||
.render_device()
|
&blit_pipeline.texture_bind_group,
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
&BindGroupEntries::sequential((upscaled_texture, &sampler)),
|
||||||
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) = cached_bind_group.insert((upscaled_texture.id(), bind_group));
|
let (_, bind_group) = cached_bind_group.insert((upscaled_texture.id(), bind_group));
|
||||||
bind_group
|
bind_group
|
||||||
|
|||||||
@ -52,7 +52,7 @@ use bevy_render::{
|
|||||||
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
|
render_asset::{PrepareAssetError, RenderAsset, RenderAssetPlugin, RenderAssets},
|
||||||
render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass},
|
render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||||
BindGroupLayoutEntry, BindingType, Buffer, BufferBindingType, BufferInitDescriptor,
|
BindGroupLayoutEntry, BindingType, Buffer, BufferBindingType, BufferInitDescriptor,
|
||||||
BufferUsages, Shader, ShaderStages, ShaderType, VertexAttribute, VertexBufferLayout,
|
BufferUsages, Shader, ShaderStages, ShaderType, VertexAttribute, VertexBufferLayout,
|
||||||
VertexFormat, VertexStepMode,
|
VertexFormat, VertexStepMode,
|
||||||
@ -422,14 +422,11 @@ fn prepare_line_gizmo_bind_group(
|
|||||||
) {
|
) {
|
||||||
if let Some(binding) = line_gizmo_uniforms.uniforms().binding() {
|
if let Some(binding) = line_gizmo_uniforms.uniforms().binding() {
|
||||||
commands.insert_resource(LineGizmoUniformBindgroup {
|
commands.insert_resource(LineGizmoUniformBindgroup {
|
||||||
bindgroup: render_device.create_bind_group(&BindGroupDescriptor {
|
bindgroup: render_device.create_bind_group(
|
||||||
entries: &[BindGroupEntry {
|
"LineGizmoUniform bindgroup",
|
||||||
binding: 0,
|
&line_gizmo_uniform_layout.layout,
|
||||||
resource: binding,
|
&BindGroupEntries::single(binding),
|
||||||
}],
|
),
|
||||||
label: Some("LineGizmoUniform bindgroup"),
|
|
||||||
layout: &line_gizmo_uniform_layout.layout,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -191,16 +191,11 @@ impl ViewNode for DeferredOpaquePass3dPbrLightingNode {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
let bind_group_1 = render_context
|
let bind_group_1 = render_context.render_device().create_bind_group(
|
||||||
.render_device()
|
"deferred_lighting_layout_group_1",
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
&deferred_lighting_layout.bind_group_layout_1,
|
||||||
label: Some("deferred_lighting_layout_group_1"),
|
&BindGroupEntries::single(deferred_lighting_pass_id_binding),
|
||||||
layout: &deferred_lighting_layout.bind_group_layout_1,
|
);
|
||||||
entries: &[BindGroupEntry {
|
|
||||||
binding: 0,
|
|
||||||
resource: deferred_lighting_pass_id_binding.clone(),
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||||
label: Some("deferred_lighting_pass"),
|
label: Some("deferred_lighting_pass"),
|
||||||
|
|||||||
@ -7,8 +7,8 @@ use bevy_render::{
|
|||||||
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
extract_component::{ExtractComponent, ExtractComponentPlugin},
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, SamplerBindingType,
|
BindGroupLayoutEntry, BindingType, Sampler, SamplerBindingType, Shader, ShaderStages,
|
||||||
Shader, ShaderStages, TextureSampleType, TextureViewDimension,
|
TextureSampleType, TextureView, TextureViewDimension,
|
||||||
},
|
},
|
||||||
texture::{FallbackImageCubemap, Image},
|
texture::{FallbackImageCubemap, Image},
|
||||||
};
|
};
|
||||||
@ -65,8 +65,7 @@ pub fn get_bindings<'a>(
|
|||||||
environment_map_light: Option<&EnvironmentMapLight>,
|
environment_map_light: Option<&EnvironmentMapLight>,
|
||||||
images: &'a RenderAssets<Image>,
|
images: &'a RenderAssets<Image>,
|
||||||
fallback_image_cubemap: &'a FallbackImageCubemap,
|
fallback_image_cubemap: &'a FallbackImageCubemap,
|
||||||
bindings: [u32; 3],
|
) -> (&'a TextureView, &'a TextureView, &'a Sampler) {
|
||||||
) -> [BindGroupEntry<'a>; 3] {
|
|
||||||
let (diffuse_map, specular_map) = match (
|
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.diffuse_map)),
|
||||||
environment_map_light.and_then(|env_map| images.get(&env_map.specular_map)),
|
environment_map_light.and_then(|env_map| images.get(&env_map.specular_map)),
|
||||||
@ -80,20 +79,7 @@ pub fn get_bindings<'a>(
|
|||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
[
|
(diffuse_map, specular_map, &fallback_image_cubemap.sampler)
|
||||||
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),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bind_group_layout_entries(bindings: [u32; 3]) -> [BindGroupLayoutEntry; 3] {
|
pub fn get_bind_group_layout_entries(bindings: [u32; 3]) -> [BindGroupLayoutEntry; 3] {
|
||||||
|
|||||||
@ -35,7 +35,7 @@ use bevy_render::{
|
|||||||
RenderPhase, SetItemPipeline, TrackedRenderPass,
|
RenderPhase, SetItemPipeline, TrackedRenderPass,
|
||||||
},
|
},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||||
BindGroupLayoutEntry, BindingType, BufferBindingType, ColorTargetState, ColorWrites,
|
BindGroupLayoutEntry, BindingType, BufferBindingType, ColorTargetState, ColorWrites,
|
||||||
CompareFunction, DepthBiasState, DepthStencilState, DynamicUniformBuffer, FragmentState,
|
CompareFunction, DepthBiasState, DepthStencilState, DynamicUniformBuffer, FragmentState,
|
||||||
FrontFace, MultisampleState, PipelineCache, PolygonMode, PrimitiveState, PushConstantRange,
|
FrontFace, MultisampleState, PipelineCache, PolygonMode, PrimitiveState, PushConstantRange,
|
||||||
@ -713,42 +713,22 @@ pub fn prepare_prepass_view_bind_group<M: Material>(
|
|||||||
view_uniforms.uniforms.binding(),
|
view_uniforms.uniforms.binding(),
|
||||||
globals_buffer.buffer.binding(),
|
globals_buffer.buffer.binding(),
|
||||||
) {
|
) {
|
||||||
prepass_view_bind_group.no_motion_vectors =
|
prepass_view_bind_group.no_motion_vectors = Some(render_device.create_bind_group(
|
||||||
Some(render_device.create_bind_group(&BindGroupDescriptor {
|
"prepass_view_no_motion_vectors_bind_group",
|
||||||
entries: &[
|
&prepass_pipeline.view_layout_no_motion_vectors,
|
||||||
BindGroupEntry {
|
&BindGroupEntries::sequential((view_binding.clone(), globals_binding.clone())),
|
||||||
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,
|
|
||||||
}));
|
|
||||||
|
|
||||||
if let Some(previous_view_proj_binding) = previous_view_proj_uniforms.uniforms.binding() {
|
if let Some(previous_view_proj_binding) = previous_view_proj_uniforms.uniforms.binding() {
|
||||||
prepass_view_bind_group.motion_vectors =
|
prepass_view_bind_group.motion_vectors = Some(render_device.create_bind_group(
|
||||||
Some(render_device.create_bind_group(&BindGroupDescriptor {
|
"prepass_view_motion_vectors_bind_group",
|
||||||
entries: &[
|
&prepass_pipeline.view_layout_motion_vectors,
|
||||||
BindGroupEntry {
|
&BindGroupEntries::sequential((
|
||||||
binding: 0,
|
view_binding,
|
||||||
resource: view_binding,
|
globals_binding,
|
||||||
},
|
previous_view_proj_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,
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use bevy_core_pipeline::prepass::ViewPrepassTextures;
|
use bevy_core_pipeline::prepass::ViewPrepassTextures;
|
||||||
use bevy_render::render_resource::{
|
use bevy_render::render_resource::{
|
||||||
BindGroupEntry, BindGroupLayoutEntry, BindingResource, BindingType, ShaderStages,
|
BindGroupLayoutEntry, BindingType, ShaderStages, TextureAspect, TextureSampleType, TextureView,
|
||||||
TextureAspect, TextureSampleType, TextureView, TextureViewDescriptor, TextureViewDimension,
|
TextureViewDescriptor, TextureViewDimension,
|
||||||
};
|
};
|
||||||
use bevy_utils::default;
|
use bevy_utils::default;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -83,51 +83,7 @@ pub fn get_bind_group_layout_entries(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needed so the texture views can live long enough.
|
pub fn get_bindings(prepass_textures: Option<&ViewPrepassTextures>) -> [Option<TextureView>; 4] {
|
||||||
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 {
|
let depth_desc = TextureViewDescriptor {
|
||||||
label: Some("prepass_depth"),
|
label: Some("prepass_depth"),
|
||||||
aspect: TextureAspect::DepthOnly,
|
aspect: TextureAspect::DepthOnly,
|
||||||
@ -149,10 +105,5 @@ pub fn get_bindings(prepass_textures: Option<&ViewPrepassTextures>) -> PrepassBi
|
|||||||
.and_then(|x| x.deferred.as_ref())
|
.and_then(|x| x.deferred.as_ref())
|
||||||
.map(|texture| texture.default_view.clone());
|
.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::{
|
use bevy_render::{
|
||||||
mesh::morph::MAX_MORPH_WEIGHTS,
|
mesh::morph::MAX_MORPH_WEIGHTS,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupLayout, BindGroupLayoutDescriptor,
|
BindGroup, BindGroupLayout, BindGroupLayoutDescriptor, BindingResource, Buffer, TextureView,
|
||||||
BindingResource, Buffer, TextureView,
|
|
||||||
},
|
},
|
||||||
renderer::RenderDevice,
|
renderer::RenderDevice,
|
||||||
};
|
};
|
||||||
@ -179,11 +178,11 @@ impl MeshLayouts {
|
|||||||
// ---------- BindGroup methods ----------
|
// ---------- BindGroup methods ----------
|
||||||
|
|
||||||
pub fn model_only(&self, render_device: &RenderDevice, model: &BindingResource) -> BindGroup {
|
pub fn model_only(&self, render_device: &RenderDevice, model: &BindingResource) -> BindGroup {
|
||||||
render_device.create_bind_group(&BindGroupDescriptor {
|
render_device.create_bind_group(
|
||||||
entries: &[entry::model(0, model.clone())],
|
"model_only_mesh_bind_group",
|
||||||
layout: &self.model_only,
|
&self.model_only,
|
||||||
label: Some("model_only_mesh_bind_group"),
|
&[entry::model(0, model.clone())],
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
pub fn skinned(
|
pub fn skinned(
|
||||||
&self,
|
&self,
|
||||||
@ -191,11 +190,11 @@ impl MeshLayouts {
|
|||||||
model: &BindingResource,
|
model: &BindingResource,
|
||||||
skin: &Buffer,
|
skin: &Buffer,
|
||||||
) -> BindGroup {
|
) -> BindGroup {
|
||||||
render_device.create_bind_group(&BindGroupDescriptor {
|
render_device.create_bind_group(
|
||||||
entries: &[entry::model(0, model.clone()), entry::skinning(1, skin)],
|
"skinned_mesh_bind_group",
|
||||||
layout: &self.skinned,
|
&self.skinned,
|
||||||
label: Some("skinned_mesh_bind_group"),
|
&[entry::model(0, model.clone()), entry::skinning(1, skin)],
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
pub fn morphed(
|
pub fn morphed(
|
||||||
&self,
|
&self,
|
||||||
@ -204,15 +203,15 @@ impl MeshLayouts {
|
|||||||
weights: &Buffer,
|
weights: &Buffer,
|
||||||
targets: &TextureView,
|
targets: &TextureView,
|
||||||
) -> BindGroup {
|
) -> BindGroup {
|
||||||
render_device.create_bind_group(&BindGroupDescriptor {
|
render_device.create_bind_group(
|
||||||
entries: &[
|
"morphed_mesh_bind_group",
|
||||||
|
&self.morphed,
|
||||||
|
&[
|
||||||
entry::model(0, model.clone()),
|
entry::model(0, model.clone()),
|
||||||
entry::weights(2, weights),
|
entry::weights(2, weights),
|
||||||
entry::targets(3, targets),
|
entry::targets(3, targets),
|
||||||
],
|
],
|
||||||
layout: &self.morphed,
|
)
|
||||||
label: Some("morphed_mesh_bind_group"),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
pub fn morphed_skinned(
|
pub fn morphed_skinned(
|
||||||
&self,
|
&self,
|
||||||
@ -222,15 +221,15 @@ impl MeshLayouts {
|
|||||||
weights: &Buffer,
|
weights: &Buffer,
|
||||||
targets: &TextureView,
|
targets: &TextureView,
|
||||||
) -> BindGroup {
|
) -> BindGroup {
|
||||||
render_device.create_bind_group(&BindGroupDescriptor {
|
render_device.create_bind_group(
|
||||||
entries: &[
|
"morphed_skinned_mesh_bind_group",
|
||||||
|
&self.morphed_skinned,
|
||||||
|
&[
|
||||||
entry::model(0, model.clone()),
|
entry::model(0, model.clone()),
|
||||||
entry::skinning(1, skin),
|
entry::skinning(1, skin),
|
||||||
entry::weights(2, weights),
|
entry::weights(2, weights),
|
||||||
entry::targets(3, targets),
|
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},
|
globals::{GlobalsBuffer, GlobalsUniform},
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
BindGroup, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType,
|
||||||
BindGroupLayoutEntry, BindingResource, BindingType, BufferBindingType, SamplerBindingType,
|
BufferBindingType, DynamicBindGroupEntries, SamplerBindingType, ShaderStages, ShaderType,
|
||||||
ShaderStages, ShaderType, TextureFormat, TextureSampleType, TextureViewDimension,
|
TextureFormat, TextureSampleType, TextureViewDimension,
|
||||||
},
|
},
|
||||||
renderer::RenderDevice,
|
renderer::RenderDevice,
|
||||||
texture::{BevyDefault, FallbackImageCubemap, FallbackImageMsaa, Image},
|
texture::{BevyDefault, FallbackImageCubemap, FallbackImageMsaa, Image},
|
||||||
@ -383,8 +383,8 @@ pub fn prepare_mesh_view_bind_groups(
|
|||||||
) {
|
) {
|
||||||
for (
|
for (
|
||||||
entity,
|
entity,
|
||||||
view_shadow_bindings,
|
shadow_bindings,
|
||||||
view_cluster_bindings,
|
cluster_bindings,
|
||||||
ssao_textures,
|
ssao_textures,
|
||||||
prepass_textures,
|
prepass_textures,
|
||||||
environment_map,
|
environment_map,
|
||||||
@ -395,108 +395,58 @@ pub fn prepare_mesh_view_bind_groups(
|
|||||||
.image_for_samplecount(1, TextureFormat::bevy_default())
|
.image_for_samplecount(1, TextureFormat::bevy_default())
|
||||||
.texture_view
|
.texture_view
|
||||||
.clone();
|
.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(
|
let layout = &mesh_pipeline.get_view_layout(
|
||||||
MeshPipelineViewLayoutKey::from(*msaa)
|
MeshPipelineViewLayoutKey::from(*msaa)
|
||||||
| MeshPipelineViewLayoutKey::from(prepass_textures),
|
| MeshPipelineViewLayoutKey::from(prepass_textures),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut entries = vec![
|
let mut entries = DynamicBindGroupEntries::new_with_indices((
|
||||||
BindGroupEntry {
|
(0, view_binding.clone()),
|
||||||
binding: 0,
|
(1, light_binding.clone()),
|
||||||
resource: view_binding.clone(),
|
(2, &shadow_bindings.point_light_depth_texture_view),
|
||||||
},
|
(3, &shadow_samplers.point_light_sampler),
|
||||||
BindGroupEntry {
|
(4, &shadow_bindings.directional_light_depth_texture_view),
|
||||||
binding: 1,
|
(5, &shadow_samplers.directional_light_sampler),
|
||||||
resource: light_binding.clone(),
|
(6, point_light_binding.clone()),
|
||||||
},
|
(7, cluster_bindings.light_index_lists_binding().unwrap()),
|
||||||
BindGroupEntry {
|
(8, cluster_bindings.offsets_and_counts_binding().unwrap()),
|
||||||
binding: 2,
|
(9, globals.clone()),
|
||||||
resource: BindingResource::TextureView(
|
(10, fog_binding.clone()),
|
||||||
&view_shadow_bindings.point_light_depth_texture_view,
|
(11, ssao_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 env_map = environment_map::get_bindings(
|
let env_map_bindings =
|
||||||
environment_map,
|
environment_map::get_bindings(environment_map, &images, &fallback_cubemap);
|
||||||
&images,
|
entries = entries.extend_with_indices((
|
||||||
&fallback_cubemap,
|
(12, env_map_bindings.0),
|
||||||
[12, 13, 14],
|
(13, env_map_bindings.1),
|
||||||
);
|
(14, env_map_bindings.2),
|
||||||
entries.extend_from_slice(&env_map);
|
));
|
||||||
|
|
||||||
let tonemapping_luts =
|
let lut_bindings = get_lut_bindings(&images, &tonemapping_luts, tonemapping);
|
||||||
get_lut_bindings(&images, &tonemapping_luts, tonemapping, [15, 16]);
|
entries = entries.extend_with_indices(((15, lut_bindings.0), (16, lut_bindings.1)));
|
||||||
entries.extend_from_slice(&tonemapping_luts);
|
|
||||||
|
|
||||||
let label = Some("mesh_view_bind_group");
|
|
||||||
|
|
||||||
// When using WebGL, we can't have a depth texture with multisampling
|
// 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")))
|
let prepass_bindings;
|
||||||
|| (cfg!(all(feature = "webgl", target_arch = "wasm32")) && msaa.samples() == 1)
|
if cfg!(any(not(feature = "webgl"), not(target_arch = "wasm32"))) || msaa.samples() == 1
|
||||||
{
|
{
|
||||||
Some(prepass::get_bindings(prepass_textures))
|
prepass_bindings = prepass::get_bindings(prepass_textures);
|
||||||
} else {
|
for (binding, index) in prepass_bindings
|
||||||
None
|
.iter()
|
||||||
};
|
.map(Option::as_ref)
|
||||||
|
.zip([17, 18, 19, 20])
|
||||||
// This if statement is here to make the borrow checker happy.
|
.flat_map(|(b, i)| b.map(|b| (b, i)))
|
||||||
// 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,
|
entries = entries.extend_with_indices(((index, binding),));
|
||||||
// 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]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commands.entity(entity).insert(MeshViewBindGroup {
|
commands.entity(entity).insert(MeshViewBindGroup {
|
||||||
value: render_device.create_bind_group(&BindGroupDescriptor {
|
value: render_device.create_bind_group("mesh_view_bind_group", layout, &entries),
|
||||||
entries: &entries,
|
|
||||||
label,
|
|
||||||
layout,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,12 +21,11 @@ use bevy_render::{
|
|||||||
prelude::Camera,
|
prelude::Camera,
|
||||||
render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner},
|
render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
AddressMode, BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout,
|
AddressMode, BindGroup, BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor,
|
||||||
BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType,
|
BindGroupLayoutEntry, BindingType, BufferBindingType, CachedComputePipelineId,
|
||||||
BufferBindingType, CachedComputePipelineId, ComputePassDescriptor,
|
ComputePassDescriptor, ComputePipelineDescriptor, Extent3d, FilterMode, PipelineCache,
|
||||||
ComputePipelineDescriptor, Extent3d, FilterMode, PipelineCache, Sampler,
|
Sampler, SamplerBindingType, SamplerDescriptor, Shader, ShaderDefVal, ShaderStages,
|
||||||
SamplerBindingType, SamplerDescriptor, Shader, ShaderDefVal, ShaderStages, ShaderType,
|
ShaderType, SpecializedComputePipeline, SpecializedComputePipelines, StorageTextureAccess,
|
||||||
SpecializedComputePipeline, SpecializedComputePipelines, StorageTextureAccess,
|
|
||||||
TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages,
|
TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages,
|
||||||
TextureView, TextureViewDescriptor, TextureViewDimension,
|
TextureView, TextureViewDescriptor, TextureViewDimension,
|
||||||
},
|
},
|
||||||
@ -776,171 +775,63 @@ fn prepare_ssao_bind_groups(
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (entity, ssao_textures, prepass_textures) in &views {
|
for (entity, ssao_textures, prepass_textures) in &views {
|
||||||
let common_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let common_bind_group = render_device.create_bind_group(
|
||||||
label: Some("ssao_common_bind_group"),
|
"ssao_common_bind_group",
|
||||||
layout: &pipelines.common_bind_group_layout,
|
&pipelines.common_bind_group_layout,
|
||||||
entries: &[
|
&BindGroupEntries::sequential((&pipelines.point_clamp_sampler, view_uniforms.clone())),
|
||||||
BindGroupEntry {
|
);
|
||||||
binding: 0,
|
|
||||||
resource: BindingResource::Sampler(&pipelines.point_clamp_sampler),
|
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: view_uniforms.clone(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
let preprocess_depth_mip_view_descriptor = TextureViewDescriptor {
|
let create_depth_view = |mip_level| {
|
||||||
format: Some(TextureFormat::R16Float),
|
ssao_textures
|
||||||
dimension: Some(TextureViewDimension::D2),
|
.preprocessed_depth_texture
|
||||||
mip_level_count: Some(1),
|
.texture
|
||||||
..default()
|
.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 {
|
let preprocess_depth_bind_group = render_device.create_bind_group(
|
||||||
label: Some("ssao_preprocess_depth_bind_group"),
|
"ssao_preprocess_depth_bind_group",
|
||||||
layout: &pipelines.preprocess_depth_bind_group_layout,
|
&pipelines.preprocess_depth_bind_group_layout,
|
||||||
entries: &[
|
&BindGroupEntries::sequential((
|
||||||
BindGroupEntry {
|
&prepass_textures.depth.as_ref().unwrap().default_view,
|
||||||
binding: 0,
|
&create_depth_view(0),
|
||||||
resource: BindingResource::TextureView(
|
&create_depth_view(1),
|
||||||
&prepass_textures.depth.as_ref().unwrap().default_view,
|
&create_depth_view(2),
|
||||||
),
|
&create_depth_view(3),
|
||||||
},
|
&create_depth_view(4),
|
||||||
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 gtao_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let gtao_bind_group = render_device.create_bind_group(
|
||||||
label: Some("ssao_gtao_bind_group"),
|
"ssao_gtao_bind_group",
|
||||||
layout: &pipelines.gtao_bind_group_layout,
|
&pipelines.gtao_bind_group_layout,
|
||||||
entries: &[
|
&BindGroupEntries::sequential((
|
||||||
BindGroupEntry {
|
&ssao_textures.preprocessed_depth_texture.default_view,
|
||||||
binding: 0,
|
&prepass_textures.normal.as_ref().unwrap().default_view,
|
||||||
resource: BindingResource::TextureView(
|
&pipelines.hilbert_index_lut,
|
||||||
&ssao_textures.preprocessed_depth_texture.default_view,
|
&ssao_textures.ssao_noisy_texture.default_view,
|
||||||
),
|
&ssao_textures.depth_differences_texture.default_view,
|
||||||
},
|
globals_uniforms.clone(),
|
||||||
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 spatial_denoise_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let spatial_denoise_bind_group = render_device.create_bind_group(
|
||||||
label: Some("ssao_spatial_denoise_bind_group"),
|
"ssao_spatial_denoise_bind_group",
|
||||||
layout: &pipelines.spatial_denoise_bind_group_layout,
|
&pipelines.spatial_denoise_bind_group_layout,
|
||||||
entries: &[
|
&BindGroupEntries::sequential((
|
||||||
BindGroupEntry {
|
&ssao_textures.ssao_noisy_texture.default_view,
|
||||||
binding: 0,
|
&ssao_textures.depth_differences_texture.default_view,
|
||||||
resource: BindingResource::TextureView(
|
&ssao_textures
|
||||||
&ssao_textures.ssao_noisy_texture.default_view,
|
.screen_space_ambient_occlusion_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,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
commands.entity(entity).insert(SsaoBindGroups {
|
commands.entity(entity).insert(SsaoBindGroups {
|
||||||
common_bind_group,
|
common_bind_group,
|
||||||
|
|||||||
@ -9,10 +9,7 @@ use crate::{
|
|||||||
pub use bevy_render_macros::AsBindGroup;
|
pub use bevy_render_macros::AsBindGroup;
|
||||||
use encase::ShaderType;
|
use encase::ShaderType;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use wgpu::{
|
use wgpu::{BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource};
|
||||||
BindGroupDescriptor, BindGroupEntry, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
|
|
||||||
BindingResource,
|
|
||||||
};
|
|
||||||
|
|
||||||
define_atomic_id!(BindGroupId);
|
define_atomic_id!(BindGroupId);
|
||||||
render_resource_wrapper!(ErasedBindGroup, wgpu::BindGroup);
|
render_resource_wrapper!(ErasedBindGroup, wgpu::BindGroup);
|
||||||
@ -289,11 +286,7 @@ pub trait AsBindGroup {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let bind_group = render_device.create_bind_group(Self::label(), layout, &entries);
|
||||||
label: Self::label(),
|
|
||||||
layout,
|
|
||||||
entries: &entries,
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(PreparedBindGroup {
|
Ok(PreparedBindGroup {
|
||||||
bindings,
|
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 batched_uniform_buffer;
|
||||||
mod bind_group;
|
mod bind_group;
|
||||||
|
mod bind_group_entries;
|
||||||
mod bind_group_layout;
|
mod bind_group_layout;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
mod buffer_vec;
|
mod buffer_vec;
|
||||||
@ -14,6 +15,7 @@ mod texture;
|
|||||||
mod uniform_buffer;
|
mod uniform_buffer;
|
||||||
|
|
||||||
pub use bind_group::*;
|
pub use bind_group::*;
|
||||||
|
pub use bind_group_entries::*;
|
||||||
pub use bind_group_layout::*;
|
pub use bind_group_layout::*;
|
||||||
pub use buffer::*;
|
pub use buffer::*;
|
||||||
pub use buffer_vec::*;
|
pub use buffer_vec::*;
|
||||||
|
|||||||
@ -13,6 +13,8 @@ use wgpu::{
|
|||||||
util::BufferInitDescriptor, BindingResource, BufferBinding, BufferDescriptor, BufferUsages,
|
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.
|
/// 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
|
/// 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.
|
/// 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
|
/// 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);
|
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,
|
RenderPipeline, Sampler, Texture,
|
||||||
};
|
};
|
||||||
use bevy_ecs::system::Resource;
|
use bevy_ecs::system::Resource;
|
||||||
use wgpu::{util::DeviceExt, BufferAsyncError, BufferBindingType};
|
use wgpu::{
|
||||||
|
util::DeviceExt, BindGroupDescriptor, BindGroupEntry, BufferAsyncError, BufferBindingType,
|
||||||
|
};
|
||||||
|
|
||||||
use super::RenderQueue;
|
use super::RenderQueue;
|
||||||
|
|
||||||
@ -82,8 +84,17 @@ impl RenderDevice {
|
|||||||
|
|
||||||
/// Creates a new [`BindGroup`](wgpu::BindGroup).
|
/// Creates a new [`BindGroup`](wgpu::BindGroup).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn create_bind_group(&self, desc: &wgpu::BindGroupDescriptor) -> BindGroup {
|
pub fn create_bind_group<'a>(
|
||||||
let wgpu_bind_group = self.device.create_bind_group(desc);
|
&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)
|
BindGroup::from(wgpu_bind_group)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
render_resource::{PipelineCache, SpecializedRenderPipelines, SurfaceTexture, TextureView},
|
render_resource::{
|
||||||
|
BindGroupEntries, PipelineCache, SpecializedRenderPipelines, SurfaceTexture, TextureView,
|
||||||
|
},
|
||||||
renderer::{RenderAdapter, RenderDevice, RenderInstance},
|
renderer::{RenderAdapter, RenderDevice, RenderInstance},
|
||||||
texture::TextureFormatPixelInfo,
|
texture::TextureFormatPixelInfo,
|
||||||
Extract, ExtractSchedule, Render, RenderApp, RenderSet,
|
Extract, ExtractSchedule, Render, RenderApp, RenderSet,
|
||||||
@ -413,14 +415,11 @@ pub fn prepare_windows(
|
|||||||
usage: BufferUsages::MAP_READ | BufferUsages::COPY_DST,
|
usage: BufferUsages::MAP_READ | BufferUsages::COPY_DST,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
});
|
});
|
||||||
let bind_group = render_device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bind_group = render_device.create_bind_group(
|
||||||
label: Some("screenshot-to-screen-bind-group"),
|
"screenshot-to-screen-bind-group",
|
||||||
layout: &screenshot_pipeline.bind_group_layout,
|
&screenshot_pipeline.bind_group_layout,
|
||||||
entries: &[wgpu::BindGroupEntry {
|
&BindGroupEntries::single(&texture_view),
|
||||||
binding: 0,
|
);
|
||||||
resource: wgpu::BindingResource::TextureView(&texture_view),
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
let pipeline_id = pipelines.specialize(
|
let pipeline_id = pipelines.specialize(
|
||||||
&pipeline_cache,
|
&pipeline_cache,
|
||||||
&screenshot_pipeline,
|
&screenshot_pipeline,
|
||||||
|
|||||||
@ -596,14 +596,11 @@ pub fn prepare_mesh2d_bind_group(
|
|||||||
) {
|
) {
|
||||||
if let Some(binding) = mesh2d_uniforms.binding() {
|
if let Some(binding) = mesh2d_uniforms.binding() {
|
||||||
commands.insert_resource(Mesh2dBindGroup {
|
commands.insert_resource(Mesh2dBindGroup {
|
||||||
value: render_device.create_bind_group(&BindGroupDescriptor {
|
value: render_device.create_bind_group(
|
||||||
entries: &[BindGroupEntry {
|
"mesh2d_bind_group",
|
||||||
binding: 0,
|
&mesh2d_pipeline.mesh_layout,
|
||||||
resource: binding,
|
&BindGroupEntries::single(binding),
|
||||||
}],
|
),
|
||||||
label: Some("mesh2d_bind_group"),
|
|
||||||
layout: &mesh2d_pipeline.mesh_layout,
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -626,20 +623,11 @@ pub fn prepare_mesh2d_view_bind_groups(
|
|||||||
globals_buffer.buffer.binding(),
|
globals_buffer.buffer.binding(),
|
||||||
) {
|
) {
|
||||||
for entity in &views {
|
for entity in &views {
|
||||||
let view_bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let view_bind_group = render_device.create_bind_group(
|
||||||
entries: &[
|
"mesh2d_view_bind_group",
|
||||||
BindGroupEntry {
|
&mesh2d_pipeline.view_layout,
|
||||||
binding: 0,
|
&BindGroupEntries::sequential((view_binding.clone(), globals.clone())),
|
||||||
resource: view_binding.clone(),
|
);
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: globals.clone(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
label: Some("mesh2d_view_bind_group"),
|
|
||||||
layout: &mesh2d_pipeline.view_layout,
|
|
||||||
});
|
|
||||||
|
|
||||||
commands.entity(entity).insert(Mesh2dViewBindGroup {
|
commands.entity(entity).insert(Mesh2dViewBindGroup {
|
||||||
value: view_bind_group,
|
value: view_bind_group,
|
||||||
|
|||||||
@ -21,7 +21,7 @@ use bevy_render::{
|
|||||||
DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, RenderPhase, SetItemPipeline,
|
DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, RenderPhase, SetItemPipeline,
|
||||||
TrackedRenderPass,
|
TrackedRenderPass,
|
||||||
},
|
},
|
||||||
render_resource::*,
|
render_resource::{BindGroupEntries, *},
|
||||||
renderer::{RenderDevice, RenderQueue},
|
renderer::{RenderDevice, RenderQueue},
|
||||||
texture::{
|
texture::{
|
||||||
BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
|
BevyDefault, DefaultImageSampler, GpuImage, Image, ImageSampler, TextureFormatPixelInfo,
|
||||||
@ -623,14 +623,11 @@ pub fn prepare_sprites(
|
|||||||
// Clear the sprite instances
|
// Clear the sprite instances
|
||||||
sprite_meta.sprite_instance_buffer.clear();
|
sprite_meta.sprite_instance_buffer.clear();
|
||||||
|
|
||||||
sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
|
sprite_meta.view_bind_group = Some(render_device.create_bind_group(
|
||||||
entries: &[BindGroupEntry {
|
"sprite_view_bind_group",
|
||||||
binding: 0,
|
&sprite_pipeline.view_layout,
|
||||||
resource: view_binding,
|
&BindGroupEntries::single(view_binding),
|
||||||
}],
|
));
|
||||||
label: Some("sprite_view_bind_group"),
|
|
||||||
layout: &sprite_pipeline.view_layout,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Index buffer indices
|
// Index buffer indices
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
@ -667,22 +664,14 @@ pub fn prepare_sprites(
|
|||||||
.values
|
.values
|
||||||
.entry(batch_image_handle)
|
.entry(batch_image_handle)
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
render_device.create_bind_group(&BindGroupDescriptor {
|
render_device.create_bind_group(
|
||||||
entries: &[
|
"sprite_material_bind_group",
|
||||||
BindGroupEntry {
|
&sprite_pipeline.material_layout,
|
||||||
binding: 0,
|
&BindGroupEntries::sequential((
|
||||||
resource: BindingResource::TextureView(
|
&gpu_image.texture_view,
|
||||||
&gpu_image.texture_view,
|
&gpu_image.sampler,
|
||||||
),
|
)),
|
||||||
},
|
)
|
||||||
BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: BindingResource::Sampler(&gpu_image.sampler),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
label: Some("sprite_material_bind_group"),
|
|
||||||
layout: &sprite_pipeline.material_layout,
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d};
|
|||||||
use bevy_hierarchy::Parent;
|
use bevy_hierarchy::Parent;
|
||||||
use bevy_render::render_phase::PhaseItem;
|
use bevy_render::render_phase::PhaseItem;
|
||||||
use bevy_render::view::ViewVisibility;
|
use bevy_render::view::ViewVisibility;
|
||||||
use bevy_render::{ExtractSchedule, Render};
|
use bevy_render::{render_resource::BindGroupEntries, ExtractSchedule, Render};
|
||||||
use bevy_window::{PrimaryWindow, Window};
|
use bevy_window::{PrimaryWindow, Window};
|
||||||
pub use pipeline::*;
|
pub use pipeline::*;
|
||||||
pub use render_pass::*;
|
pub use render_pass::*;
|
||||||
@ -812,14 +812,11 @@ pub fn prepare_uinodes(
|
|||||||
let mut batches: Vec<(Entity, UiBatch)> = Vec::with_capacity(*previous_len);
|
let mut batches: Vec<(Entity, UiBatch)> = Vec::with_capacity(*previous_len);
|
||||||
|
|
||||||
ui_meta.vertices.clear();
|
ui_meta.vertices.clear();
|
||||||
ui_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
|
ui_meta.view_bind_group = Some(render_device.create_bind_group(
|
||||||
entries: &[BindGroupEntry {
|
"ui_view_bind_group",
|
||||||
binding: 0,
|
&ui_pipeline.view_layout,
|
||||||
resource: view_binding,
|
&BindGroupEntries::single(view_binding),
|
||||||
}],
|
));
|
||||||
label: Some("ui_view_bind_group"),
|
|
||||||
layout: &ui_pipeline.view_layout,
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Vertex buffer index
|
// Vertex buffer index
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
@ -851,24 +848,14 @@ pub fn prepare_uinodes(
|
|||||||
.values
|
.values
|
||||||
.entry(batch_image_handle)
|
.entry(batch_image_handle)
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
render_device.create_bind_group(&BindGroupDescriptor {
|
render_device.create_bind_group(
|
||||||
entries: &[
|
"ui_material_bind_group",
|
||||||
BindGroupEntry {
|
&ui_pipeline.image_layout,
|
||||||
binding: 0,
|
&BindGroupEntries::sequential((
|
||||||
resource: BindingResource::TextureView(
|
&gpu_image.texture_view,
|
||||||
&gpu_image.texture_view,
|
&gpu_image.sampler,
|
||||||
),
|
)),
|
||||||
},
|
)
|
||||||
BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: BindingResource::Sampler(
|
|
||||||
&gpu_image.sampler,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
label: Some("ui_material_bind_group"),
|
|
||||||
layout: &ui_pipeline.image_layout,
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
existing_batch = batches.last_mut();
|
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>,
|
render_device: Res<RenderDevice>,
|
||||||
) {
|
) {
|
||||||
let view = gpu_images.get(&game_of_life_image.0).unwrap();
|
let view = gpu_images.get(&game_of_life_image.0).unwrap();
|
||||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let bind_group = render_device.create_bind_group(
|
||||||
label: None,
|
None,
|
||||||
layout: &pipeline.texture_bind_group_layout,
|
&pipeline.texture_bind_group_layout,
|
||||||
entries: &[BindGroupEntry {
|
&BindGroupEntries::single(&view.texture_view),
|
||||||
binding: 0,
|
);
|
||||||
resource: BindingResource::TextureView(&view.texture_view),
|
|
||||||
}],
|
|
||||||
});
|
|
||||||
commands.insert_resource(GameOfLifeImageBindGroup(bind_group));
|
commands.insert_resource(GameOfLifeImageBindGroup(bind_group));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,12 +20,12 @@ use bevy::{
|
|||||||
NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner,
|
NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner,
|
||||||
},
|
},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
|
BindGroupEntries, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry,
|
||||||
BindGroupLayoutEntry, BindingResource, BindingType, CachedRenderPipelineId,
|
BindingType, CachedRenderPipelineId, ColorTargetState, ColorWrites, FragmentState,
|
||||||
ColorTargetState, ColorWrites, FragmentState, MultisampleState, Operations,
|
MultisampleState, Operations, PipelineCache, PrimitiveState, RenderPassColorAttachment,
|
||||||
PipelineCache, PrimitiveState, RenderPassColorAttachment, RenderPassDescriptor,
|
RenderPassDescriptor, RenderPipelineDescriptor, Sampler, SamplerBindingType,
|
||||||
RenderPipelineDescriptor, Sampler, SamplerBindingType, SamplerDescriptor, ShaderStages,
|
SamplerDescriptor, ShaderStages, ShaderType, TextureFormat, TextureSampleType,
|
||||||
ShaderType, TextureFormat, TextureSampleType, TextureViewDimension,
|
TextureViewDimension,
|
||||||
},
|
},
|
||||||
renderer::{RenderContext, RenderDevice},
|
renderer::{RenderContext, RenderDevice},
|
||||||
texture::BevyDefault,
|
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 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
|
// The only way to have the correct source/destination for the bind_group
|
||||||
// is to make sure you get it during the node execution.
|
// is to make sure you get it during the node execution.
|
||||||
let bind_group = render_context
|
let bind_group = render_context.render_device().create_bind_group(
|
||||||
.render_device()
|
"post_process_bind_group",
|
||||||
.create_bind_group(&BindGroupDescriptor {
|
&post_process_pipeline.layout,
|
||||||
label: Some("post_process_bind_group"),
|
// It's important for this to match the BindGroupLayout defined in the PostProcessPipeline
|
||||||
layout: &post_process_pipeline.layout,
|
&BindGroupEntries::sequential((
|
||||||
// It's important for this to match the BindGroupLayout defined in the PostProcessPipeline
|
// Make sure to use the source view
|
||||||
entries: &[
|
post_process.source,
|
||||||
BindGroupEntry {
|
// Use the sampler created for the pipeline
|
||||||
binding: 0,
|
&post_process_pipeline.sampler,
|
||||||
// Make sure to use the source view
|
// Set the settings binding
|
||||||
resource: BindingResource::TextureView(post_process.source),
|
settings_binding.clone(),
|
||||||
},
|
)),
|
||||||
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(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
// Begin the render pass
|
// Begin the render pass
|
||||||
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
let mut render_pass = render_context.begin_tracked_render_pass(RenderPassDescriptor {
|
||||||
|
|||||||
@ -5,11 +5,8 @@ use bevy::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
reflect::TypePath,
|
reflect::TypePath,
|
||||||
render::{
|
render::{
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets, render_resource::*, renderer::RenderDevice,
|
||||||
render_resource::{AsBindGroupError, PreparedBindGroup, *},
|
texture::FallbackImage, RenderApp,
|
||||||
renderer::RenderDevice,
|
|
||||||
texture::FallbackImage,
|
|
||||||
RenderApp,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::{num::NonZeroU32, process::exit};
|
use std::{num::NonZeroU32, process::exit};
|
||||||
@ -119,20 +116,11 @@ impl AsBindGroup for BindlessMaterial {
|
|||||||
textures[id] = &*image.texture_view;
|
textures[id] = &*image.texture_view;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bind_group = render_device.create_bind_group(&BindGroupDescriptor {
|
let bind_group = render_device.create_bind_group(
|
||||||
label: "bindless_material_bind_group".into(),
|
"bindless_material_bind_group",
|
||||||
layout,
|
layout,
|
||||||
entries: &[
|
&BindGroupEntries::sequential((&textures[..], &fallback_image.sampler)),
|
||||||
BindGroupEntry {
|
);
|
||||||
binding: 0,
|
|
||||||
resource: BindingResource::TextureViewArray(&textures[..]),
|
|
||||||
},
|
|
||||||
BindGroupEntry {
|
|
||||||
binding: 1,
|
|
||||||
resource: BindingResource::Sampler(&fallback_image.sampler),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(PreparedBindGroup {
|
Ok(PreparedBindGroup {
|
||||||
bindings: vec![],
|
bindings: vec![],
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user