1use GPUSupportedLimits_Binding::GPUSupportedLimitsMethods;
6use dom_struct::dom_struct;
7use js::context::JSContext;
8use num_traits::bounds::UpperBounded;
9use script_bindings::reflector::{Reflector, reflect_dom_object_with_cx};
10use wgpu_types::Limits;
11
12use crate::dom::bindings::codegen::Bindings::WebGPUBinding::GPUSupportedLimits_Binding;
13use crate::dom::bindings::root::DomRoot;
14use crate::dom::globalscope::GlobalScope;
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(cx: &mut JSContext, global: &GlobalScope, limits: Limits) -> DomRoot<Self> {
34 reflect_dom_object_with_cx(Box::new(Self::new_inherited(limits)), global, cx)
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_plus_vertex_buffers
68 }
69
70 fn MaxBindingsPerBindGroup(&self) -> u32 {
79 self.limits.max_bindings_per_bind_group
80 }
81
82 fn MaxDynamicUniformBuffersPerPipelineLayout(&self) -> u32 {
84 self.limits.max_dynamic_uniform_buffers_per_pipeline_layout
85 }
86
87 fn MaxDynamicStorageBuffersPerPipelineLayout(&self) -> u32 {
89 self.limits.max_dynamic_storage_buffers_per_pipeline_layout
90 }
91
92 fn MaxSampledTexturesPerShaderStage(&self) -> u32 {
94 self.limits.max_sampled_textures_per_shader_stage
95 }
96
97 fn MaxSamplersPerShaderStage(&self) -> u32 {
99 self.limits.max_samplers_per_shader_stage
100 }
101
102 fn MaxStorageBuffersPerShaderStage(&self) -> u32 {
104 self.limits.max_storage_buffers_per_shader_stage
105 }
106
107 fn MaxStorageBuffersInVertexStage(&self) -> u32 {
109 self.limits.max_storage_buffers_per_shader_stage
111 }
112
113 fn MaxStorageBuffersInFragmentStage(&self) -> u32 {
115 self.limits.max_storage_buffers_per_shader_stage
117 }
118
119 fn MaxStorageTexturesPerShaderStage(&self) -> u32 {
121 self.limits.max_storage_textures_per_shader_stage
122 }
123
124 fn MaxStorageTexturesInVertexStage(&self) -> u32 {
126 self.limits.max_storage_textures_per_shader_stage
128 }
129
130 fn MaxStorageTexturesInFragmentStage(&self) -> u32 {
132 self.limits.max_storage_textures_per_shader_stage
134 }
135
136 fn MaxUniformBuffersPerShaderStage(&self) -> u32 {
138 self.limits.max_uniform_buffers_per_shader_stage
139 }
140
141 fn MaxUniformBufferBindingSize(&self) -> u64 {
143 self.limits.max_uniform_buffer_binding_size
144 }
145
146 fn MaxStorageBufferBindingSize(&self) -> u64 {
148 self.limits.max_storage_buffer_binding_size
149 }
150
151 fn MinUniformBufferOffsetAlignment(&self) -> u32 {
153 self.limits.min_uniform_buffer_offset_alignment
154 }
155
156 fn MinStorageBufferOffsetAlignment(&self) -> u32 {
158 self.limits.min_storage_buffer_offset_alignment
159 }
160
161 fn MaxVertexBuffers(&self) -> u32 {
163 self.limits.max_vertex_buffers
164 }
165
166 fn MaxBufferSize(&self) -> u64 {
168 self.limits.max_buffer_size
169 }
170
171 fn MaxVertexAttributes(&self) -> u32 {
173 self.limits.max_vertex_attributes
174 }
175
176 fn MaxVertexBufferArrayStride(&self) -> u32 {
178 self.limits.max_vertex_buffer_array_stride
179 }
180
181 fn MaxInterStageShaderVariables(&self) -> u32 {
183 self.limits.max_inter_stage_shader_variables
184 }
185
186 fn MaxColorAttachments(&self) -> u32 {
188 self.limits.max_color_attachments
189 }
190
191 fn MaxColorAttachmentBytesPerSample(&self) -> u32 {
193 self.limits.max_color_attachment_bytes_per_sample
194 }
195
196 fn MaxComputeWorkgroupStorageSize(&self) -> u32 {
198 self.limits.max_compute_workgroup_storage_size
199 }
200
201 fn MaxComputeInvocationsPerWorkgroup(&self) -> u32 {
203 self.limits.max_compute_invocations_per_workgroup
204 }
205
206 fn MaxComputeWorkgroupSizeX(&self) -> u32 {
208 self.limits.max_compute_workgroup_size_x
209 }
210
211 fn MaxComputeWorkgroupSizeY(&self) -> u32 {
213 self.limits.max_compute_workgroup_size_y
214 }
215
216 fn MaxComputeWorkgroupSizeZ(&self) -> u32 {
218 self.limits.max_compute_workgroup_size_z
219 }
220
221 fn MaxComputeWorkgroupsPerDimension(&self) -> u32 {
223 self.limits.max_compute_workgroups_per_dimension
224 }
225}
226
227pub(crate) fn set_limit(limits: &mut Limits, limit: &str, value: u64) -> bool {
229 fn set_maximum<T>(limit: &mut T, value: u64) -> bool
233 where
234 T: Ord + Copy + TryFrom<u64> + UpperBounded,
235 {
236 if let Ok(value) = T::try_from(value) {
237 *limit = value.max(*limit);
238 true
239 } else {
240 false
241 }
242 }
243
244 fn set_alignment<T>(limit: &mut T, value: u64) -> bool
248 where
249 T: Ord + Copy + TryFrom<u64> + UpperBounded,
250 {
251 if !value.is_power_of_two() {
252 return false;
253 }
254 if let Ok(value) = T::try_from(value) {
255 *limit = value.min(*limit);
256 true
257 } else {
258 false
259 }
260 }
261
262 match limit {
264 "maxTextureDimension1D" => set_maximum(&mut limits.max_texture_dimension_1d, value),
265 "maxTextureDimension2D" => set_maximum(&mut limits.max_texture_dimension_2d, value),
266 "maxTextureDimension3D" => set_maximum(&mut limits.max_texture_dimension_3d, value),
267 "maxTextureArrayLayers" => set_maximum(&mut limits.max_texture_array_layers, value),
268 "maxBindGroups" => set_maximum(&mut limits.max_bind_groups, value),
269 "maxBindGroupsPlusVertexBuffers" => {
270 set_maximum(&mut limits.max_bind_groups_plus_vertex_buffers, value)
271 },
272 "maxImmediateSize" => set_maximum(&mut limits.max_immediate_size, value),
273 "maxBindingsPerBindGroup" => set_maximum(&mut limits.max_bindings_per_bind_group, value),
274 "maxDynamicUniformBuffersPerPipelineLayout" => set_maximum(
275 &mut limits.max_dynamic_uniform_buffers_per_pipeline_layout,
276 value,
277 ),
278 "maxDynamicStorageBuffersPerPipelineLayout" => set_maximum(
279 &mut limits.max_dynamic_storage_buffers_per_pipeline_layout,
280 value,
281 ),
282 "maxSampledTexturesPerShaderStage" => {
283 set_maximum(&mut limits.max_sampled_textures_per_shader_stage, value)
284 },
285 "maxSamplersPerShaderStage" => {
286 set_maximum(&mut limits.max_samplers_per_shader_stage, value)
287 },
288 "maxStorageBuffersPerShaderStage" => {
289 set_maximum(&mut limits.max_storage_buffers_per_shader_stage, value)
290 },
291 "maxStorageBuffersInVertexStage" => {
292 let mut v: u32 = 0;
296 set_maximum(&mut v, value)
297 },
298 "maxStorageBuffersInFragmentStage" => {
299 let mut v: u32 = 0;
303 set_maximum(&mut v, value)
304 },
305 "maxStorageTexturesPerShaderStage" => {
306 set_maximum(&mut limits.max_storage_textures_per_shader_stage, value)
307 },
308 "maxStorageTexturesInVertexStage" => {
309 let mut v: u32 = 0;
313 set_maximum(&mut v, value)
314 },
315 "maxStorageTexturesInFragmentStage" => {
316 let mut v: u32 = 0;
320 set_maximum(&mut v, value)
321 },
322 "maxUniformBuffersPerShaderStage" => {
323 set_maximum(&mut limits.max_uniform_buffers_per_shader_stage, value)
324 },
325 "maxUniformBufferBindingSize" => {
326 set_maximum(&mut limits.max_uniform_buffer_binding_size, value)
327 },
328 "maxStorageBufferBindingSize" => {
329 set_maximum(&mut limits.max_storage_buffer_binding_size, value)
330 },
331 "minUniformBufferOffsetAlignment" => {
332 set_alignment(&mut limits.min_uniform_buffer_offset_alignment, value)
333 },
334 "minStorageBufferOffsetAlignment" => {
335 set_alignment(&mut limits.min_storage_buffer_offset_alignment, value)
336 },
337 "maxVertexBuffers" => set_maximum(&mut limits.max_vertex_buffers, value),
338 "maxBufferSize" => set_maximum(&mut limits.max_buffer_size, value),
339 "maxVertexAttributes" => set_maximum(&mut limits.max_vertex_attributes, value),
340 "maxVertexBufferArrayStride" => {
341 set_maximum(&mut limits.max_vertex_buffer_array_stride, value)
342 },
343 "maxInterStageShaderVariables" => {
344 set_maximum(&mut limits.max_inter_stage_shader_variables, value)
345 },
346 "maxColorAttachments" => set_maximum(&mut limits.max_color_attachments, value),
347 "maxColorAttachmentBytesPerSample" => {
348 set_maximum(&mut limits.max_color_attachment_bytes_per_sample, value)
349 },
350 "maxComputeWorkgroupStorageSize" => {
351 set_maximum(&mut limits.max_compute_workgroup_storage_size, value)
352 },
353 "maxComputeInvocationsPerWorkgroup" => {
354 set_maximum(&mut limits.max_compute_invocations_per_workgroup, value)
355 },
356 "maxComputeWorkgroupSizeX" => set_maximum(&mut limits.max_compute_workgroup_size_x, value),
357 "maxComputeWorkgroupSizeY" => set_maximum(&mut limits.max_compute_workgroup_size_y, value),
358 "maxComputeWorkgroupSizeZ" => set_maximum(&mut limits.max_compute_workgroup_size_z, value),
359 "maxComputeWorkgroupsPerDimension" => {
360 set_maximum(&mut limits.max_compute_workgroups_per_dimension, value)
361 },
362 _ => false,
363 }
364}