Skip to content

Commit 2931f2a

Browse files
fix(core): cover clip_distances bindings in max_inter_stage_shader_variables limit check
1 parent afbf47f commit 2931f2a

2 files changed

Lines changed: 55 additions & 4 deletions

File tree

wgpu-core/src/validation.rs

Lines changed: 40 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,
@@ -202,7 +202,7 @@ impl BuiltIn {
202202
Self::ViewIndex => naga::BuiltIn::ViewIndex,
203203
Self::BaseInstance => naga::BuiltIn::BaseInstance,
204204
Self::BaseVertex => naga::BuiltIn::BaseVertex,
205-
Self::ClipDistance => naga::BuiltIn::ClipDistance,
205+
Self::ClipDistance { .. } => naga::BuiltIn::ClipDistance,
206206
Self::CullDistance => naga::BuiltIn::CullDistance,
207207
Self::InstanceIndex => naga::BuiltIn::InstanceIndex,
208208
Self::PointSize => naga::BuiltIn::PointSize,
@@ -1127,6 +1127,28 @@ impl Interface {
11271127
}
11281128
return;
11291129
}
1130+
naga::TypeInner::Array { base, size, stride }
1131+
if matches!(
1132+
binding,
1133+
Some(naga::Binding::BuiltIn(naga::BuiltIn::ClipDistance)),
1134+
) =>
1135+
{
1136+
// NOTE: We should already have validated these in `naga`.
1137+
debug_assert_eq!(
1138+
&arena[base].inner,
1139+
&naga::TypeInner::Scalar(naga::Scalar::F32)
1140+
);
1141+
debug_assert_eq!(stride, 4);
1142+
1143+
let naga::ArraySize::Constant(array_size) = size else {
1144+
// TODO: Should we accept override expressions?
1145+
unreachable!("non-constant array size for `clip_distances`")
1146+
};
1147+
let array_size = array_size.get();
1148+
1149+
list.push(Varying::BuiltIn(BuiltIn::ClipDistance { array_size }));
1150+
return;
1151+
}
11301152
ref other => {
11311153
//Note: technically this should be at least `log::error`, but
11321154
// the reality is - every shader coming from `glslc` outputs an array
@@ -1159,7 +1181,7 @@ impl Interface {
11591181
naga::BuiltIn::ViewIndex => BuiltIn::ViewIndex,
11601182
naga::BuiltIn::BaseInstance => BuiltIn::BaseInstance,
11611183
naga::BuiltIn::BaseVertex => BuiltIn::BaseVertex,
1162-
naga::BuiltIn::ClipDistance => BuiltIn::ClipDistance,
1184+
naga::BuiltIn::ClipDistance => unreachable!(),
11631185
naga::BuiltIn::CullDistance => BuiltIn::CullDistance,
11641186
naga::BuiltIn::InstanceIndex => BuiltIn::InstanceIndex,
11651187
naga::BuiltIn::PointSize => BuiltIn::PointSize,
@@ -1619,7 +1641,21 @@ impl Interface {
16191641
None
16201642
};
16211643

1622-
let deductions = point_list_deduction.into_iter();
1644+
let clip_distance_deductions = entry_point.outputs.iter().filter_map(|output| {
1645+
if let &Varying::BuiltIn(BuiltIn::ClipDistance { array_size }) = output {
1646+
Some(MaxVertexShaderOutputDeduction::ClipDistance { array_size })
1647+
} else {
1648+
None
1649+
}
1650+
});
1651+
debug_assert!(
1652+
clip_distance_deductions.clone().count() <= 1,
1653+
"multiple `clip_distance` outputs found"
1654+
);
1655+
1656+
let deductions = point_list_deduction
1657+
.into_iter()
1658+
.chain(clip_distance_deductions);
16231659

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

wgpu-core/src/validation/shader_io_deductions.rs

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

1726
impl MaxVertexShaderOutputDeduction {
1827
pub fn for_variables(self) -> u32 {
1928
match self {
2029
Self::PointListPrimitiveTopology => 1,
30+
Self::ClipDistance { array_size } => {
31+
Self::variables_from_clip_distance_slot(array_size)
32+
}
2133
}
2234
}
2335

2436
pub fn for_location(self) -> u32 {
2537
match self {
2638
Self::PointListPrimitiveTopology => 0,
39+
Self::ClipDistance { array_size } => {
40+
Self::variables_from_clip_distance_slot(array_size)
41+
}
2742
}
2843
}
2944
}

0 commit comments

Comments
 (0)