Skip to content

Commit f92d516

Browse files
authored
Dispatch and uniform fixes.
1 parent 2767eae commit f92d516

5 files changed

Lines changed: 58 additions & 20 deletions

File tree

‎crates/processing_core/src/error.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ pub enum ProcessingError {
5858
PipelineCompileError(String),
5959
#[error("Pipeline not ready after {0} frames")]
6060
PipelineNotReady(u32),
61+
#[error("`{0}` isn't on the GPU yet")]
62+
ResourceNotReady(String),
6163
#[error("Particles not found")]
6264
ParticlesNotFound,
6365
#[error("Grid not found")]

‎crates/processing_render/src/compute.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,18 @@ pub fn dispatch(
359359
.clone();
360360

361361
let reflection = shader.reflection();
362+
// a missing GPU resource drops its binding, and wgpu panics on an incomplete bind group
363+
for param in reflection.parameters() {
364+
let Some(name) = param.name() else { continue };
365+
let ready = match (shader.buffer_handle(name), shader.image_handle(name)) {
366+
(Some(handle), _) => gpu_buffers.get(handle).is_some(),
367+
(_, Some(handle)) => gpu_images.get(handle).is_some(),
368+
_ => true,
369+
};
370+
if !ready {
371+
return Err(ProcessingError::ResourceNotReady(name.to_string()));
372+
}
373+
}
362374

363375
let mut bind_groups = Vec::new();
364376
for (group, desc) in &layout_descriptors {

‎crates/processing_render/src/lib.rs‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2553,7 +2553,10 @@ pub(crate) fn compute_dispatch_no_update(
25532553
z: u32,
25542554
) -> error::Result<()> {
25552555
app_mut(|app| match dispatch_inner(app, entity, x, y, z) {
2556-
Err(error::ProcessingError::PipelineNotReady(_)) => {
2556+
Err(
2557+
error::ProcessingError::PipelineNotReady(_)
2558+
| error::ProcessingError::ResourceNotReady(_),
2559+
) => {
25572560
app.update();
25582561
dispatch_inner(app, entity, x, y, z)
25592562
}

‎crates/processing_render/src/material/custom.rs‎

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,27 @@ pub(crate) fn apply_reflect_field(
322322
return Ok(());
323323
}
324324

325-
let param_name = find_param_containing_field(shader, name);
326-
if let Some(param_name) = param_name
327-
&& let Some(param) = shader.field_mut(&param_name)
325+
// `struct.field` picks a struct explicitly
326+
let (param_name, field_name) = match name.split_once('.') {
327+
Some((param, field)) => (param.to_string(), field),
328+
None => {
329+
let params = params_containing_field(shader, name);
330+
if params.len() > 1 {
331+
return Err(ProcessingError::InvalidArgument(format!(
332+
"`{name}` is a field of {}; name one, e.g. `{}.{name}`",
333+
params.join(" and "),
334+
params[0],
335+
)));
336+
}
337+
let Some(param) = params.into_iter().next() else {
338+
return Err(ProcessingError::UnknownShaderProperty(name.to_string()));
339+
};
340+
(param, name)
341+
}
342+
};
343+
if let Some(param) = shader.field_mut(&param_name)
328344
&& let ReflectMut::Struct(s) = param.reflect_mut()
329-
&& let Some(field) = s.field_mut(name)
345+
&& let Some(field) = s.field_mut(field_name)
330346
{
331347
apply_field_coerced(field, value);
332348
return Ok(());
@@ -509,15 +525,20 @@ pub(crate) fn find_param_containing_field(
509525
shader: &DynamicShader,
510526
field_name: &str,
511527
) -> Option<String> {
512-
for i in 0..shader.field_len() {
513-
if let Some(field) = shader.field_at(i)
514-
&& let ReflectRef::Struct(s) = field.reflect_ref()
515-
&& s.field(field_name).is_some()
516-
{
517-
return shader.name_at(i).map(|s: &str| s.to_string());
518-
}
519-
}
520-
None
528+
params_containing_field(shader, field_name)
529+
.into_iter()
530+
.next()
531+
}
532+
533+
fn params_containing_field(shader: &DynamicShader, field_name: &str) -> Vec<String> {
534+
(0..shader.field_len())
535+
.filter(|&i| {
536+
shader.field_at(i).is_some_and(|field| {
537+
matches!(field.reflect_ref(), ReflectRef::Struct(s) if s.field(field_name).is_some())
538+
})
539+
})
540+
.filter_map(|i| shader.name_at(i).map(str::to_string))
541+
.collect()
521542
}
522543

523544
pub struct CustomMaterialPlugin;

‎crates/processing_render/src/particles/algebra.rs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bevy::prelude::Entity;
55
use processing_core::error::{ProcessingError, Result};
66

77
use crate::shader_value::ShaderValue;
8-
use crate::{buffer_size, compute_dispatch, compute_set, shader_create_with_features};
8+
use crate::{buffer_size, compute_dispatch_no_update, compute_set, shader_create_with_features};
99

1010
const WG: u32 = 64;
1111

@@ -96,7 +96,7 @@ static MAP: Mutex<Option<(Entity, Entity)>> = Mutex::new(None);
9696

9797
fn dispatch_particles(compute: Entity, floats: u64, components: u32) -> Result<()> {
9898
let n = (floats / components as u64) as u32;
99-
compute_dispatch(compute, n.div_ceil(WG), 1, 1)
99+
compute_dispatch_no_update(compute, n.div_ceil(WG), 1, 1)
100100
}
101101

102102
fn check_components(verb: &str, components: u32) -> Result<()> {
@@ -373,7 +373,7 @@ pub fn lookup(
373373
compute_set(c, "tex", ShaderValue::Texture(tex))?;
374374
compute_set(c, "samp", ShaderValue::Texture(tex))?;
375375
let n = (buffer_size(dst)? / 16) as u32;
376-
compute_dispatch(c, n.div_ceil(WG), 1, 1)
376+
compute_dispatch_no_update(c, n.div_ceil(WG), 1, 1)
377377
}
378378

379379
pub const REDUCE_LENGTH: u32 = 0;
@@ -430,7 +430,7 @@ pub fn reduce_components(dst: Entity, src: Entity, components: u32, op: u32) ->
430430
compute_set(c, "components", ShaderValue::UInt(components))?;
431431
compute_set(c, "op", ShaderValue::UInt(op))?;
432432
let n = (buffer_size(dst)? / 4) as u32;
433-
compute_dispatch(c, n.div_ceil(WG), 1, 1)
433+
compute_dispatch_no_update(c, n.div_ceil(WG), 1, 1)
434434
}
435435

436436
const EXTRACT_SRC: &str = r#"
@@ -465,7 +465,7 @@ pub fn extract(dst: Entity, src: Entity, components: u32, index: u32) -> Result<
465465
compute_set(c, "components", ShaderValue::UInt(components))?;
466466
compute_set(c, "index", ShaderValue::UInt(index))?;
467467
let n = (buffer_size(dst)? / 4) as u32;
468-
compute_dispatch(c, n.div_ceil(WG), 1, 1)
468+
compute_dispatch_no_update(c, n.div_ceil(WG), 1, 1)
469469
}
470470

471471
const PACK_SRC: &str = r#"
@@ -534,7 +534,7 @@ pub fn pack(dst: Entity, sources: &[Entity]) -> Result<()> {
534534
compute_set(c, "dst", ShaderValue::Buffer(dst))?;
535535
compute_set(c, "components", ShaderValue::UInt(components))?;
536536
let n = (buffer_size(sources[0])? / 4) as u32;
537-
compute_dispatch(c, n.div_ceil(WG), 1, 1)
537+
compute_dispatch_no_update(c, n.div_ceil(WG), 1, 1)
538538
}
539539

540540
pub const GEN_UNIFORM: u32 = 0;

0 commit comments

Comments
 (0)