wgpu_core/validation/
shader_io_deductions.rs1use core::fmt::{self, Debug, Display, Formatter};
2
3#[cfg(doc)]
4#[expect(unused_imports)]
5use crate::validation::StageError;
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11pub enum MaxVertexShaderOutputDeduction {
12 PointListPrimitiveTopology,
15}
16
17impl MaxVertexShaderOutputDeduction {
18 pub fn for_variables(self) -> u32 {
19 match self {
20 Self::PointListPrimitiveTopology => 1,
21 }
22 }
23
24 pub fn for_location(self) -> u32 {
25 match self {
26 Self::PointListPrimitiveTopology => 0,
27 }
28 }
29}
30
31#[derive(Clone, Copy, Debug, Eq, PartialEq)]
35pub enum MaxFragmentShaderInputDeduction {
36 InterStageBuiltIn(InterStageBuiltIn),
37}
38
39impl MaxFragmentShaderInputDeduction {
40 pub fn for_variables(self) -> u32 {
41 match self {
42 Self::InterStageBuiltIn(builtin) => match builtin {
43 InterStageBuiltIn::FrontFacing
44 | InterStageBuiltIn::SampleIndex
45 | InterStageBuiltIn::SampleMask
46 | InterStageBuiltIn::PrimitiveIndex
47 | InterStageBuiltIn::SubgroupInvocationId
48 | InterStageBuiltIn::SubgroupSize
49 | InterStageBuiltIn::ViewIndex
50 | InterStageBuiltIn::PointCoord => 1,
51 InterStageBuiltIn::Barycentric => 3,
52 InterStageBuiltIn::Position => 0,
53 },
54 }
55 }
56
57 pub fn from_inter_stage_builtin(builtin: naga::BuiltIn) -> Option<Self> {
58 use naga::BuiltIn;
59
60 Some(Self::InterStageBuiltIn(match builtin {
61 BuiltIn::Position { .. } => InterStageBuiltIn::Position,
62 BuiltIn::FrontFacing => InterStageBuiltIn::FrontFacing,
63 BuiltIn::SampleIndex => InterStageBuiltIn::SampleIndex,
64 BuiltIn::SampleMask => InterStageBuiltIn::SampleMask,
65 BuiltIn::PrimitiveIndex => InterStageBuiltIn::PrimitiveIndex,
66 BuiltIn::SubgroupSize => InterStageBuiltIn::SubgroupSize,
67 BuiltIn::SubgroupInvocationId => InterStageBuiltIn::SubgroupInvocationId,
68
69 BuiltIn::PointCoord => InterStageBuiltIn::PointCoord,
70 BuiltIn::Barycentric { .. } => InterStageBuiltIn::Barycentric,
71 BuiltIn::ViewIndex => InterStageBuiltIn::ViewIndex,
72
73 BuiltIn::BaseInstance
74 | BuiltIn::BaseVertex
75 | BuiltIn::ClipDistance
76 | BuiltIn::CullDistance
77 | BuiltIn::InstanceIndex
78 | BuiltIn::PointSize
79 | BuiltIn::VertexIndex
80 | BuiltIn::DrawID
81 | BuiltIn::FragDepth
82 | BuiltIn::GlobalInvocationId
83 | BuiltIn::LocalInvocationId
84 | BuiltIn::LocalInvocationIndex
85 | BuiltIn::WorkGroupId
86 | BuiltIn::WorkGroupSize
87 | BuiltIn::NumWorkGroups
88 | BuiltIn::NumSubgroups
89 | BuiltIn::SubgroupId
90 | BuiltIn::MeshTaskSize
91 | BuiltIn::CullPrimitive
92 | BuiltIn::PointIndex
93 | BuiltIn::LineIndices
94 | BuiltIn::TriangleIndices
95 | BuiltIn::VertexCount
96 | BuiltIn::Vertices
97 | BuiltIn::PrimitiveCount
98 | BuiltIn::Primitives => return None,
99 }))
100 }
101}
102
103#[derive(Clone, Copy, Debug, Eq, PartialEq)]
108pub enum InterStageBuiltIn {
109 Position,
111 FrontFacing,
112 SampleIndex,
113 SampleMask,
114 PrimitiveIndex,
115 SubgroupInvocationId,
116 SubgroupSize,
117
118 PointCoord,
120 Barycentric,
121 ViewIndex,
122}
123
124pub(in crate::validation) fn display_deductions_as_optional_list<T>(
125 deductions: &[T],
126 accessor: fn(&T) -> u32,
127) -> impl Display + '_
128where
129 T: Debug,
130{
131 struct DisplayFromFn<F>(F);
132
133 impl<F> Display for DisplayFromFn<F>
134 where
135 F: Fn(&mut Formatter<'_>) -> fmt::Result,
136 {
137 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
138 let Self(inner) = self;
139 inner(f)
140 }
141 }
142
143 DisplayFromFn(move |f: &mut Formatter<'_>| {
144 let relevant_deductions = deductions
145 .iter()
146 .map(|deduction| (deduction, accessor(deduction)))
147 .filter(|(_, effective_deduction)| *effective_deduction > 0);
148 if relevant_deductions.clone().next().is_some() {
149 writeln!(f, "; note that some deductions apply during validation:")?;
150 let mut wrote_something = false;
151 for deduction in deductions {
152 let deducted_amount = accessor(deduction);
153 if deducted_amount > 0 {
154 writeln!(f, "\n- {deduction:?}: {}", accessor(deduction))?;
155 wrote_something = true;
156 }
157 }
158 debug_assert!(
159 wrote_something,
160 "no substantial deductions found in error display"
161 );
162 }
163 Ok(())
164 })
165}