22
33use core:: cmp:: Ordering ;
44
5+ use macro_rules_attribute:: macro_rules_derive;
6+
57#[ cfg( any( feature = "serde" , test) ) ]
68use serde:: { Deserialize , Serialize } ;
79
810#[ cfg( doc) ]
911use crate :: { Features , TextureFormat } ;
1012
11- /// Invoke a macro for each of the limits.
12- ///
13- /// The supplied macro should take two arguments. The first is a limit name, as
14- /// an identifier, typically used to access a member of `struct Limits`. The
15- /// second is `Ordering::Less` if valid values are less than the limit (the
16- /// common case), or `Ordering::Greater` if valid values are more than the limit
17- /// (for limits like alignments, which are minima instead of maxima).
18- macro_rules! with_limits {
19- ( $macro_name: ident) => {
20- $macro_name!( max_texture_dimension_1d, Ordering :: Less ) ;
21- $macro_name!( max_texture_dimension_1d, Ordering :: Less ) ;
22- $macro_name!( max_texture_dimension_2d, Ordering :: Less ) ;
23- $macro_name!( max_texture_dimension_3d, Ordering :: Less ) ;
24- $macro_name!( max_texture_array_layers, Ordering :: Less ) ;
25- $macro_name!( max_bind_groups, Ordering :: Less ) ;
26- $macro_name!( max_bindings_per_bind_group, Ordering :: Less ) ;
27- $macro_name!(
28- max_dynamic_uniform_buffers_per_pipeline_layout,
29- Ordering :: Less
30- ) ;
31- $macro_name!(
32- max_dynamic_storage_buffers_per_pipeline_layout,
33- Ordering :: Less
34- ) ;
35- $macro_name!( max_sampled_textures_per_shader_stage, Ordering :: Less ) ;
36- $macro_name!( max_samplers_per_shader_stage, Ordering :: Less ) ;
37- $macro_name!( max_storage_buffers_per_shader_stage, Ordering :: Less ) ;
38- $macro_name!( max_storage_textures_per_shader_stage, Ordering :: Less ) ;
39- $macro_name!( max_uniform_buffers_per_shader_stage, Ordering :: Less ) ;
40- $macro_name!( max_binding_array_elements_per_shader_stage, Ordering :: Less ) ;
41- $macro_name!(
42- max_binding_array_acceleration_structure_elements_per_shader_stage,
43- Ordering :: Less
44- ) ;
45- $macro_name!( max_uniform_buffer_binding_size, Ordering :: Less ) ;
46- $macro_name!( max_storage_buffer_binding_size, Ordering :: Less ) ;
47- $macro_name!( max_vertex_buffers, Ordering :: Less ) ;
48- $macro_name!( max_buffer_size, Ordering :: Less ) ;
49- $macro_name!( max_vertex_attributes, Ordering :: Less ) ;
50- $macro_name!( max_vertex_buffer_array_stride, Ordering :: Less ) ;
51- $macro_name!( max_inter_stage_shader_variables, Ordering :: Less ) ;
52- $macro_name!( min_uniform_buffer_offset_alignment, Ordering :: Greater ) ;
53- $macro_name!( min_storage_buffer_offset_alignment, Ordering :: Greater ) ;
54- $macro_name!( max_color_attachments, Ordering :: Less ) ;
55- $macro_name!( max_color_attachment_bytes_per_sample, Ordering :: Less ) ;
56- $macro_name!( max_compute_workgroup_storage_size, Ordering :: Less ) ;
57- $macro_name!( max_compute_invocations_per_workgroup, Ordering :: Less ) ;
58- $macro_name!( max_compute_workgroup_size_x, Ordering :: Less ) ;
59- $macro_name!( max_compute_workgroup_size_y, Ordering :: Less ) ;
60- $macro_name!( max_compute_workgroup_size_z, Ordering :: Less ) ;
61- $macro_name!( max_compute_workgroups_per_dimension, Ordering :: Less ) ;
62-
63- $macro_name!( max_immediate_size, Ordering :: Less ) ;
64- $macro_name!( max_non_sampler_bindings, Ordering :: Less ) ;
65-
66- $macro_name!( max_task_mesh_workgroup_total_count, Ordering :: Less ) ;
67- $macro_name!( max_task_mesh_workgroups_per_dimension, Ordering :: Less ) ;
68- $macro_name!( max_task_invocations_per_workgroup, Ordering :: Less ) ;
69- $macro_name!( max_task_invocations_per_dimension, Ordering :: Less ) ;
70- $macro_name!( max_mesh_invocations_per_workgroup, Ordering :: Less ) ;
71- $macro_name!( max_mesh_invocations_per_dimension, Ordering :: Less ) ;
72-
73- $macro_name!( max_task_payload_size, Ordering :: Less ) ;
74- $macro_name!( max_mesh_output_vertices, Ordering :: Less ) ;
75- $macro_name!( max_mesh_output_primitives, Ordering :: Less ) ;
76- $macro_name!( max_mesh_output_layers, Ordering :: Less ) ;
77- $macro_name!( max_mesh_multiview_view_count, Ordering :: Less ) ;
78-
79- $macro_name!( max_blas_primitive_count, Ordering :: Less ) ;
80- $macro_name!( max_blas_geometry_count, Ordering :: Less ) ;
81- $macro_name!( max_tlas_instance_count, Ordering :: Less ) ;
82-
83- $macro_name!( max_multiview_view_count, Ordering :: Less ) ;
13+ macro_rules! WithLimits {
14+ (
15+ $( #[ $StructMeta: meta] ) *
16+ $StructVis: vis
17+ struct $Struct: ident {
18+ $(
19+ $( #[ doc = $literal: literal] ) *
20+ $( #[ cfg_attr( $Cond: meta, $Output: meta) ] ) *
21+ #[ custom( ordering( $Ordering: ident) ) ]
22+ $( #[ $FieldMeta: meta] ) *
23+ $FieldVis: vis
24+ $Field: ident: $FieldType: ty
25+ ) ,* $( , ) ?
26+ }
27+ ) => {
28+ /// Invoke a macro for each of the limits.
29+ ///
30+ /// The supplied macro should take two arguments. The first is a limit name, as
31+ /// an identifier, typically used to access a member of `struct Limits`. The
32+ /// second is `Ordering::Less` if valid values are less than the limit (the
33+ /// common case), or `Ordering::Greater` if valid values are more than the limit
34+ /// (for limits like alignments, which are minima instead of maxima).
35+ macro_rules! with_limits {
36+ ( $macro_name: ident) => {
37+ $(
38+ $macro_name!( $Field, Ordering :: $Ordering) ;
39+ ) *
40+ } ;
41+ }
8442 } ;
8543}
8644
@@ -120,112 +78,146 @@ macro_rules! with_limits {
12078#[ derive( Clone , Debug , PartialEq , Eq , Hash ) ]
12179#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
12280#[ cfg_attr( feature = "serde" , serde( rename_all = "camelCase" , default ) ) ]
81+ #[ macro_rules_derive( WithLimits ) ]
12382pub struct Limits {
12483 /// Maximum allowed value for the `size.width` of a texture created with `TextureDimension::D1`.
12584 /// Defaults to 8192. Higher is "better".
12685 #[ cfg_attr( feature = "serde" , serde( rename = "maxTextureDimension1D" ) ) ]
86+ #[ custom( ordering( Less ) ) ]
12787 pub max_texture_dimension_1d : u32 ,
12888 /// Maximum allowed value for the `size.width` and `size.height` of a texture created with `TextureDimension::D2`.
12989 /// Defaults to 8192. Higher is "better".
13090 #[ cfg_attr( feature = "serde" , serde( rename = "maxTextureDimension2D" ) ) ]
91+ #[ custom( ordering( Less ) ) ]
13192 pub max_texture_dimension_2d : u32 ,
13293 /// Maximum allowed value for the `size.width`, `size.height`, and `size.depth_or_array_layers`
13394 /// of a texture created with `TextureDimension::D3`.
13495 /// Defaults to 2048. Higher is "better".
13596 #[ cfg_attr( feature = "serde" , serde( rename = "maxTextureDimension3D" ) ) ]
97+ #[ custom( ordering( Less ) ) ]
13698 pub max_texture_dimension_3d : u32 ,
13799 /// Maximum allowed value for the `size.depth_or_array_layers` of a texture created with `TextureDimension::D2`.
138100 /// Defaults to 256. Higher is "better".
101+ #[ custom( ordering( Less ) ) ]
139102 pub max_texture_array_layers : u32 ,
140103 /// Amount of bind groups that can be attached to a pipeline at the same time. Defaults to 4. Higher is "better".
104+ #[ custom( ordering( Less ) ) ]
141105 pub max_bind_groups : u32 ,
142106 /// Maximum binding index allowed in `create_bind_group_layout`. Defaults to 1000. Higher is "better".
107+ #[ custom( ordering( Less ) ) ]
143108 pub max_bindings_per_bind_group : u32 ,
144109 /// Amount of uniform buffer bindings that can be dynamic in a single pipeline. Defaults to 8. Higher is "better".
110+ #[ custom( ordering( Less ) ) ]
145111 pub max_dynamic_uniform_buffers_per_pipeline_layout : u32 ,
146112 /// Amount of storage buffer bindings that can be dynamic in a single pipeline. Defaults to 4. Higher is "better".
113+ #[ custom( ordering( Less ) ) ]
147114 pub max_dynamic_storage_buffers_per_pipeline_layout : u32 ,
148115 /// Amount of sampled textures visible in a single shader stage. Defaults to 16. Higher is "better".
116+ #[ custom( ordering( Less ) ) ]
149117 pub max_sampled_textures_per_shader_stage : u32 ,
150118 /// Amount of samplers visible in a single shader stage. Defaults to 16. Higher is "better".
119+ #[ custom( ordering( Less ) ) ]
151120 pub max_samplers_per_shader_stage : u32 ,
152121 /// Amount of storage buffers visible in a single shader stage. Defaults to 8. Higher is "better".
122+ #[ custom( ordering( Less ) ) ]
153123 pub max_storage_buffers_per_shader_stage : u32 ,
154124 /// Amount of storage textures visible in a single shader stage. Defaults to 4. Higher is "better".
125+ #[ custom( ordering( Less ) ) ]
155126 pub max_storage_textures_per_shader_stage : u32 ,
156127 /// Amount of uniform buffers visible in a single shader stage. Defaults to 12. Higher is "better".
128+ #[ custom( ordering( Less ) ) ]
157129 pub max_uniform_buffers_per_shader_stage : u32 ,
158130 /// Amount of individual resources within binding arrays that can be accessed in a single shader stage. Applies
159131 /// to all types of bindings except samplers.
160132 ///
161133 /// This "defaults" to 0. However if binding arrays are supported, all devices can support 500,000. Higher is "better".
134+ #[ custom( ordering( Less ) ) ]
162135 pub max_binding_array_elements_per_shader_stage : u32 ,
163136 /// Amount of individual acceleration structures within binding arrays that can be accessed in a single shader stage.
164137 ///
165138 /// This "defaults" to 0. Higher is "better".
139+ #[ custom( ordering( Less ) ) ]
166140 pub max_binding_array_acceleration_structure_elements_per_shader_stage : u32 ,
167141 /// Amount of individual samplers within binding arrays that can be accessed in a single shader stage.
168142 ///
169143 /// This "defaults" to 0. However if binding arrays are supported, all devices can support 1,000. Higher is "better".
144+ #[ custom( ordering( Less ) ) ]
170145 pub max_binding_array_sampler_elements_per_shader_stage : u32 ,
171146 /// Maximum size in bytes of a binding to a uniform buffer. Defaults to 64 KiB. Higher is "better".
147+ #[ custom( ordering( Less ) ) ]
172148 pub max_uniform_buffer_binding_size : u64 ,
173149 /// Maximum size in bytes of a binding to a storage buffer. Defaults to 128 MiB. Higher is "better".
150+ #[ custom( ordering( Less ) ) ]
174151 pub max_storage_buffer_binding_size : u64 ,
175152 /// Maximum length of `VertexState::buffers` when creating a `RenderPipeline`.
176153 /// Defaults to 8. Higher is "better".
154+ #[ custom( ordering( Less ) ) ]
177155 pub max_vertex_buffers : u32 ,
178156 /// A limit above which buffer allocations are guaranteed to fail.
179157 /// Defaults to 256 MiB. Higher is "better".
180158 ///
181159 /// Buffer allocations below the maximum buffer size may not succeed depending on available memory,
182160 /// fragmentation and other factors.
161+ #[ custom( ordering( Less ) ) ]
183162 pub max_buffer_size : u64 ,
184163 /// Maximum length of `VertexBufferLayout::attributes`, summed over all `VertexState::buffers`,
185164 /// when creating a `RenderPipeline`.
186165 /// Defaults to 16. Higher is "better".
166+ #[ custom( ordering( Less ) ) ]
187167 pub max_vertex_attributes : u32 ,
188168 /// Maximum value for `VertexBufferLayout::array_stride` when creating a `RenderPipeline`.
189169 /// Defaults to 2048. Higher is "better".
170+ #[ custom( ordering( Less ) ) ]
190171 pub max_vertex_buffer_array_stride : u32 ,
191172 /// Maximum value for the number of input or output variables for inter-stage communication
192173 /// (like vertex outputs or fragment inputs) `@location(…)`s (in WGSL parlance)
193174 /// when creating a `RenderPipeline`.
194175 /// Defaults to 16. Higher is "better".
176+ #[ custom( ordering( Less ) ) ]
195177 pub max_inter_stage_shader_variables : u32 ,
196178 /// Required `BufferBindingType::Uniform` alignment for `BufferBinding::offset`
197179 /// when creating a `BindGroup`, or for `set_bind_group` `dynamicOffsets`.
198180 /// Defaults to 256. Lower is "better".
181+ #[ custom( ordering( Greater ) ) ]
199182 pub min_uniform_buffer_offset_alignment : u32 ,
200183 /// Required `BufferBindingType::Storage` alignment for `BufferBinding::offset`
201184 /// when creating a `BindGroup`, or for `set_bind_group` `dynamicOffsets`.
202185 /// Defaults to 256. Lower is "better".
186+ #[ custom( ordering( Greater ) ) ]
203187 pub min_storage_buffer_offset_alignment : u32 ,
204188 /// The maximum allowed number of color attachments.
189+ #[ custom( ordering( Less ) ) ]
205190 pub max_color_attachments : u32 ,
206191 /// The maximum number of bytes necessary to hold one sample (pixel or subpixel) of render
207192 /// pipeline output data, across all color attachments as described by [`TextureFormat::target_pixel_byte_cost`]
208193 /// and [`TextureFormat::target_component_alignment`]. Defaults to 32. Higher is "better".
209194 ///
210195 /// ⚠️ `Rgba8Unorm`/`Rgba8Snorm`/`Bgra8Unorm`/`Bgra8Snorm` are deceptively 8 bytes per sample. ⚠️
196+ #[ custom( ordering( Less ) ) ]
211197 pub max_color_attachment_bytes_per_sample : u32 ,
212198 /// Maximum number of bytes used for workgroup memory in a compute entry point. Defaults to
213199 /// 16384. Higher is "better".
200+ #[ custom( ordering( Less ) ) ]
214201 pub max_compute_workgroup_storage_size : u32 ,
215202 /// Maximum value of the product of the `workgroup_size` dimensions for a compute entry-point.
216203 /// Defaults to 256. Higher is "better".
204+ #[ custom( ordering( Less ) ) ]
217205 pub max_compute_invocations_per_workgroup : u32 ,
218206 /// The maximum value of the `workgroup_size` X dimension for a compute stage `ShaderModule` entry-point.
219207 /// Defaults to 256. Higher is "better".
208+ #[ custom( ordering( Less ) ) ]
220209 pub max_compute_workgroup_size_x : u32 ,
221210 /// The maximum value of the `workgroup_size` Y dimension for a compute stage `ShaderModule` entry-point.
222211 /// Defaults to 256. Higher is "better".
212+ #[ custom( ordering( Less ) ) ]
223213 pub max_compute_workgroup_size_y : u32 ,
224214 /// The maximum value of the `workgroup_size` Z dimension for a compute stage `ShaderModule` entry-point.
225215 /// Defaults to 64. Higher is "better".
216+ #[ custom( ordering( Less ) ) ]
226217 pub max_compute_workgroup_size_z : u32 ,
227218 /// The maximum value for each dimension of a `ComputePass::dispatch(x, y, z)` operation.
228219 /// Defaults to 65535. Higher is "better".
220+ #[ custom( ordering( Less ) ) ]
229221 pub max_compute_workgroups_per_dimension : u32 ,
230222
231223 /// Amount of storage available for immediates in bytes. Defaults to 0. Higher is "better".
@@ -237,6 +229,7 @@ pub struct Limits {
237229 /// - Metal: 4096 bytes
238230 /// - OpenGL doesn't natively support immediates, and are emulated with uniforms,
239231 /// so this number is less useful but likely 256.
232+ #[ custom( ordering( Less ) ) ]
240233 pub max_immediate_size : u32 ,
241234 /// Maximum number of live non-sampler bindings.
242235 ///
@@ -247,55 +240,72 @@ pub struct Limits {
247240 ///
248241 /// This limit only affects the d3d12 backend. Using a large number will allow the device
249242 /// to create many bind groups at the cost of a large up-front allocation at device creation.
243+ #[ custom( ordering( Less ) ) ]
250244 pub max_non_sampler_bindings : u32 ,
251245
252246 /// The maximum total value for a `RenderPass::draw_mesh_tasks(x, y, z)` operation or the
253247 /// `@builtin(mesh_task_size)` returned from a task shader. Higher is "better".
248+ #[ custom( ordering( Less ) ) ]
254249 pub max_task_mesh_workgroup_total_count : u32 ,
255250 /// The maximum value for each dimension of a `RenderPass::draw_mesh_tasks(x, y, z)` operation.
256251 /// Also for task shader outputs. Higher is "better".
252+ #[ custom( ordering( Less ) ) ]
257253 pub max_task_mesh_workgroups_per_dimension : u32 ,
258254 // These are fundamentally different. It is very common for limits on mesh shaders to be much lower.
259255 /// Maximum total number of invocations, or threads, per task shader workgroup. Higher is "better".
256+ #[ custom( ordering( Less ) ) ]
260257 pub max_task_invocations_per_workgroup : u32 ,
261258 /// The maximum value for each dimension of a task shader's workgroup size. Higher is "better".
259+ #[ custom( ordering( Less ) ) ]
262260 pub max_task_invocations_per_dimension : u32 ,
263261 /// Maximum total number of invocations, or threads, per mesh shader workgroup. Higher is "better".
262+ #[ custom( ordering( Less ) ) ]
264263 pub max_mesh_invocations_per_workgroup : u32 ,
265264 /// The maximum value for each dimension of a mesh shader's workgroup size. Higher is "better".
265+ #[ custom( ordering( Less ) ) ]
266266 pub max_mesh_invocations_per_dimension : u32 ,
267267
268268 /// The maximum size of the payload passed from task to mesh shader. Higher is "better".
269+ #[ custom( ordering( Less ) ) ]
269270 pub max_task_payload_size : u32 ,
270271 /// The maximum number of vertices that a mesh shader may output. Higher is "better".
272+ #[ custom( ordering( Less ) ) ]
271273 pub max_mesh_output_vertices : u32 ,
272274 /// The maximum number of primitives that a mesh shader may output. Higher is "better".
275+ #[ custom( ordering( Less ) ) ]
273276 pub max_mesh_output_primitives : u32 ,
274277 /// The maximum number of layers that can be output from a mesh shader. Higher is "better".
275278 /// See [#8509](https://github.com/gfx-rs/wgpu/issues/8509).
279+ #[ custom( ordering( Less ) ) ]
276280 pub max_mesh_output_layers : u32 ,
277281 /// The maximum number of views that can be used by a mesh shader in multiview rendering.
278282 /// Higher is "better".
283+ #[ custom( ordering( Less ) ) ]
279284 pub max_mesh_multiview_view_count : u32 ,
280285
281286 /// The maximum number of primitive (ex: triangles, aabbs) a BLAS is allowed to have. Requesting
282287 /// more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`]
283288 /// is enabled.
289+ #[ custom( ordering( Less ) ) ]
284290 pub max_blas_primitive_count : u32 ,
285291 /// The maximum number of geometry descriptors a BLAS is allowed to have. Requesting
286292 /// more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`]
287293 /// is enabled.
294+ #[ custom( ordering( Less ) ) ]
288295 pub max_blas_geometry_count : u32 ,
289296 /// The maximum number of instances a TLAS is allowed to have. Requesting more than 0 during
290297 /// device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`]
291298 /// is enabled.
299+ #[ custom( ordering( Less ) ) ]
292300 pub max_tlas_instance_count : u32 ,
293301 /// The maximum number of acceleration structures allowed to be used in a shader stage.
294302 /// Requesting more than 0 during device creation only makes sense if [`Features::EXPERIMENTAL_RAY_QUERY`]
295303 /// is enabled.
304+ #[ custom( ordering( Less ) ) ]
296305 pub max_acceleration_structures_per_shader_stage : u32 ,
297306
298307 /// The maximum number of views that can be used in multiview rendering
308+ #[ custom( ordering( Less ) ) ]
299309 pub max_multiview_view_count : u32 ,
300310}
301311
0 commit comments