Skip to content

Commit 34aab16

Browse files
committed
Move storage buffer detection to RenderDevice
1 parent b77c4fc commit 34aab16

File tree

7 files changed

+69
-83
lines changed

7 files changed

+69
-83
lines changed

crates/bevy_pbr/src/lib.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ use bevy_render::{
4040
prelude::Color,
4141
render_graph::RenderGraph,
4242
render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions},
43-
render_resource::{Shader, SpecializedMeshPipelines, SupportedBindingTypes},
44-
renderer::RenderDevice,
43+
render_resource::{Shader, SpecializedMeshPipelines},
4544
view::VisibilitySystems,
4645
RenderApp, RenderStage,
4746
};
@@ -127,11 +126,6 @@ impl Plugin for PbrPlugin {
127126
},
128127
);
129128

130-
let supported_binding_types = SupportedBindingTypes::from_device(
131-
app.world.resource::<RenderDevice>(),
132-
CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
133-
);
134-
135129
let render_app = match app.get_sub_app_mut(RenderApp) {
136130
Ok(render_app) => render_app,
137131
Err(_) => return,
@@ -170,7 +164,7 @@ impl Plugin for PbrPlugin {
170164
.init_resource::<ShadowPipeline>()
171165
.init_resource::<DrawFunctions<Shadow>>()
172166
.init_resource::<LightMeta>()
173-
.insert_resource(GlobalLightMeta::new(supported_binding_types))
167+
.init_resource::<GlobalLightMeta>()
174168
.init_resource::<SpecializedMeshPipelines<ShadowPipeline>>();
175169

176170
let shadow_pass_node = ShadowPassNode::new(&mut render_app.world);

crates/bevy_pbr/src/light.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use bevy_render::{
99
color::Color,
1010
prelude::Image,
1111
primitives::{Aabb, CubemapFrusta, Frustum, Sphere},
12-
render_resource::SupportedBindingTypes,
12+
render_resource::BufferBindingType,
1313
renderer::RenderDevice,
1414
view::{ComputedVisibility, RenderLayers, Visibility, VisibleEntities},
1515
};
@@ -730,11 +730,12 @@ pub(crate) fn assign_lights_to_clusters(
730730
),
731731
);
732732

733-
let supports_storage_buffers = SupportedBindingTypes::from_device(
734-
render_device.into_inner(),
735-
CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
736-
)
737-
.contains(SupportedBindingTypes::STORAGE);
733+
let clustered_forward_buffer_binding_type =
734+
render_device.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
735+
let supports_storage_buffers = matches!(
736+
clustered_forward_buffer_binding_type,
737+
BufferBindingType::Storage { .. }
738+
);
738739
if lights.len() > MAX_POINT_LIGHTS && !supports_storage_buffers {
739740
lights.sort_by(|light_1, light_2| {
740741
point_light_order(

crates/bevy_pbr/src/pbr_material.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -373,11 +373,11 @@ impl SpecializedMaterial for StandardMaterial {
373373
StandardMaterialKey {
374374
normal_map: render_asset.has_normal_map,
375375
cull_mode: render_asset.cull_mode,
376-
use_storage_buffers: SupportedBindingTypes::from_device(
377-
render_device,
378-
CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
379-
)
380-
.contains(SupportedBindingTypes::STORAGE),
376+
use_storage_buffers: matches!(
377+
render_device
378+
.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT),
379+
BufferBindingType::Storage { .. }
380+
),
381381
}
382382
}
383383

crates/bevy_pbr/src/render/light.rs

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,10 @@ pub enum GpuPointLights {
102102
}
103103

104104
impl GpuPointLights {
105-
fn new(supported_binding_types: SupportedBindingTypes) -> Self {
106-
if supported_binding_types.contains(SupportedBindingTypes::STORAGE) {
107-
Self::storage()
108-
} else {
109-
Self::uniform()
105+
fn new(buffer_binding_type: BufferBindingType) -> Self {
106+
match buffer_binding_type {
107+
BufferBindingType::Storage { .. } => Self::storage(),
108+
BufferBindingType::Uniform => Self::uniform(),
110109
}
111110
}
112111

@@ -602,10 +601,20 @@ pub struct GlobalLightMeta {
602601
pub entity_to_index: HashMap<Entity, usize>,
603602
}
604603

604+
impl FromWorld for GlobalLightMeta {
605+
fn from_world(world: &mut World) -> Self {
606+
Self::new(
607+
world
608+
.resource::<RenderDevice>()
609+
.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT),
610+
)
611+
}
612+
}
613+
605614
impl GlobalLightMeta {
606-
pub fn new(supported_binding_types: SupportedBindingTypes) -> Self {
615+
pub fn new(buffer_binding_type: BufferBindingType) -> Self {
607616
Self {
608-
gpu_point_lights: GpuPointLights::new(supported_binding_types),
617+
gpu_point_lights: GpuPointLights::new(buffer_binding_type),
609618
entity_to_index: HashMap::default(),
610619
}
611620
}
@@ -1020,11 +1029,10 @@ enum ViewClusterBuffers {
10201029
}
10211030

10221031
impl ViewClusterBuffers {
1023-
fn new(supported_binding_types: SupportedBindingTypes) -> Self {
1024-
if supported_binding_types.contains(SupportedBindingTypes::STORAGE) {
1025-
Self::storage()
1026-
} else {
1027-
Self::uniform()
1032+
fn new(buffer_binding_type: BufferBindingType) -> Self {
1033+
match buffer_binding_type {
1034+
BufferBindingType::Storage { .. } => Self::storage(),
1035+
BufferBindingType::Uniform => Self::uniform(),
10281036
}
10291037
}
10301038

@@ -1055,11 +1063,11 @@ impl ViewClusterBindings {
10551063
const MAX_UNIFORM_ITEMS: usize = Self::MAX_OFFSETS / 4;
10561064
pub const MAX_INDICES: usize = 16384;
10571065

1058-
pub fn new(supported_binding_types: SupportedBindingTypes) -> Self {
1066+
pub fn new(buffer_binding_type: BufferBindingType) -> Self {
10591067
Self {
10601068
n_indices: 0,
10611069
n_offsets: 0,
1062-
buffers: ViewClusterBuffers::new(supported_binding_types),
1070+
buffers: ViewClusterBuffers::new(buffer_binding_type),
10631071
}
10641072
}
10651073

@@ -1191,6 +1199,7 @@ pub fn prepare_clusters(
11911199
mut commands: Commands,
11921200
render_device: Res<RenderDevice>,
11931201
render_queue: Res<RenderQueue>,
1202+
mesh_pipeline: Res<MeshPipeline>,
11941203
global_light_meta: Res<GlobalLightMeta>,
11951204
views: Query<
11961205
(
@@ -1202,11 +1211,13 @@ pub fn prepare_clusters(
12021211
>,
12031212
) {
12041213
let render_device = render_device.into_inner();
1205-
let supported_binding_types =
1206-
SupportedBindingTypes::from_device(render_device, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
1207-
let supports_storage_buffers = supported_binding_types.contains(SupportedBindingTypes::STORAGE);
1214+
let supports_storage_buffers = matches!(
1215+
mesh_pipeline.clustered_forward_buffer_binding_type,
1216+
BufferBindingType::Storage { .. }
1217+
);
12081218
for (entity, cluster_config, extracted_clusters) in views.iter() {
1209-
let mut view_clusters_bindings = ViewClusterBindings::new(supported_binding_types);
1219+
let mut view_clusters_bindings =
1220+
ViewClusterBindings::new(mesh_pipeline.clustered_forward_buffer_binding_type);
12101221
view_clusters_bindings.reserve_and_clear();
12111222

12121223
let mut indices_full = false;

crates/bevy_pbr/src/render/mesh.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -162,22 +162,18 @@ pub struct MeshPipeline {
162162
pub mesh_layout: BindGroupLayout,
163163
// This dummy white texture is to be used in place of optional StandardMaterial textures
164164
pub dummy_white_gpu_image: GpuImage,
165+
pub clustered_forward_buffer_binding_type: BufferBindingType,
165166
}
166167

167168
impl FromWorld for MeshPipeline {
168169
fn from_world(world: &mut World) -> Self {
169170
let render_device = world.resource::<RenderDevice>();
170-
let (cluster_buffer_binding_type, cluster_min_binding_size) =
171-
if SupportedBindingTypes::from_device(
172-
render_device,
173-
CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
174-
)
175-
.contains(SupportedBindingTypes::STORAGE)
176-
{
177-
(BufferBindingType::Storage { read_only: true }, None)
178-
} else {
179-
(BufferBindingType::Uniform, BufferSize::new(16384))
180-
};
171+
let clustered_forward_buffer_binding_type = render_device
172+
.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
173+
let cluster_min_binding_size = match clustered_forward_buffer_binding_type {
174+
BufferBindingType::Storage { .. } => None,
175+
BufferBindingType::Uniform => BufferSize::new(16384),
176+
};
181177
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
182178
entries: &[
183179
// View
@@ -249,7 +245,7 @@ impl FromWorld for MeshPipeline {
249245
binding: 6,
250246
visibility: ShaderStages::FRAGMENT,
251247
ty: BindingType::Buffer {
252-
ty: cluster_buffer_binding_type,
248+
ty: clustered_forward_buffer_binding_type,
253249
has_dynamic_offset: false,
254250
// NOTE (when no storage buffers): Static size for uniform buffers.
255251
// GpuPointLight has a padded size of 64 bytes, so 16384 / 64 = 256
@@ -263,7 +259,7 @@ impl FromWorld for MeshPipeline {
263259
binding: 7,
264260
visibility: ShaderStages::FRAGMENT,
265261
ty: BindingType::Buffer {
266-
ty: cluster_buffer_binding_type,
262+
ty: clustered_forward_buffer_binding_type,
267263
has_dynamic_offset: false,
268264
// NOTE (when no storage buffers): With 256 point lights max, indices
269265
// need 8 bits so use u8
@@ -276,7 +272,7 @@ impl FromWorld for MeshPipeline {
276272
binding: 8,
277273
visibility: ShaderStages::FRAGMENT,
278274
ty: BindingType::Buffer {
279-
ty: cluster_buffer_binding_type,
275+
ty: clustered_forward_buffer_binding_type,
280276
has_dynamic_offset: false,
281277
// NOTE (when no storage buffers): The offset needs to address 16384
282278
// indices, which needs 14 bits. The count can be at most all 256 lights
@@ -353,6 +349,7 @@ impl FromWorld for MeshPipeline {
353349
MeshPipeline {
354350
view_layout,
355351
mesh_layout,
352+
clustered_forward_buffer_binding_type,
356353
dummy_white_gpu_image,
357354
}
358355
}

crates/bevy_render/src/render_resource/storage_buffer.rs

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,10 @@
1-
use std::num::NonZeroU64;
2-
1+
use super::Buffer;
2+
use crate::renderer::{RenderDevice, RenderQueue};
33
use bevy_crevice::std430::{self, AsStd430, Std430};
44
use bevy_utils::tracing::warn;
5+
use std::num::NonZeroU64;
56
use wgpu::{BindingResource, BufferBinding, BufferDescriptor, BufferUsages};
67

7-
use crate::renderer::{RenderDevice, RenderQueue};
8-
9-
use super::Buffer;
10-
11-
bitflags::bitflags! {
12-
#[repr(transparent)]
13-
pub struct SupportedBindingTypes: u32 {
14-
const UNIFORM = (1 << 0);
15-
const STORAGE = (1 << 1);
16-
const NONE = 0;
17-
const UNINITIALIZED = 0xFFFF;
18-
}
19-
}
20-
21-
impl SupportedBindingTypes {
22-
pub fn from_device(
23-
render_device: &RenderDevice,
24-
required_binding_count_per_stage: u32,
25-
) -> SupportedBindingTypes {
26-
let mut supported_binding_types = SupportedBindingTypes::UNIFORM;
27-
if render_device.limits().max_storage_buffers_per_shader_stage
28-
>= required_binding_count_per_stage
29-
{
30-
supported_binding_types |= SupportedBindingTypes::STORAGE;
31-
}
32-
supported_binding_types
33-
}
34-
}
35-
368
/// A helper for a storage buffer binding with a body, or a variable-sized array, or both.
379
pub struct StorageBuffer<T: AsStd430, U: AsStd430 = ()> {
3810
body: U,

crates/bevy_render/src/renderer/render_device.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::render_resource::{
44
};
55
use futures_lite::future;
66
use std::sync::Arc;
7-
use wgpu::util::DeviceExt;
7+
use wgpu::{util::DeviceExt, BufferBindingType};
88

99
use super::RenderQueue;
1010

@@ -184,4 +184,15 @@ impl RenderDevice {
184184
let padded_bytes_per_row_padding = (align - row_bytes % align) % align;
185185
row_bytes + padded_bytes_per_row_padding
186186
}
187+
188+
pub fn get_supported_read_only_binding_type(
189+
&self,
190+
buffers_per_shader_stage: u32,
191+
) -> BufferBindingType {
192+
if self.limits().max_storage_buffers_per_shader_stage >= buffers_per_shader_stage {
193+
BufferBindingType::Storage { read_only: true }
194+
} else {
195+
BufferBindingType::Uniform
196+
}
197+
}
187198
}

0 commit comments

Comments
 (0)