1use GPUSupportedLimits_Binding::GPUSupportedLimitsMethods;
6use dom_struct::dom_struct;
7use num_traits::bounds::UpperBounded;
8use script_bindings::reflector::{Reflector, reflect_dom_object};
9use wgpu_types::Limits;
10
11use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUSupportedLimits_Binding;
12use crate::dom::bindings::root::DomRoot;
13use crate::dom::globalscope::GlobalScope;
14use crate::script_runtime::CanGc;
15
16#[dom_struct]
18pub(crate) struct GPUSupportedLimits {
19 reflector_: Reflector,
20 #[ignore_malloc_size_of = "defined in wgpu-types"]
21 #[no_trace]
22 limits: Limits,
23}
24
25impl GPUSupportedLimits {
26 fn new_inherited(limits: Limits) -> Self {
27 Self {
28 reflector_: Reflector::new(),
29 limits,
30 }
31 }
32
33 pub(crate) fn new(global: &GlobalScope, limits: Limits, can_gc: CanGc) -> DomRoot<Self> {
34 reflect_dom_object(Box::new(Self::new_inherited(limits)), global, can_gc)
35 }
36}
37
38impl GPUSupportedLimitsMethods<crate::DomTypeHolder> for GPUSupportedLimits {
40 fn MaxTextureDimension1D(&self) -> u32 {
42 self.limits.max_texture_dimension_1d
43 }
44
45 fn MaxTextureDimension2D(&self) -> u32 {
47 self.limits.max_texture_dimension_2d
48 }
49
50 fn MaxTextureDimension3D(&self) -> u32 {
52 self.limits.max_texture_dimension_3d
53 }
54
55 fn MaxTextureArrayLayers(&self) -> u32 {
57 self.limits.max_texture_array_layers
58 }
59
60 fn MaxBindGroups(&self) -> u32 {
62 self.limits.max_bind_groups
63 }
64
65 fn MaxBindGroupsPlusVertexBuffers(&self) -> u32 {
67 self.limits.max_bind_groups + self.limits.max_vertex_buffers
69 }
70
71 fn MaxBindingsPerBindGroup(&self) -> u32 {
80 self.limits.max_bindings_per_bind_group
81 }
82
83 fn MaxDynamicUniformBuffersPerPipelineLayout(&self) -> u32 {
85 self.limits.max_dynamic_uniform_buffers_per_pipeline_layout
86 }
87
88 fn MaxDynamicStorageBuffersPerPipelineLayout(&self) -> u32 {
90 self.limits.max_dynamic_storage_buffers_per_pipeline_layout
91 }
92
93 fn MaxSampledTexturesPerShaderStage(&self) -> u32 {
95 self.limits.max_sampled_textures_per_shader_stage
96 }
97
98 fn MaxSamplersPerShaderStage(&self) -> u32 {
100 self.limits.max_samplers_per_shader_stage
101 }
102
103 fn MaxStorageBuffersPerShaderStage(&self) -> u32 {
105 self.limits.max_storage_buffers_per_shader_stage
106 }
107
108 fn MaxStorageBuffersInVertexStage(&self) -> u32 {
110 self.limits.max_storage_buffers_per_shader_stage
112 }
113
114 fn MaxStorageBuffersInFragmentStage(&self) -> u32 {
116 self.limits.max_storage_buffers_per_shader_stage
118 }
119
120 fn MaxStorageTexturesPerShaderStage(&self) -> u32 {
122 self.limits.max_storage_textures_per_shader_stage
123 }
124
125 fn MaxStorageTexturesInVertexStage(&self) -> u32 {
127 self.limits.max_storage_textures_per_shader_stage
129 }
130
131 fn MaxStorageTexturesInFragmentStage(&self) -> u32 {
133 self.limits.max_storage_textures_per_shader_stage
135 }
136
137 fn MaxUniformBuffersPerShaderStage(&self) -> u32 {
139 self.limits.max_uniform_buffers_per_shader_stage
140 }
141
142 fn MaxUniformBufferBindingSize(&self) -> u64 {
144 self.limits.max_uniform_buffer_binding_size
145 }
146
147 fn MaxStorageBufferBindingSize(&self) -> u64 {
149 self.limits.max_storage_buffer_binding_size
150 }
151
152 fn MinUniformBufferOffsetAlignment(&self) -> u32 {
154 self.limits.min_uniform_buffer_offset_alignment
155 }
156
157 fn MinStorageBufferOffsetAlignment(&self) -> u32 {
159 self.limits.min_storage_buffer_offset_alignment
160 }
161
162 fn MaxVertexBuffers(&self) -> u32 {
164 self.limits.max_vertex_buffers
165 }
166
167 fn MaxBufferSize(&self) -> u64 {
169 self.limits.max_buffer_size
170 }
171
172 fn MaxVertexAttributes(&self) -> u32 {
174 self.limits.max_vertex_attributes
175 }
176
177 fn MaxVertexBufferArrayStride(&self) -> u32 {
179 self.limits.max_vertex_buffer_array_stride
180 }
181
182 fn MaxInterStageShaderVariables(&self) -> u32 {
184 self.limits.max_inter_stage_shader_variables
185 }
186
187 fn MaxColorAttachments(&self) -> u32 {
189 self.limits.max_color_attachments
190 }
191
192 fn MaxColorAttachmentBytesPerSample(&self) -> u32 {
194 self.limits.max_color_attachment_bytes_per_sample
195 }
196
197 fn MaxComputeWorkgroupStorageSize(&self) -> u32 {
199 self.limits.max_compute_workgroup_storage_size
200 }
201
202 fn MaxComputeInvocationsPerWorkgroup(&self) -> u32 {
204 self.limits.max_compute_invocations_per_workgroup
205 }
206
207 fn MaxComputeWorkgroupSizeX(&self) -> u32 {
209 self.limits.max_compute_workgroup_size_x
210 }
211
212 fn MaxComputeWorkgroupSizeY(&self) -> u32 {
214 self.limits.max_compute_workgroup_size_y
215 }
216
217 fn MaxComputeWorkgroupSizeZ(&self) -> u32 {
219 self.limits.max_compute_workgroup_size_z
220 }
221
222 fn MaxComputeWorkgroupsPerDimension(&self) -> u32 {
224 self.limits.max_compute_workgroups_per_dimension
225 }
226}
227
228pub(crate) fn set_limit(limits: &mut Limits, limit: &str, value: u64) -> bool {
230 fn set_maximum<T>(limit: &mut T, value: u64) -> bool
234 where
235 T: Ord + Copy + TryFrom<u64> + UpperBounded,
236 {
237 if let Ok(value) = T::try_from(value) {
238 *limit = value.max(*limit);
239 true
240 } else {
241 false
242 }
243 }
244
245 fn set_alignment<T>(limit: &mut T, value: u64) -> bool
249 where
250 T: Ord + Copy + TryFrom<u64> + UpperBounded,
251 {
252 if !value.is_power_of_two() {
253 return false;
254 }
255 if let Ok(value) = T::try_from(value) {
256 *limit = value.min(*limit);
257 true
258 } else {
259 false
260 }
261 }
262
263 match limit {
265 "maxTextureDimension1D" => set_maximum(&mut limits.max_texture_dimension_1d, value),
266 "maxTextureDimension2D" => set_maximum(&mut limits.max_texture_dimension_2d, value),
267 "maxTextureDimension3D" => set_maximum(&mut limits.max_texture_dimension_3d, value),
268 "maxTextureArrayLayers" => set_maximum(&mut limits.max_texture_array_layers, value),
269 "maxBindGroups" => set_maximum(&mut limits.max_bind_groups, value),
270 "maxBindGroupsPlusVertexBuffers" => {
271 let mut v: u32 = 0;
275 set_maximum(&mut v, value)
276 },
277 "maxImmediateSize" => set_maximum(&mut limits.max_immediate_size, value),
278 "maxBindingsPerBindGroup" => set_maximum(&mut limits.max_bindings_per_bind_group, value),
279 "maxDynamicUniformBuffersPerPipelineLayout" => set_maximum(
280 &mut limits.max_dynamic_uniform_buffers_per_pipeline_layout,
281 value,
282 ),
283 "maxDynamicStorageBuffersPerPipelineLayout" => set_maximum(
284 &mut limits.max_dynamic_storage_buffers_per_pipeline_layout,
285 value,
286 ),
287 "maxSampledTexturesPerShaderStage" => {
288 set_maximum(&mut limits.max_sampled_textures_per_shader_stage, value)
289 },
290 "maxSamplersPerShaderStage" => {
291 set_maximum(&mut limits.max_samplers_per_shader_stage, value)
292 },
293 "maxStorageBuffersPerShaderStage" => {
294 set_maximum(&mut limits.max_storage_buffers_per_shader_stage, value)
295 },
296 "maxStorageBuffersInVertexStage" => {
297 let mut v: u32 = 0;
301 set_maximum(&mut v, value)
302 },
303 "maxStorageBuffersInFragmentStage" => {
304 let mut v: u32 = 0;
308 set_maximum(&mut v, value)
309 },
310 "maxStorageTexturesPerShaderStage" => {
311 set_maximum(&mut limits.max_storage_textures_per_shader_stage, value)
312 },
313 "maxStorageTexturesInVertexStage" => {
314 let mut v: u32 = 0;
318 set_maximum(&mut v, value)
319 },
320 "maxStorageTexturesInFragmentStage" => {
321 let mut v: u32 = 0;
325 set_maximum(&mut v, value)
326 },
327 "maxUniformBuffersPerShaderStage" => {
328 set_maximum(&mut limits.max_uniform_buffers_per_shader_stage, value)
329 },
330 "maxUniformBufferBindingSize" => {
331 set_maximum(&mut limits.max_uniform_buffer_binding_size, value)
332 },
333 "maxStorageBufferBindingSize" => {
334 set_maximum(&mut limits.max_storage_buffer_binding_size, value)
335 },
336 "minUniformBufferOffsetAlignment" => {
337 set_alignment(&mut limits.min_uniform_buffer_offset_alignment, value)
338 },
339 "minStorageBufferOffsetAlignment" => {
340 set_alignment(&mut limits.min_storage_buffer_offset_alignment, value)
341 },
342 "maxVertexBuffers" => set_maximum(&mut limits.max_vertex_buffers, value),
343 "maxBufferSize" => set_maximum(&mut limits.max_buffer_size, value),
344 "maxVertexAttributes" => set_maximum(&mut limits.max_vertex_attributes, value),
345 "maxVertexBufferArrayStride" => {
346 set_maximum(&mut limits.max_vertex_buffer_array_stride, value)
347 },
348 "maxInterStageShaderVariables" => {
349 set_maximum(&mut limits.max_inter_stage_shader_variables, value)
350 },
351 "maxColorAttachments" => set_maximum(&mut limits.max_color_attachments, value),
352 "maxColorAttachmentBytesPerSample" => {
353 set_maximum(&mut limits.max_color_attachment_bytes_per_sample, value)
354 },
355 "maxComputeWorkgroupStorageSize" => {
356 set_maximum(&mut limits.max_compute_workgroup_storage_size, value)
357 },
358 "maxComputeInvocationsPerWorkgroup" => {
359 set_maximum(&mut limits.max_compute_invocations_per_workgroup, value)
360 },
361 "maxComputeWorkgroupSizeX" => set_maximum(&mut limits.max_compute_workgroup_size_x, value),
362 "maxComputeWorkgroupSizeY" => set_maximum(&mut limits.max_compute_workgroup_size_y, value),
363 "maxComputeWorkgroupSizeZ" => set_maximum(&mut limits.max_compute_workgroup_size_z, value),
364 "maxComputeWorkgroupsPerDimension" => {
365 set_maximum(&mut limits.max_compute_workgroups_per_dimension, value)
366 },
367 _ => false,
368 }
369}