Skip to content

Commit 8c9a8a5

Browse files
cartsuperdump
authored andcommitted
Move storage buffer detection to RenderDevice
1 parent 1d3f878 commit 8c9a8a5

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

@@ -620,10 +619,20 @@ pub struct GlobalLightMeta {
620619
pub entity_to_index: HashMap<Entity, usize>,
621620
}
622621

622+
impl FromWorld for GlobalLightMeta {
623+
fn from_world(world: &mut World) -> Self {
624+
Self::new(
625+
world
626+
.resource::<RenderDevice>()
627+
.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT),
628+
)
629+
}
630+
}
631+
623632
impl GlobalLightMeta {
624-
pub fn new(supported_binding_types: SupportedBindingTypes) -> Self {
633+
pub fn new(buffer_binding_type: BufferBindingType) -> Self {
625634
Self {
626-
gpu_point_lights: GpuPointLights::new(supported_binding_types),
635+
gpu_point_lights: GpuPointLights::new(buffer_binding_type),
627636
entity_to_index: HashMap::default(),
628637
}
629638
}
@@ -1038,11 +1047,10 @@ enum ViewClusterBuffers {
10381047
}
10391048

10401049
impl ViewClusterBuffers {
1041-
fn new(supported_binding_types: SupportedBindingTypes) -> Self {
1042-
if supported_binding_types.contains(SupportedBindingTypes::STORAGE) {
1043-
Self::storage()
1044-
} else {
1045-
Self::uniform()
1050+
fn new(buffer_binding_type: BufferBindingType) -> Self {
1051+
match buffer_binding_type {
1052+
BufferBindingType::Storage { .. } => Self::storage(),
1053+
BufferBindingType::Uniform => Self::uniform(),
10461054
}
10471055
}
10481056

@@ -1073,11 +1081,11 @@ impl ViewClusterBindings {
10731081
const MAX_UNIFORM_ITEMS: usize = Self::MAX_OFFSETS / 4;
10741082
pub const MAX_INDICES: usize = 16384;
10751083

1076-
pub fn new(supported_binding_types: SupportedBindingTypes) -> Self {
1084+
pub fn new(buffer_binding_type: BufferBindingType) -> Self {
10771085
Self {
10781086
n_indices: 0,
10791087
n_offsets: 0,
1080-
buffers: ViewClusterBuffers::new(supported_binding_types),
1088+
buffers: ViewClusterBuffers::new(buffer_binding_type),
10811089
}
10821090
}
10831091

@@ -1209,6 +1217,7 @@ pub fn prepare_clusters(
12091217
mut commands: Commands,
12101218
render_device: Res<RenderDevice>,
12111219
render_queue: Res<RenderQueue>,
1220+
mesh_pipeline: Res<MeshPipeline>,
12121221
global_light_meta: Res<GlobalLightMeta>,
12131222
views: Query<
12141223
(
@@ -1220,11 +1229,13 @@ pub fn prepare_clusters(
12201229
>,
12211230
) {
12221231
let render_device = render_device.into_inner();
1223-
let supported_binding_types =
1224-
SupportedBindingTypes::from_device(render_device, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
1225-
let supports_storage_buffers = supported_binding_types.contains(SupportedBindingTypes::STORAGE);
1232+
let supports_storage_buffers = matches!(
1233+
mesh_pipeline.clustered_forward_buffer_binding_type,
1234+
BufferBindingType::Storage { .. }
1235+
);
12261236
for (entity, cluster_config, extracted_clusters) in views.iter() {
1227-
let mut view_clusters_bindings = ViewClusterBindings::new(supported_binding_types);
1237+
let mut view_clusters_bindings =
1238+
ViewClusterBindings::new(mesh_pipeline.clustered_forward_buffer_binding_type);
12281239
view_clusters_bindings.reserve_and_clear();
12291240

12301241
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
@@ -259,22 +259,18 @@ pub struct MeshPipeline {
259259
pub skinned_mesh_layout: BindGroupLayout,
260260
// This dummy white texture is to be used in place of optional StandardMaterial textures
261261
pub dummy_white_gpu_image: GpuImage,
262+
pub clustered_forward_buffer_binding_type: BufferBindingType,
262263
}
263264

264265
impl FromWorld for MeshPipeline {
265266
fn from_world(world: &mut World) -> Self {
266267
let render_device = world.resource::<RenderDevice>();
267-
let (cluster_buffer_binding_type, cluster_min_binding_size) =
268-
if SupportedBindingTypes::from_device(
269-
render_device,
270-
CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
271-
)
272-
.contains(SupportedBindingTypes::STORAGE)
273-
{
274-
(BufferBindingType::Storage { read_only: true }, None)
275-
} else {
276-
(BufferBindingType::Uniform, BufferSize::new(16384))
277-
};
268+
let clustered_forward_buffer_binding_type = render_device
269+
.get_supported_read_only_binding_type(CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT);
270+
let cluster_min_binding_size = match clustered_forward_buffer_binding_type {
271+
BufferBindingType::Storage { .. } => None,
272+
BufferBindingType::Uniform => BufferSize::new(16384),
273+
};
278274
let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
279275
entries: &[
280276
// View
@@ -346,7 +342,7 @@ impl FromWorld for MeshPipeline {
346342
binding: 6,
347343
visibility: ShaderStages::FRAGMENT,
348344
ty: BindingType::Buffer {
349-
ty: cluster_buffer_binding_type,
345+
ty: clustered_forward_buffer_binding_type,
350346
has_dynamic_offset: false,
351347
// NOTE (when no storage buffers): Static size for uniform buffers.
352348
// GpuPointLight has a padded size of 64 bytes, so 16384 / 64 = 256
@@ -360,7 +356,7 @@ impl FromWorld for MeshPipeline {
360356
binding: 7,
361357
visibility: ShaderStages::FRAGMENT,
362358
ty: BindingType::Buffer {
363-
ty: cluster_buffer_binding_type,
359+
ty: clustered_forward_buffer_binding_type,
364360
has_dynamic_offset: false,
365361
// NOTE (when no storage buffers): With 256 point lights max, indices
366362
// need 8 bits so use u8
@@ -373,7 +369,7 @@ impl FromWorld for MeshPipeline {
373369
binding: 8,
374370
visibility: ShaderStages::FRAGMENT,
375371
ty: BindingType::Buffer {
376-
ty: cluster_buffer_binding_type,
372+
ty: clustered_forward_buffer_binding_type,
377373
has_dynamic_offset: false,
378374
// NOTE (when no storage buffers): The offset needs to address 16384
379375
// indices, which needs 14 bits. The count can be at most all 256 lights
@@ -472,6 +468,7 @@ impl FromWorld for MeshPipeline {
472468
view_layout,
473469
mesh_layout,
474470
skinned_mesh_layout,
471+
clustered_forward_buffer_binding_type,
475472
dummy_white_gpu_image,
476473
}
477474
}

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)