script/dom/webgpu/
gpusupportedlimits.rs1use GPUSupportedLimits_Binding::GPUSupportedLimitsMethods;
6use dom_struct::dom_struct;
7use num_traits::bounds::UpperBounded;
8use wgpu_types::Limits;
9
10use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUSupportedLimits_Binding;
11use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
12use crate::dom::bindings::root::DomRoot;
13use crate::dom::globalscope::GlobalScope;
14use crate::script_runtime::CanGc;
15
16#[dom_struct]
17pub(crate) struct GPUSupportedLimits {
18 reflector_: Reflector,
19 #[ignore_malloc_size_of = "defined in wgpu-types"]
20 #[no_trace]
21 limits: Limits,
22}
23
24impl GPUSupportedLimits {
25 fn new_inherited(limits: Limits) -> Self {
26 Self {
27 reflector_: Reflector::new(),
28 limits,
29 }
30 }
31
32 pub(crate) fn new(global: &GlobalScope, limits: Limits, can_gc: CanGc) -> DomRoot<Self> {
33 reflect_dom_object(Box::new(Self::new_inherited(limits)), global, can_gc)
34 }
35}
36
37impl GPUSupportedLimits {
38 pub(crate) fn wgpu_limits(&self) -> &Limits {
39 &self.limits
40 }
41}
42
43impl GPUSupportedLimitsMethods<crate::DomTypeHolder> for GPUSupportedLimits {
44 fn MaxTextureDimension1D(&self) -> u32 {
46 self.limits.max_texture_dimension_1d
47 }
48
49 fn MaxTextureDimension2D(&self) -> u32 {
51 self.limits.max_texture_dimension_2d
52 }
53
54 fn MaxTextureDimension3D(&self) -> u32 {
56 self.limits.max_texture_dimension_3d
57 }
58
59 fn MaxTextureArrayLayers(&self) -> u32 {
61 self.limits.max_texture_array_layers
62 }
63
64 fn MaxBindGroups(&self) -> u32 {
66 self.limits.max_bind_groups
67 }
68
69 fn MaxBindingsPerBindGroup(&self) -> u32 {
71 self.limits.max_bindings_per_bind_group
72 }
73
74 fn MaxDynamicUniformBuffersPerPipelineLayout(&self) -> u32 {
76 self.limits.max_dynamic_uniform_buffers_per_pipeline_layout
77 }
78
79 fn MaxDynamicStorageBuffersPerPipelineLayout(&self) -> u32 {
81 self.limits.max_dynamic_storage_buffers_per_pipeline_layout
82 }
83
84 fn MaxSampledTexturesPerShaderStage(&self) -> u32 {
86 self.limits.max_sampled_textures_per_shader_stage
87 }
88
89 fn MaxSamplersPerShaderStage(&self) -> u32 {
91 self.limits.max_samplers_per_shader_stage
92 }
93
94 fn MaxStorageBuffersPerShaderStage(&self) -> u32 {
96 self.limits.max_storage_buffers_per_shader_stage
97 }
98
99 fn MaxStorageTexturesPerShaderStage(&self) -> u32 {
101 self.limits.max_storage_textures_per_shader_stage
102 }
103
104 fn MaxUniformBuffersPerShaderStage(&self) -> u32 {
106 self.limits.max_uniform_buffers_per_shader_stage
107 }
108
109 fn MaxUniformBufferBindingSize(&self) -> u64 {
111 self.limits.max_uniform_buffer_binding_size as u64
112 }
113
114 fn MaxStorageBufferBindingSize(&self) -> u64 {
116 self.limits.max_storage_buffer_binding_size as u64
117 }
118
119 fn MinUniformBufferOffsetAlignment(&self) -> u32 {
121 self.limits.min_uniform_buffer_offset_alignment
122 }
123
124 fn MinStorageBufferOffsetAlignment(&self) -> u32 {
126 self.limits.min_storage_buffer_offset_alignment
127 }
128
129 fn MaxVertexBuffers(&self) -> u32 {
131 self.limits.max_vertex_buffers
132 }
133
134 fn MaxBufferSize(&self) -> u64 {
136 self.limits.max_buffer_size
137 }
138
139 fn MaxVertexAttributes(&self) -> u32 {
141 self.limits.max_vertex_attributes
142 }
143
144 fn MaxVertexBufferArrayStride(&self) -> u32 {
146 self.limits.max_vertex_buffer_array_stride
147 }
148
149 fn MaxInterStageShaderComponents(&self) -> u32 {
151 self.limits.max_inter_stage_shader_components
152 }
153
154 fn MaxComputeWorkgroupStorageSize(&self) -> u32 {
156 self.limits.max_compute_workgroup_storage_size
157 }
158
159 fn MaxComputeInvocationsPerWorkgroup(&self) -> u32 {
161 self.limits.max_compute_invocations_per_workgroup
162 }
163
164 fn MaxComputeWorkgroupSizeX(&self) -> u32 {
166 self.limits.max_compute_workgroup_size_x
167 }
168
169 fn MaxComputeWorkgroupSizeY(&self) -> u32 {
171 self.limits.max_compute_workgroup_size_y
172 }
173
174 fn MaxComputeWorkgroupSizeZ(&self) -> u32 {
176 self.limits.max_compute_workgroup_size_z
177 }
178
179 fn MaxComputeWorkgroupsPerDimension(&self) -> u32 {
181 self.limits.max_compute_workgroups_per_dimension
182 }
183
184 fn MaxBindGroupsPlusVertexBuffers(&self) -> u32 {
186 self.limits.max_bind_groups + self.limits.max_vertex_buffers
188 }
189
190 fn MaxInterStageShaderVariables(&self) -> u32 {
192 16
194 }
195
196 fn MaxColorAttachments(&self) -> u32 {
198 self.limits.max_color_attachments
199 }
200
201 fn MaxColorAttachmentBytesPerSample(&self) -> u32 {
203 self.limits.max_color_attachment_bytes_per_sample
204 }
205}
206
207pub(crate) fn set_limit(limits: &mut Limits, limit: &str, value: u64) -> bool {
209 fn set_maximum<T>(limit: &mut T, value: u64) -> bool
213 where
214 T: Ord + Copy + TryFrom<u64> + UpperBounded,
215 {
216 if let Ok(value) = T::try_from(value) {
217 *limit = value.max(*limit);
218 true
219 } else {
220 false
221 }
222 }
223
224 fn set_alignment<T>(limit: &mut T, value: u64) -> bool
228 where
229 T: Ord + Copy + TryFrom<u64> + UpperBounded,
230 {
231 if !value.is_power_of_two() {
232 return false;
233 }
234 if let Ok(value) = T::try_from(value) {
235 *limit = value.min(*limit);
236 true
237 } else {
238 false
239 }
240 }
241
242 match limit {
243 "maxTextureDimension1D" => set_maximum(&mut limits.max_texture_dimension_1d, value),
244 "maxTextureDimension2D" => set_maximum(&mut limits.max_texture_dimension_2d, value),
245 "maxTextureDimension3D" => set_maximum(&mut limits.max_texture_dimension_3d, value),
246 "maxTextureArrayLayers" => set_maximum(&mut limits.max_texture_array_layers, value),
247 "maxBindGroups" => set_maximum(&mut limits.max_bind_groups, value),
248 "maxBindGroupsPlusVertexBuffers" => {
249 let mut v: u32 = 0;
252 set_maximum(&mut v, value)
253 },
254 "maxBindingsPerBindGroup" => set_maximum(&mut limits.max_bindings_per_bind_group, value),
255 "maxDynamicUniformBuffersPerPipelineLayout" => set_maximum(
256 &mut limits.max_dynamic_uniform_buffers_per_pipeline_layout,
257 value,
258 ),
259 "maxDynamicStorageBuffersPerPipelineLayout" => set_maximum(
260 &mut limits.max_dynamic_storage_buffers_per_pipeline_layout,
261 value,
262 ),
263 "maxSampledTexturesPerShaderStage" => {
264 set_maximum(&mut limits.max_sampled_textures_per_shader_stage, value)
265 },
266 "maxSamplersPerShaderStage" => {
267 set_maximum(&mut limits.max_samplers_per_shader_stage, value)
268 },
269 "maxStorageBuffersPerShaderStage" => {
270 set_maximum(&mut limits.max_storage_buffers_per_shader_stage, value)
271 },
272 "maxStorageTexturesPerShaderStage" => {
273 set_maximum(&mut limits.max_storage_textures_per_shader_stage, value)
274 },
275 "maxUniformBuffersPerShaderStage" => {
276 set_maximum(&mut limits.max_uniform_buffers_per_shader_stage, value)
277 },
278 "maxUniformBufferBindingSize" => {
279 set_maximum(&mut limits.max_uniform_buffer_binding_size, value)
280 },
281 "maxStorageBufferBindingSize" => {
282 set_maximum(&mut limits.max_storage_buffer_binding_size, value)
283 },
284 "minUniformBufferOffsetAlignment" => {
285 set_alignment(&mut limits.min_uniform_buffer_offset_alignment, value)
286 },
287 "minStorageBufferOffsetAlignment" => {
288 set_alignment(&mut limits.min_storage_buffer_offset_alignment, value)
289 },
290 "maxVertexBuffers" => set_maximum(&mut limits.max_vertex_buffers, value),
291 "maxBufferSize" => set_maximum(&mut limits.max_buffer_size, value),
292 "maxVertexAttributes" => set_maximum(&mut limits.max_vertex_attributes, value),
293 "maxVertexBufferArrayStride" => {
294 set_maximum(&mut limits.max_vertex_buffer_array_stride, value)
295 },
296 "maxInterStageShaderComponents" => {
297 set_maximum(&mut limits.max_inter_stage_shader_components, value)
298 },
299 "maxInterStageShaderVariables" => {
300 let mut v: u32 = 0;
303 set_maximum(&mut v, value)
304 },
305 "maxColorAttachments" => set_maximum(&mut limits.max_color_attachments, value),
306 "maxColorAttachmentBytesPerSample" => {
307 set_maximum(&mut limits.max_color_attachment_bytes_per_sample, value)
308 },
309 "maxComputeWorkgroupStorageSize" => {
310 set_maximum(&mut limits.max_compute_workgroup_storage_size, value)
311 },
312 "maxComputeInvocationsPerWorkgroup" => {
313 set_maximum(&mut limits.max_compute_invocations_per_workgroup, value)
314 },
315 "maxComputeWorkgroupSizeX" => set_maximum(&mut limits.max_compute_workgroup_size_x, value),
316 "maxComputeWorkgroupSizeY" => set_maximum(&mut limits.max_compute_workgroup_size_y, value),
317 "maxComputeWorkgroupSizeZ" => set_maximum(&mut limits.max_compute_workgroup_size_z, value),
318 "maxComputeWorkgroupsPerDimension" => {
319 set_maximum(&mut limits.max_compute_workgroups_per_dimension, value)
320 },
321 _ => false,
322 }
323}