diff --git a/player/tests/data/quad.ron b/player/tests/data/quad.ron index b91ef58bfc..e004d52e72 100644 --- a/player/tests/data/quad.ron +++ b/player/tests/data/quad.ron @@ -22,7 +22,7 @@ size: ( width: 64, height: 64, - depth: 1, + depth_or_array_layers: 1, ), mip_level_count: 1, sample_count: 1, @@ -127,7 +127,7 @@ size: ( width: 64, height: 64, - depth: 1, + depth_or_array_layers: 1, ), ), ]), diff --git a/wgpu-core/src/binding_model.rs b/wgpu-core/src/binding_model.rs index 541a6148b7..0d4f0ec9dc 100644 --- a/wgpu-core/src/binding_model.rs +++ b/wgpu-core/src/binding_model.rs @@ -89,8 +89,14 @@ pub enum CreateBindGroupError { SwapChainImage, #[error("buffer offset {0} does not respect `BIND_BUFFER_ALIGNMENT`")] UnalignedBufferOffset(wgt::BufferAddress), - #[error("uniform buffer binding range exceeds `max_uniform_buffer_binding_size` limit")] - UniformBufferRangeTooLarge, + #[error( + "buffer binding {binding} range {given} exceeds `max_*_buffer_binding_size` limit {limit}" + )] + BufferRangeTooLarge { + binding: u32, + given: u32, + limit: u32, + }, #[error("binding {binding} has a different type ({actual:?}) than the one in the layout ({expected:?})")] WrongBindingType { // Index of the binding diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 92ed562143..9679d3c030 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -122,7 +122,7 @@ pub(crate) fn texture_copy_view_to_hal( let (layer, layer_count, z) = match texture.dimension { wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => ( view.origin.z as hal::image::Layer, - size.depth as hal::image::Layer, + size.depth_or_array_layers as hal::image::Layer, 0, ), wgt::TextureDimension::D3 => (0, 1, view.origin.z as i32), @@ -162,7 +162,7 @@ pub(crate) fn validate_linear_texture_data( // Convert all inputs to BufferAddress (u64) to prevent overflow issues let copy_width = copy_size.width as BufferAddress; let copy_height = copy_size.height as BufferAddress; - let copy_depth = copy_size.depth as BufferAddress; + let copy_depth = copy_size.depth_or_array_layers as BufferAddress; let offset = layout.offset; let rows_per_image = layout.rows_per_image as BufferAddress; @@ -244,7 +244,7 @@ pub(crate) fn validate_texture_copy_range( match texture_dimension { hal::image::Kind::D1(..) => { - if (copy_size.height, copy_size.depth) != (1, 1) { + if (copy_size.height, copy_size.depth_or_array_layers) != (1, 1) { return Err(TransferError::InvalidCopySize); } } @@ -274,7 +274,7 @@ pub(crate) fn validate_texture_copy_range( side: texture_side, }); } - let z_copy_max = texture_copy_view.origin.z + copy_size.depth; + let z_copy_max = texture_copy_view.origin.z + copy_size.depth_or_array_layers; if z_copy_max > extent.depth { return Err(TransferError::TextureOverrun { start_offset: texture_copy_view.origin.z, @@ -469,7 +469,7 @@ impl Global { }); } - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth == 0 { + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 { tracing::trace!("Ignoring copy_buffer_to_texture of size 0"); return Ok(()); } @@ -564,7 +564,7 @@ impl Global { let image_extent = Extent3d { width: copy_size.width.min(max_image_extent.width), height: copy_size.height.min(max_image_extent.height), - depth: copy_size.depth, + depth_or_array_layers: copy_size.depth_or_array_layers, }; let buffer_width = (source.layout.bytes_per_row / bytes_per_block) * block_width as u32; @@ -620,7 +620,7 @@ impl Global { }); } - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth == 0 { + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 { tracing::trace!("Ignoring copy_texture_to_buffer of size 0"); return Ok(()); } @@ -718,7 +718,7 @@ impl Global { let image_extent = Extent3d { width: copy_size.width.min(max_image_extent.width), height: copy_size.height.min(max_image_extent.height), - depth: copy_size.depth, + depth_or_array_layers: copy_size.depth_or_array_layers, }; let buffer_width = @@ -781,7 +781,7 @@ impl Global { }); } - if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth == 0 { + if copy_size.width == 0 || copy_size.height == 0 || copy_size.depth_or_array_layers == 0 { tracing::trace!("Ignoring copy_texture_to_texture of size 0"); return Ok(()); } @@ -859,7 +859,7 @@ impl Global { height: copy_size .height .min(max_src_image_extent.height.min(max_dst_image_extent.height)), - depth: copy_size.depth, + depth_or_array_layers: copy_size.depth_or_array_layers, }; let region = hal::command::ImageCopy { diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 1c2fa91ba3..bf4bb2c4d6 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -160,7 +160,7 @@ pub fn map_extent(extent: &wgt::Extent3d, dim: wgt::TextureDimension) -> hal::im height: extent.height, depth: match dim { wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => 1, - wgt::TextureDimension::D3 => extent.depth, + wgt::TextureDimension::D3 => extent.depth_or_array_layers, }, } } @@ -518,52 +518,63 @@ pub fn map_texture_dimension_size( wgt::Extent3d { width, height, - depth, + depth_or_array_layers, }: wgt::Extent3d, sample_size: u32, + limits: &wgt::Limits, ) -> Result { use hal::image::Kind as H; - use resource::TextureDimensionError as Tde; + use resource::{TextureDimensionError as Tde, TextureErrorDimension as Ted}; use wgt::TextureDimension::*; - let zero_dim = if width == 0 { - Some(resource::TextureErrorDimension::X) - } else if height == 0 { - Some(resource::TextureErrorDimension::Y) - } else if depth == 0 { - Some(resource::TextureErrorDimension::Z) - } else { - None + let layers = depth_or_array_layers.try_into().unwrap_or(!0); + let (kind, extent_limits, sample_limit) = match dimension { + D1 => ( + H::D1(width, layers), + [ + limits.max_texture_dimension_1d, + 1, + limits.max_texture_array_layers, + ], + 1, + ), + D2 => ( + H::D2(width, height, layers, sample_size as u8), + [ + limits.max_texture_dimension_2d, + limits.max_texture_dimension_2d, + limits.max_texture_array_layers, + ], + 32, + ), + D3 => ( + H::D3(width, height, depth_or_array_layers), + [ + limits.max_texture_dimension_3d, + limits.max_texture_dimension_3d, + limits.max_texture_dimension_3d, + ], + 1, + ), }; - if let Some(dim) = zero_dim { - return Err(resource::TextureDimensionError::Zero(dim)); + + for (&dim, (&given, &limit)) in [Ted::X, Ted::Y, Ted::Z].iter().zip( + [width, height, depth_or_array_layers] + .iter() + .zip(extent_limits.iter()), + ) { + if given == 0 { + return Err(Tde::Zero(dim)); + } + if given > limit { + return Err(Tde::LimitExceeded { dim, given, limit }); + } + } + if sample_size == 0 || sample_size > sample_limit || !is_power_of_two(sample_size) { + return Err(Tde::InvalidSampleCount(sample_size)); } - Ok(match dimension { - D1 => { - if height != 1 { - return Err(Tde::InvalidHeight); - } - if sample_size != 1 { - return Err(Tde::InvalidSampleCount(sample_size)); - } - let layers = depth.try_into().unwrap_or(!0); - H::D1(width, layers) - } - D2 => { - if sample_size > 32 || !is_power_of_two(sample_size) { - return Err(Tde::InvalidSampleCount(sample_size)); - } - let layers = depth.try_into().unwrap_or(!0); - H::D2(width, height, layers, sample_size as u8) - } - D3 => { - if sample_size != 1 { - return Err(Tde::InvalidSampleCount(sample_size)); - } - H::D3(width, height, depth) - } - }) + Ok(kind) } pub fn map_texture_view_dimension(dimension: wgt::TextureViewDimension) -> hal::image::ViewKind { diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 3fdd512d32..f7d032f92e 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -643,7 +643,12 @@ impl Device { )); } - let kind = conv::map_texture_dimension_size(desc.dimension, desc.size, desc.sample_count)?; + let kind = conv::map_texture_dimension_size( + desc.dimension, + desc.size, + desc.sample_count, + &self.limits, + )?; let format = conv::map_texture_format(desc.format, self.private_features); let aspects = format.surface_desc().aspects; let usage = conv::map_texture_usage(desc.usage, aspects); @@ -660,7 +665,7 @@ impl Device { let mut view_caps = hal::image::ViewCapabilities::empty(); // 2D textures with array layer counts that are multiples of 6 could be cubemaps // Following gpuweb/gpuweb#68 always add the hint in that case - if desc.dimension == TextureDimension::D2 && desc.size.depth % 6 == 0 { + if desc.dimension == TextureDimension::D2 && desc.size.depth_or_array_layers % 6 == 0 { view_caps |= hal::image::ViewCapabilities::KIND_CUBE; }; @@ -874,7 +879,7 @@ impl Device { extent: wgt::Extent3d { width: hal_extent.width, height: hal_extent.height, - depth: view_layer_count, + depth_or_array_layers: view_layer_count, }, samples: texture.kind.num_samples(), framebuffer_attachment: texture.framebuffer_attachment.clone(), @@ -1312,10 +1317,12 @@ impl Device { }) } }; - let (pub_usage, internal_use) = match binding_ty { - wgt::BufferBindingType::Uniform => { - (wgt::BufferUsage::UNIFORM, resource::BufferUse::UNIFORM) - } + let (pub_usage, internal_use, range_limit) = match binding_ty { + wgt::BufferBindingType::Uniform => ( + wgt::BufferUsage::UNIFORM, + resource::BufferUse::UNIFORM, + self.limits.max_uniform_buffer_binding_size, + ), wgt::BufferBindingType::Storage { read_only } => ( wgt::BufferUsage::STORAGE, if read_only { @@ -1323,6 +1330,7 @@ impl Device { } else { resource::BufferUse::STORAGE_STORE }, + self.limits.max_storage_buffer_binding_size, ), }; @@ -1355,10 +1363,12 @@ impl Device { None => (buffer.size - bb.offset, buffer.size), }; - if binding_ty == wgt::BufferBindingType::Uniform - && (self.limits.max_uniform_buffer_binding_size as u64) < bind_size - { - return Err(Error::UniformBufferRangeTooLarge); + if bind_size > range_limit as u64 { + return Err(Error::BufferRangeTooLarge { + binding, + given: bind_size as u32, + limit: range_limit, + }); } // Record binding info for validating dynamic offsets @@ -2029,6 +2039,13 @@ impl Device { if vb_state.attributes.is_empty() { continue; } + if vb_state.array_stride > self.limits.max_vertex_buffer_array_stride as u64 { + return Err(pipeline::CreateRenderPipelineError::VertexStrideTooLarge { + index: i as u32, + given: vb_state.array_stride as u32, + limit: self.limits.max_vertex_buffer_array_stride, + }); + } if vb_state.array_stride % wgt::VERTEX_STRIDE_ALIGNMENT != 0 { return Err(pipeline::CreateRenderPipelineError::UnalignedVertexStride { index: i as u32, @@ -2084,6 +2101,21 @@ impl Device { } } + if vertex_buffers.len() > self.limits.max_vertex_buffers as usize { + return Err(pipeline::CreateRenderPipelineError::TooManyVertexBuffers { + given: vertex_buffers.len() as u32, + limit: self.limits.max_vertex_buffers, + }); + } + if attributes.len() > self.limits.max_vertex_attributes as usize { + return Err( + pipeline::CreateRenderPipelineError::TooManyVertexAttributes { + given: attributes.len() as u32, + limit: self.limits.max_vertex_attributes, + }, + ); + } + if desc.primitive.strip_index_format.is_some() && desc.primitive.topology != wgt::PrimitiveTopology::LineStrip && desc.primitive.topology != wgt::PrimitiveTopology::TriangleStrip diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index c93b45e0c1..494e42e508 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -321,7 +321,7 @@ impl Global { }); } - if size.width == 0 || size.height == 0 || size.depth == 0 { + if size.width == 0 || size.height == 0 || size.depth_or_array_layers == 0 { tracing::trace!("Ignoring write_texture of size 0"); return Ok(()); } @@ -359,7 +359,8 @@ impl Global { ); let stage_bytes_per_row = align_to(bytes_per_block * width_blocks, bytes_per_row_alignment); - let block_rows_in_copy = (size.depth - 1) * block_rows_per_image + height_blocks; + let block_rows_in_copy = + (size.depth_or_array_layers - 1) * block_rows_per_image + height_blocks; let stage_size = stage_bytes_per_row as u64 * block_rows_in_copy as u64; let mut stage = device.prepare_stage(stage_size)?; @@ -403,7 +404,7 @@ impl Global { // Copy row by row into the optimal alignment. let copy_bytes_per_row = stage_bytes_per_row.min(data_layout.bytes_per_row) as usize; - for layer in 0..size.depth { + for layer in 0..size.depth_or_array_layers { let rows_offset = layer * block_rows_per_image; for row in 0..height_blocks { ptr::copy_nonoverlapping( @@ -432,7 +433,7 @@ impl Global { let image_extent = wgt::Extent3d { width: size.width.min(max_image_extent.width), height: size.height.min(max_image_extent.height), - depth: size.depth, + depth_or_array_layers: size.depth_or_array_layers, }; let region = hal::command::BufferImageCopy { diff --git a/wgpu-core/src/instance.rs b/wgpu-core/src/instance.rs index f7e64afe22..229eb5bdb4 100644 --- a/wgpu-core/src/instance.rs +++ b/wgpu-core/src/instance.rs @@ -217,6 +217,20 @@ impl Adapter { // TODO: fix all gfx-hal backends to produce limits we care about, and remove .max let desc_limits = &properties.limits.descriptor_limits; let limits = wgt::Limits { + max_texture_dimension_1d: properties + .limits + .max_image_1d_size + .max(default_limits.max_texture_dimension_1d), + max_texture_dimension_2d: properties + .limits + .max_image_2d_size + .max(default_limits.max_texture_dimension_1d), + max_texture_dimension_3d: properties + .limits + .max_image_3d_size + .max(default_limits.max_texture_dimension_1d), + max_texture_array_layers: (properties.limits.max_image_array_layers as u32) + .max(default_limits.max_texture_array_layers), max_bind_groups: (properties.limits.max_bound_descriptor_sets as u32) .min(MAX_BIND_GROUPS as u32) .max(default_limits.max_bind_groups), @@ -243,6 +257,15 @@ impl Adapter { .max(default_limits.max_uniform_buffers_per_shader_stage), max_uniform_buffer_binding_size: (properties.limits.max_uniform_buffer_range as u32) .max(default_limits.max_uniform_buffer_binding_size), + max_storage_buffer_binding_size: (properties.limits.max_storage_buffer_range as u32) + .max(default_limits.max_storage_buffer_binding_size), + max_vertex_buffers: (properties.limits.max_vertex_input_bindings as u32) + .max(default_limits.max_vertex_buffers), + max_vertex_attributes: (properties.limits.max_vertex_input_attributes as u32) + .max(default_limits.max_vertex_attributes), + max_vertex_buffer_array_stride: (properties.limits.max_vertex_input_binding_stride + as u32) + .max(default_limits.max_vertex_buffer_array_stride), max_push_constant_size: (properties.limits.max_push_constants_size as u32) .max(MIN_PUSH_CONSTANT_SIZE), // As an extension, the default is always 0, so define a separate minimum. }; diff --git a/wgpu-core/src/pipeline.rs b/wgpu-core/src/pipeline.rs index 06dde63bd7..77ab4a27a9 100644 --- a/wgpu-core/src/pipeline.rs +++ b/wgpu-core/src/pipeline.rs @@ -203,6 +203,12 @@ pub enum CreateRenderPipelineError { IncompatibleOutputFormat { index: u8 }, #[error("invalid sample count {0}")] InvalidSampleCount(u32), + #[error("the number of vertex buffers {given} exceeds the limit {limit}")] + TooManyVertexBuffers { given: u32, limit: u32 }, + #[error("the total number of vertex attributes {given} exceeds the limit {limit}")] + TooManyVertexAttributes { given: u32, limit: u32 }, + #[error("vertex buffer {index} stride {given} exceeds the limit {limit}")] + VertexStrideTooLarge { index: u32, given: u32, limit: u32 }, #[error("vertex buffer {index} stride {stride} does not respect `VERTEX_STRIDE_ALIGNMENT`")] UnalignedVertexStride { index: u32, diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 36c276be43..03d28ec6a8 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -213,7 +213,7 @@ pub struct Texture { pub(crate) life_guard: LifeGuard, } -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub enum TextureErrorDimension { X, Y, @@ -224,8 +224,12 @@ pub enum TextureErrorDimension { pub enum TextureDimensionError { #[error("Dimension {0:?} is zero")] Zero(TextureErrorDimension), - #[error("1D textures must have height set to 1")] - InvalidHeight, + #[error("Dimension {0:?} value {given} exceeds the limit of {limit}")] + LimitExceeded { + dim: TextureErrorDimension, + given: u32, + limit: u32, + }, #[error("sample count {0} is invalid")] InvalidSampleCount(u32), } diff --git a/wgpu-core/src/swap_chain.rs b/wgpu-core/src/swap_chain.rs index e8dfe31e26..65fa57149b 100644 --- a/wgpu-core/src/swap_chain.rs +++ b/wgpu-core/src/swap_chain.rs @@ -193,7 +193,7 @@ impl Global { extent: wgt::Extent3d { width: sc.desc.width, height: sc.desc.height, - depth: 1, + depth_or_array_layers: 1, }, samples: 1, framebuffer_attachment: sc.framebuffer_attachment.clone(), diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index c8a11d49d2..254562b872 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -442,6 +442,20 @@ bitflags::bitflags! { #[cfg_attr(feature = "trace", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] pub struct Limits { + /// Maximum allowed value for the `size.width` of a texture created with `TextureDimension::D1`. + /// Defaults to 8192. Higher is "better". + pub max_texture_dimension_1d: u32, + /// Maximum allowed value for the `size.width` and `size.height` of a texture created with `TextureDimension::D2`. + /// Defaults to 8192. Higher is "better". + pub max_texture_dimension_2d: u32, + /// Maximum allowed value for the `size.width`, `size.height`, and `size.depth_or_array_layers` + /// of a texture created with `TextureDimension::D3`. + /// Defaults to 2048. Higher is "better". + pub max_texture_dimension_3d: u32, + /// Maximum allowed value for the `size.depth_or_array_layers` of a texture created with + /// `TextureDimension::D1` or `TextureDimension::D2`. + /// Defaults to 2048. Higher is "better". + pub max_texture_array_layers: u32, /// Amount of bind groups that can be attached to a pipeline at the same time. Defaults to 4. Higher is "better". pub max_bind_groups: u32, /// Amount of uniform buffer bindings that can be dynamic in a single pipeline. Defaults to 8. Higher is "better". @@ -460,6 +474,18 @@ pub struct Limits { pub max_uniform_buffers_per_shader_stage: u32, /// Maximum size in bytes of a binding to a uniform buffer. Defaults to 16384. Higher is "better". pub max_uniform_buffer_binding_size: u32, + /// Maximum size in bytes of a binding to a storage buffer. Defaults to 128 MB. Higher is "better". + pub max_storage_buffer_binding_size: u32, + /// Maximum length of `VertexState::buffers` when creating a `RenderPipeline`. + /// Defaults to 8. Higher is "better". + pub max_vertex_buffers: u32, + /// Maximum length of `VertexBufferLayout::attributes`, summed over all `VertexState::buffers`, + /// when creating a `RenderPipeline`. + /// Defaults to 16. Higher is "better". + pub max_vertex_attributes: u32, + /// Maximum value for `VertexBufferLayout::array_stride` when creating a `RenderPipeline`. + /// Defaults to 2048. Higher is "better". + pub max_vertex_buffer_array_stride: u32, /// Amount of storage available for push constants in bytes. Defaults to 0. Higher is "better". /// Requesting more than 0 during device creation requires [`Features::PUSH_CONSTANTS`] to be enabled. /// @@ -475,6 +501,10 @@ pub struct Limits { impl Default for Limits { fn default() -> Self { Self { + max_texture_dimension_1d: 8192, + max_texture_dimension_2d: 8192, + max_texture_dimension_3d: 2048, + max_texture_array_layers: 2048, max_bind_groups: 4, max_dynamic_uniform_buffers_per_pipeline_layout: 8, max_dynamic_storage_buffers_per_pipeline_layout: 4, @@ -484,6 +514,10 @@ impl Default for Limits { max_storage_textures_per_shader_stage: 4, max_uniform_buffers_per_shader_stage: 12, max_uniform_buffer_binding_size: 16384, + max_storage_buffer_binding_size: 128 << 20, + max_vertex_buffers: 8, + max_vertex_attributes: 16, + max_vertex_buffer_array_stride: 2048, max_push_constant_size: 0, } } @@ -2164,7 +2198,7 @@ pub struct Extent3d { /// pub height: u32, /// - pub depth: u32, + pub depth_or_array_layers: u32, } impl Default for Extent3d { @@ -2172,7 +2206,7 @@ impl Default for Extent3d { Self { width: 1, height: 1, - depth: 1, + depth_or_array_layers: 1, } } } @@ -2187,18 +2221,18 @@ impl Extent3d { /// # use wgpu_types as wgpu; /// let format = wgpu::TextureFormat::Bc1RgbaUnormSrgb; // 4x4 blocks /// assert_eq!( - /// wgpu::Extent3d { width: 7, height: 7, depth: 1 }.physical_size(format), - /// wgpu::Extent3d { width: 8, height: 8, depth: 1 } + /// wgpu::Extent3d { width: 7, height: 7, depth_or_array_layers: 1 }.physical_size(format), + /// wgpu::Extent3d { width: 8, height: 8, depth_or_array_layers: 1 } /// ); /// // Doesn't change, already aligned /// assert_eq!( - /// wgpu::Extent3d { width: 8, height: 8, depth: 1 }.physical_size(format), - /// wgpu::Extent3d { width: 8, height: 8, depth: 1 } + /// wgpu::Extent3d { width: 8, height: 8, depth_or_array_layers: 1 }.physical_size(format), + /// wgpu::Extent3d { width: 8, height: 8, depth_or_array_layers: 1 } /// ); /// let format = wgpu::TextureFormat::Astc8x5RgbaUnorm; // 8x5 blocks /// assert_eq!( - /// wgpu::Extent3d { width: 7, height: 7, depth: 1 }.physical_size(format), - /// wgpu::Extent3d { width: 8, height: 10, depth: 1 } + /// wgpu::Extent3d { width: 7, height: 7, depth_or_array_layers: 1 }.physical_size(format), + /// wgpu::Extent3d { width: 8, height: 10, depth_or_array_layers: 1 } /// ); /// ``` /// @@ -2214,7 +2248,7 @@ impl Extent3d { Self { width, height, - depth: self.depth, + depth_or_array_layers: self.depth_or_array_layers, } } @@ -2225,12 +2259,12 @@ impl Extent3d { /// /// ```rust /// # use wgpu_types as wgpu; - /// assert_eq!(wgpu::Extent3d { width: 1, height: 1, depth: 1 }.max_mips(), 1); - /// assert_eq!(wgpu::Extent3d { width: 60, height: 60, depth: 1 }.max_mips(), 6); - /// assert_eq!(wgpu::Extent3d { width: 240, height: 1, depth: 1 }.max_mips(), 8); + /// assert_eq!(wgpu::Extent3d { width: 1, height: 1, depth_or_array_layers: 1 }.max_mips(), 1); + /// assert_eq!(wgpu::Extent3d { width: 60, height: 60, depth_or_array_layers: 1 }.max_mips(), 6); + /// assert_eq!(wgpu::Extent3d { width: 240, height: 1, depth_or_array_layers: 1 }.max_mips(), 8); /// ``` pub fn max_mips(&self) -> u8 { - let max_dim = self.width.max(self.height.max(self.depth)); + let max_dim = self.width.max(self.height.max(self.depth_or_array_layers)); let max_levels = 32 - max_dim.leading_zeros(); max_levels as u8 @@ -2245,15 +2279,15 @@ impl Extent3d { /// /// ```rust /// # use wgpu_types as wgpu; - /// let extent = wgpu::Extent3d { width: 100, height: 60, depth: 1 }; + /// let extent = wgpu::Extent3d { width: 100, height: 60, depth_or_array_layers: 1 }; /// - /// assert_eq!(extent.at_mip_level(0), Some(wgpu::Extent3d { width: 100, height: 60, depth: 1 })); - /// assert_eq!(extent.at_mip_level(1), Some(wgpu::Extent3d { width: 50, height: 30, depth: 1 })); - /// assert_eq!(extent.at_mip_level(2), Some(wgpu::Extent3d { width: 25, height: 15, depth: 1 })); - /// assert_eq!(extent.at_mip_level(3), Some(wgpu::Extent3d { width: 12, height: 7, depth: 1 })); - /// assert_eq!(extent.at_mip_level(4), Some(wgpu::Extent3d { width: 6, height: 3, depth: 1 })); - /// assert_eq!(extent.at_mip_level(5), Some(wgpu::Extent3d { width: 3, height: 1, depth: 1 })); - /// assert_eq!(extent.at_mip_level(6), Some(wgpu::Extent3d { width: 1, height: 1, depth: 1 })); + /// assert_eq!(extent.at_mip_level(0), Some(wgpu::Extent3d { width: 100, height: 60, depth_or_array_layers: 1 })); + /// assert_eq!(extent.at_mip_level(1), Some(wgpu::Extent3d { width: 50, height: 30, depth_or_array_layers: 1 })); + /// assert_eq!(extent.at_mip_level(2), Some(wgpu::Extent3d { width: 25, height: 15, depth_or_array_layers: 1 })); + /// assert_eq!(extent.at_mip_level(3), Some(wgpu::Extent3d { width: 12, height: 7, depth_or_array_layers: 1 })); + /// assert_eq!(extent.at_mip_level(4), Some(wgpu::Extent3d { width: 6, height: 3, depth_or_array_layers: 1 })); + /// assert_eq!(extent.at_mip_level(5), Some(wgpu::Extent3d { width: 3, height: 1, depth_or_array_layers: 1 })); + /// assert_eq!(extent.at_mip_level(6), Some(wgpu::Extent3d { width: 1, height: 1, depth_or_array_layers: 1 })); /// assert_eq!(extent.at_mip_level(7), None); /// ``` pub fn at_mip_level(&self, level: u8) -> Option { @@ -2263,10 +2297,10 @@ impl Extent3d { return None; } - Some(Extent3d { + Some(Self { width: u32::max(1, self.width >> level as u32), height: u32::max(1, self.height >> level as u32), - depth: u32::max(1, self.depth >> level as u32), + depth_or_array_layers: u32::max(1, self.depth_or_array_layers >> level as u32), }) } }