Skip to content

Commit 02673d3

Browse files
fix(core): cover clip_distances bindings in max_inter_stage_shader_variables limit check
1 parent ad79934 commit 02673d3

2 files changed

Lines changed: 59 additions & 4 deletions

File tree

wgpu-core/src/validation.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ enum BuiltIn {
161161
ViewIndex,
162162
BaseInstance,
163163
BaseVertex,
164-
ClipDistance,
164+
ClipDistance { array_size: u32 },
165165
CullDistance,
166166
InstanceIndex,
167167
PointSize,
@@ -215,7 +215,7 @@ impl BuiltIn {
215215
Self::ViewIndex => naga::BuiltIn::ViewIndex,
216216
Self::BaseInstance => naga::BuiltIn::BaseInstance,
217217
Self::BaseVertex => naga::BuiltIn::BaseVertex,
218-
Self::ClipDistance => naga::BuiltIn::ClipDistance,
218+
Self::ClipDistance { .. } => naga::BuiltIn::ClipDistance,
219219
Self::CullDistance => naga::BuiltIn::CullDistance,
220220
Self::InstanceIndex => naga::BuiltIn::InstanceIndex,
221221
Self::PointSize => naga::BuiltIn::PointSize,
@@ -1185,6 +1185,33 @@ impl Interface {
11851185
}
11861186
return;
11871187
}
1188+
naga::TypeInner::Array { base, size, stride }
1189+
if matches!(
1190+
binding,
1191+
Some(naga::Binding::BuiltIn(naga::BuiltIn::ClipDistance)),
1192+
) =>
1193+
{
1194+
// NOTE: We should already have validated these in `naga`.
1195+
debug_assert_eq!(
1196+
&arena[base].inner,
1197+
&naga::TypeInner::Scalar(naga::Scalar::F32)
1198+
);
1199+
debug_assert_eq!(stride, 4);
1200+
1201+
let naga::ArraySize::Constant(array_size) = size else {
1202+
// NOTE: Based on the
1203+
// [spec](https://gpuweb.github.io/gpuweb/wgsl/#fixed-footprint-types):
1204+
//
1205+
// > The only valid use of a fixed-size array with an element count that is an
1206+
// > override-expression that is not a const-expression is as a memory view in
1207+
// > the workgroup address space.
1208+
unreachable!("non-constant array size for `clip_distances`")
1209+
};
1210+
let array_size = array_size.get();
1211+
1212+
list.push(Varying::BuiltIn(BuiltIn::ClipDistance { array_size }));
1213+
return;
1214+
}
11881215
ref other => {
11891216
//Note: technically this should be at least `log::error`, but
11901217
// the reality is - every shader coming from `glslc` outputs an array
@@ -1217,7 +1244,7 @@ impl Interface {
12171244
naga::BuiltIn::ViewIndex => BuiltIn::ViewIndex,
12181245
naga::BuiltIn::BaseInstance => BuiltIn::BaseInstance,
12191246
naga::BuiltIn::BaseVertex => BuiltIn::BaseVertex,
1220-
naga::BuiltIn::ClipDistance => BuiltIn::ClipDistance,
1247+
naga::BuiltIn::ClipDistance => unreachable!(),
12211248
naga::BuiltIn::CullDistance => BuiltIn::CullDistance,
12221249
naga::BuiltIn::InstanceIndex => BuiltIn::InstanceIndex,
12231250
naga::BuiltIn::PointSize => BuiltIn::PointSize,
@@ -1696,7 +1723,21 @@ impl Interface {
16961723
None
16971724
};
16981725

1699-
let deductions = point_list_deduction.into_iter();
1726+
let clip_distance_deductions = entry_point.outputs.iter().filter_map(|output| {
1727+
if let &Varying::BuiltIn(BuiltIn::ClipDistance { array_size }) = output {
1728+
Some(MaxVertexShaderOutputDeduction::ClipDistance { array_size })
1729+
} else {
1730+
None
1731+
}
1732+
});
1733+
debug_assert!(
1734+
clip_distance_deductions.clone().count() <= 1,
1735+
"multiple `clip_distance` outputs found"
1736+
);
1737+
1738+
let deductions = point_list_deduction
1739+
.into_iter()
1740+
.chain(clip_distance_deductions);
17001741

17011742
for deduction in deductions.clone() {
17021743
// NOTE: Deductions, in the current version of the spec. we implement, do not

wgpu-core/src/validation/shader_io_deductions.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,32 @@ pub enum MaxVertexShaderOutputDeduction {
1212
/// When a pipeline's [`crate::pipeline::RenderPipelineDescriptor::primitive`] is set to
1313
/// [`wgt::PrimitiveTopology::PointList`].
1414
PointListPrimitiveTopology,
15+
/// When a clip distances array primitive is used in an output.
16+
ClipDistance { array_size: u32 },
17+
}
18+
19+
impl MaxVertexShaderOutputDeduction {
20+
fn variables_from_clip_distance_slot(num_slots: u32) -> u32 {
21+
num_slots.div_ceil(4)
22+
}
1523
}
1624

1725
impl MaxVertexShaderOutputDeduction {
1826
pub fn for_variables(self) -> u32 {
1927
match self {
2028
Self::PointListPrimitiveTopology => 1,
29+
Self::ClipDistance { array_size } => {
30+
Self::variables_from_clip_distance_slot(array_size)
31+
}
2132
}
2233
}
2334

2435
pub fn for_location(self) -> u32 {
2536
match self {
2637
Self::PointListPrimitiveTopology => 0,
38+
Self::ClipDistance { array_size } => {
39+
Self::variables_from_clip_distance_slot(array_size)
40+
}
2741
}
2842
}
2943
}

0 commit comments

Comments
 (0)