diff --git a/CHANGELOG.md b/CHANGELOG.md index eeb0dcb046..f8d114831b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,12 @@ Bottom level categories: ## Unreleased +### Major changes + +#### General + +- Change type of `mip_level_count` and `array_layer_count` (members of `TextureViewDescriptor` and `ImageSubresourceRange`) from `Option` to `Option`. By @teoxoy in [#3445](https://github.com/gfx-rs/wgpu/pull/3445) + ### Changes #### WebGPU diff --git a/deno_webgpu/src/texture.rs b/deno_webgpu/src/texture.rs index 94fa7141c1..1578312cef 100644 --- a/deno_webgpu/src/texture.rs +++ b/deno_webgpu/src/texture.rs @@ -73,11 +73,8 @@ pub struct CreateTextureViewArgs { label: Option, format: Option, dimension: Option, - aspect: wgpu_types::TextureAspect, - base_mip_level: u32, - mip_level_count: Option, - base_array_layer: u32, - array_layer_count: Option, + #[serde(flatten)] + range: wgpu_types::ImageSubresourceRange, } #[op] @@ -95,13 +92,7 @@ pub fn op_webgpu_create_texture_view( label: args.label.map(Cow::from), format: args.format, dimension: args.dimension, - range: wgpu_types::ImageSubresourceRange { - aspect: args.aspect, - base_mip_level: args.base_mip_level, - mip_level_count: std::num::NonZeroU32::new(args.mip_level_count.unwrap_or(0)), - base_array_layer: args.base_array_layer, - array_layer_count: std::num::NonZeroU32::new(args.array_layer_count.unwrap_or(0)), - }, + range: args.range, }; gfx_put!(texture => instance.texture_create_view( diff --git a/wgpu-core/src/command/clear.rs b/wgpu-core/src/command/clear.rs index 8b93960ddd..ce39adc135 100644 --- a/wgpu-core/src/command/clear.rs +++ b/wgpu-core/src/command/clear.rs @@ -53,14 +53,14 @@ whereas subesource range specified start {subresource_base_mip_level} and count InvalidTextureLevelRange { texture_level_range: Range, subresource_base_mip_level: u32, - subresource_mip_level_count: Option, + subresource_mip_level_count: Option, }, #[error("image subresource layer range is outside of the texture's layer range. texture range is {texture_layer_range:?}, \ whereas subesource range specified start {subresource_base_array_layer} and count {subresource_array_layer_count:?}")] InvalidTextureLayerRange { texture_layer_range: Range, subresource_base_array_layer: u32, - subresource_array_layer_count: Option, + subresource_array_layer_count: Option, }, } @@ -188,12 +188,9 @@ impl Global { }; // Check if subresource level range is valid - let subresource_level_end = match subresource_range.mip_level_count { - Some(count) => subresource_range.base_mip_level + count.get(), - None => dst_texture.full_range.mips.end, - }; - if dst_texture.full_range.mips.start > subresource_range.base_mip_level - || dst_texture.full_range.mips.end < subresource_level_end + let subresource_mip_range = subresource_range.mip_range(dst_texture.full_range.mips.end); + if dst_texture.full_range.mips.start > subresource_mip_range.start + || dst_texture.full_range.mips.end < subresource_mip_range.end { return Err(ClearError::InvalidTextureLevelRange { texture_level_range: dst_texture.full_range.mips.clone(), @@ -202,12 +199,10 @@ impl Global { }); } // Check if subresource layer range is valid - let subresource_layer_end = match subresource_range.array_layer_count { - Some(count) => subresource_range.base_array_layer + count.get(), - None => dst_texture.full_range.layers.end, - }; - if dst_texture.full_range.layers.start > subresource_range.base_array_layer - || dst_texture.full_range.layers.end < subresource_layer_end + let subresource_layer_range = + subresource_range.layer_range(dst_texture.full_range.layers.end); + if dst_texture.full_range.layers.start > subresource_layer_range.start + || dst_texture.full_range.layers.end < subresource_layer_range.end { return Err(ClearError::InvalidTextureLayerRange { texture_layer_range: dst_texture.full_range.layers.clone(), @@ -222,8 +217,8 @@ impl Global { &*texture_guard, Valid(dst), TextureInitRange { - mip_range: subresource_range.base_mip_level..subresource_level_end, - layer_range: subresource_range.base_array_layer..subresource_layer_end, + mip_range: subresource_mip_range, + layer_range: subresource_layer_range, }, cmd_buf.encoder.open(), &mut cmd_buf.trackers.textures, diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index a3906e3760..9370e7bd4c 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -191,7 +191,8 @@ pub(crate) fn extract_texture_selector( } let (layers, origin_z) = match texture.desc.dimension { - wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => ( + wgt::TextureDimension::D1 => (0..1, 0), + wgt::TextureDimension::D2 => ( copy_texture.origin.z..copy_texture.origin.z + copy_size.depth_or_array_layers, 0, ), @@ -323,7 +324,7 @@ pub(crate) fn validate_linear_texture_data( /// /// Returns the HAL copy extent and the layer count. /// -/// [vtcr]: https://gpuweb.github.io/gpuweb/#valid-texture-copy-range +/// [vtcr]: https://gpuweb.github.io/gpuweb/#validating-texture-copy-range pub(crate) fn validate_texture_copy_range( texture_copy_view: &ImageCopyTexture, desc: &wgt::TextureDescriptor<(), Vec>, @@ -417,9 +418,8 @@ pub(crate) fn validate_texture_copy_range( } let (depth, array_layer_count) = match desc.dimension { - wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => { - (1, copy_size.depth_or_array_layers) - } + wgt::TextureDimension::D1 => (1, 1), + wgt::TextureDimension::D2 => (1, copy_size.depth_or_array_layers), wgt::TextureDimension::D3 => (copy_size.depth_or_array_layers, 1), }; diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index c344ece757..ea9dece925 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -931,9 +931,9 @@ impl Device { range: wgt::ImageSubresourceRange { aspect: wgt::TextureAspect::All, base_mip_level: mip_level, - mip_level_count: NonZeroU32::new(1), + mip_level_count: Some(1), base_array_layer: array_layer, - array_layer_count: NonZeroU32::new(1), + array_layer_count: Some(1), }, }; clear_views.push( @@ -992,33 +992,28 @@ impl Device { wgt::TextureDimension::D3 => wgt::TextureViewDimension::D3, }); - let resolved_mip_level_count = desc - .range - .mip_level_count - .map(NonZeroU32::get) - .unwrap_or_else(|| { - texture - .desc - .mip_level_count - .saturating_sub(desc.range.base_mip_level) - }); + let resolved_mip_level_count = desc.range.mip_level_count.unwrap_or_else(|| { + texture + .desc + .mip_level_count + .saturating_sub(desc.range.base_mip_level) + }); - let resolved_array_layer_count = desc - .range - .array_layer_count - .map(NonZeroU32::get) - .unwrap_or_else(|| match resolved_dimension { - wgt::TextureViewDimension::D1 - | wgt::TextureViewDimension::D2 - | wgt::TextureViewDimension::D3 => 1, - wgt::TextureViewDimension::Cube => 6, - wgt::TextureViewDimension::D2Array | wgt::TextureViewDimension::CubeArray => { - texture - .desc - .array_layer_count() - .saturating_sub(desc.range.base_array_layer) - } - }); + let resolved_array_layer_count = + desc.range + .array_layer_count + .unwrap_or_else(|| match resolved_dimension { + wgt::TextureViewDimension::D1 + | wgt::TextureViewDimension::D2 + | wgt::TextureViewDimension::D3 => 1, + wgt::TextureViewDimension::Cube => 6, + wgt::TextureViewDimension::D2Array | wgt::TextureViewDimension::CubeArray => { + texture + .desc + .array_layer_count() + .saturating_sub(desc.range.base_array_layer) + } + }); // validate TextureViewDescriptor @@ -1179,9 +1174,9 @@ impl Device { let resolved_range = wgt::ImageSubresourceRange { aspect: desc.range.aspect, base_mip_level: desc.range.base_mip_level, - mip_level_count: NonZeroU32::new(resolved_mip_level_count), + mip_level_count: Some(resolved_mip_level_count), base_array_layer: desc.range.base_array_layer, - array_layer_count: NonZeroU32::new(resolved_array_layer_count), + array_layer_count: Some(resolved_array_layer_count), }; let hal_desc = hal::TextureViewDescriptor { @@ -1878,8 +1873,11 @@ impl Device { used_texture_ranges.push(TextureInitTrackerAction { id: view.parent_id.value.0, range: TextureInitRange { - mip_range: view.desc.range.mip_range(&texture.desc), - layer_range: view.desc.range.layer_range(&texture.desc), + mip_range: view.desc.range.mip_range(texture.desc.mip_level_count), + layer_range: view + .desc + .range + .layer_range(texture.desc.array_layer_count()), }, kind: MemoryInitKind::NeedsInitializedMemory, }); diff --git a/wgpu-core/src/track/mod.rs b/wgpu-core/src/track/mod.rs index c5bfa68ebb..b2548f08ae 100644 --- a/wgpu-core/src/track/mod.rs +++ b/wgpu-core/src/track/mod.rs @@ -105,7 +105,7 @@ use crate::{ pipeline, resource, }; -use std::{fmt, num::NonZeroU32, ops}; +use std::{fmt, ops}; use thiserror::Error; pub(crate) use buffer::{BufferBindGroupState, BufferTracker, BufferUsageScope}; @@ -162,9 +162,9 @@ impl PendingTransition { range: wgt::ImageSubresourceRange { aspect: wgt::TextureAspect::All, base_mip_level: self.selector.mips.start, - mip_level_count: unsafe { Some(NonZeroU32::new_unchecked(mip_count)) }, + mip_level_count: Some(mip_count), base_array_layer: self.selector.layers.start, - array_layer_count: unsafe { Some(NonZeroU32::new_unchecked(layer_count)) }, + array_layer_count: Some(layer_count), }, usage: self.usage, } diff --git a/wgpu-hal/src/dx12/command.rs b/wgpu-hal/src/dx12/command.rs index d109531ace..d678496960 100644 --- a/wgpu-hal/src/dx12/command.rs +++ b/wgpu-hal/src/dx12/command.rs @@ -384,20 +384,12 @@ impl crate::CommandEncoder for super::CommandEncoder { } }; - let mip_level_count = match barrier.range.mip_level_count { - Some(count) => count.get(), - None => barrier.texture.mip_level_count - barrier.range.base_mip_level, - }; - let array_layer_count = match barrier.range.array_layer_count { - Some(count) => count.get(), - None => barrier.texture.array_layer_count() - barrier.range.base_array_layer, - }; + let tex_mip_level_count = barrier.texture.mip_level_count; + let tex_array_layer_count = barrier.texture.array_layer_count(); - if barrier.range.aspect == wgt::TextureAspect::All - && barrier.range.base_mip_level == 0 - && mip_level_count == barrier.texture.mip_level_count - && barrier.range.base_array_layer == 0 - && array_layer_count == barrier.texture.array_layer_count() + if barrier + .range + .is_full_resource(tex_mip_level_count, tex_array_layer_count) { // Only one barrier if it affects the whole image. self.temp.barriers.push(raw); @@ -415,16 +407,13 @@ impl crate::CommandEncoder for super::CommandEncoder { 0..1 }; - for rel_mip_level in 0..mip_level_count { - for rel_array_layer in 0..array_layer_count { + for mip_level in barrier.range.mip_range(tex_mip_level_count) { + for array_layer in barrier.range.layer_range(tex_array_layer_count) { for plane in planes.clone() { unsafe { - raw.u.Transition_mut().Subresource = - barrier.texture.calc_subresource( - barrier.range.base_mip_level + rel_mip_level, - barrier.range.base_array_layer + rel_array_layer, - plane, - ); + raw.u.Transition_mut().Subresource = barrier + .texture + .calc_subresource(mip_level, array_layer, plane); }; self.temp.barriers.push(raw); } diff --git a/wgpu-hal/src/dx12/mod.rs b/wgpu-hal/src/dx12/mod.rs index 81e0b962f7..5e4d399e3b 100644 --- a/wgpu-hal/src/dx12/mod.rs +++ b/wgpu-hal/src/dx12/mod.rs @@ -434,10 +434,8 @@ unsafe impl Sync for Texture {} impl Texture { fn array_layer_count(&self) -> u32 { match self.dimension { - wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => { - self.size.depth_or_array_layers - } - wgt::TextureDimension::D3 => 1, + wgt::TextureDimension::D1 | wgt::TextureDimension::D3 => 1, + wgt::TextureDimension::D2 => self.size.depth_or_array_layers, } } diff --git a/wgpu-hal/src/dx12/view.rs b/wgpu-hal/src/dx12/view.rs index 39d9707312..f52e0ee4b8 100644 --- a/wgpu-hal/src/dx12/view.rs +++ b/wgpu-hal/src/dx12/view.rs @@ -23,15 +23,9 @@ impl crate::TextureViewDescriptor<'_> { format_nodepth: auxil::dxgi::conv::map_texture_format_nodepth(self.format), multisampled: texture.sample_count > 1, mip_level_base: self.range.base_mip_level, - mip_level_count: match self.range.mip_level_count { - Some(count) => count.get(), - None => !0, - }, + mip_level_count: self.range.mip_level_count.unwrap_or(!0), array_layer_base: self.range.base_array_layer, - array_layer_count: match self.range.array_layer_count { - Some(count) => count.get(), - None => !0, - }, + array_layer_count: self.range.array_layer_count.unwrap_or(!0), } } } diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index b8c530ed30..f6921d2b69 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -101,9 +101,7 @@ impl super::Device { desc: &crate::TextureDescriptor, drop_guard: Option, ) -> super::Texture { - let mut copy_size = crate::CopyExtent::map_extent_to_copy_size(&desc.size, desc.dimension); - - let (target, _, is_cubemap) = super::Texture::get_info_from_desc(&mut copy_size, desc); + let (target, _, is_cubemap) = super::Texture::get_info_from_desc(desc); super::Texture { inner: super::TextureInner::Texture { @@ -112,14 +110,10 @@ impl super::Device { }, drop_guard, mip_level_count: desc.mip_level_count, - array_layer_count: if desc.dimension == wgt::TextureDimension::D2 { - desc.size.depth_or_array_layers - } else { - 1 - }, + array_layer_count: desc.array_layer_count(), format: desc.format, format_desc: self.shared.describe_texture_format(desc.format), - copy_size, + copy_size: desc.copy_extent(), is_cubemap, } } @@ -138,22 +132,16 @@ impl super::Device { desc: &crate::TextureDescriptor, drop_guard: Option, ) -> super::Texture { - let copy_size = crate::CopyExtent::map_extent_to_copy_size(&desc.size, desc.dimension); - super::Texture { inner: super::TextureInner::Renderbuffer { raw: glow::NativeRenderbuffer(name), }, drop_guard, mip_level_count: desc.mip_level_count, - array_layer_count: if desc.dimension == wgt::TextureDimension::D2 { - desc.size.depth_or_array_layers - } else { - 1 - }, + array_layer_count: desc.array_layer_count(), format: desc.format, format_desc: self.shared.describe_texture_format(desc.format), - copy_size, + copy_size: desc.copy_extent(), is_cubemap: false, } } @@ -675,12 +663,6 @@ impl crate::Device for super::Device { | crate::TextureUses::DEPTH_STENCIL_READ; let format_desc = self.shared.describe_texture_format(desc.format); - let mut copy_size = crate::CopyExtent { - width: desc.size.width, - height: desc.size.height, - depth: 1, - }; - let (inner, is_cubemap) = if render_usage.contains(desc.usage) && desc.dimension == wgt::TextureDimension::D2 && desc.size.depth_or_array_layers == 1 @@ -720,8 +702,7 @@ impl crate::Device for super::Device { (super::TextureInner::Renderbuffer { raw }, false) } else { let raw = unsafe { gl.create_texture().unwrap() }; - let (target, is_3d, is_cubemap) = - super::Texture::get_info_from_desc(&mut copy_size, desc); + let (target, is_3d, is_cubemap) = super::Texture::get_info_from_desc(desc); unsafe { gl.bind_texture(target, Some(raw)) }; //Note: this has to be done before defining the storage! @@ -791,14 +772,10 @@ impl crate::Device for super::Device { inner, drop_guard: None, mip_level_count: desc.mip_level_count, - array_layer_count: if desc.dimension == wgt::TextureDimension::D2 { - desc.size.depth_or_array_layers - } else { - 1 - }, + array_layer_count: desc.array_layer_count(), format: desc.format, format_desc, - copy_size, + copy_size: desc.copy_extent(), is_cubemap, }) } @@ -828,22 +805,14 @@ impl crate::Device for super::Device { texture: &super::Texture, desc: &crate::TextureViewDescriptor, ) -> Result { - let end_array_layer = match desc.range.array_layer_count { - Some(count) => desc.range.base_array_layer + count.get(), - None => texture.array_layer_count, - }; - let end_mip_level = match desc.range.mip_level_count { - Some(count) => desc.range.base_mip_level + count.get(), - None => texture.mip_level_count, - }; Ok(super::TextureView { //TODO: use `conv::map_view_dimension(desc.dimension)`? inner: texture.inner.clone(), sample_type: texture.format.describe().sample_type, aspects: crate::FormatAspects::from(texture.format) & crate::FormatAspects::from(desc.range.aspect), - mip_levels: desc.range.base_mip_level..end_mip_level, - array_layers: desc.range.base_array_layer..end_array_layer, + mip_levels: desc.range.mip_range(texture.mip_level_count), + array_layers: desc.range.layer_range(texture.array_layer_count), format: texture.format, }) } diff --git a/wgpu-hal/src/gles/mod.rs b/wgpu-hal/src/gles/mod.rs index 5b0e447c1b..31fde089d9 100644 --- a/wgpu-hal/src/gles/mod.rs +++ b/wgpu-hal/src/gles/mod.rs @@ -319,35 +319,19 @@ impl Texture { } /// Returns the `target`, whether the image is 3d and whether the image is a cubemap. - fn get_info_from_desc( - copy_size: &mut CopyExtent, - desc: &TextureDescriptor, - ) -> (u32, bool, bool) { + fn get_info_from_desc(desc: &TextureDescriptor) -> (u32, bool, bool) { match desc.dimension { - wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => { - if desc.size.depth_or_array_layers > 1 { - //HACK: detect a cube map - let cube_count = if desc.size.width == desc.size.height - && desc.size.depth_or_array_layers % 6 == 0 - && desc.sample_count == 1 - { - Some(desc.size.depth_or_array_layers / 6) - } else { - None - }; - match cube_count { - None => (glow::TEXTURE_2D_ARRAY, true, false), - Some(1) => (glow::TEXTURE_CUBE_MAP, false, true), - Some(_) => (glow::TEXTURE_CUBE_MAP_ARRAY, true, true), - } - } else { - (glow::TEXTURE_2D, false, false) + wgt::TextureDimension::D1 => (glow::TEXTURE_2D, false, false), + wgt::TextureDimension::D2 => { + // HACK: detect a cube map; forces cube compatible textures to be cube textures + match (desc.is_cube_compatible(), desc.size.depth_or_array_layers) { + (false, 1) => (glow::TEXTURE_2D, false, false), + (false, _) => (glow::TEXTURE_2D_ARRAY, true, false), + (true, 6) => (glow::TEXTURE_CUBE_MAP, false, true), + (true, _) => (glow::TEXTURE_CUBE_MAP_ARRAY, true, true), } } - wgt::TextureDimension::D3 => { - copy_size.depth = desc.size.depth_or_array_layers; - (glow::TEXTURE_3D, true, false) - } + wgt::TextureDimension::D3 => (glow::TEXTURE_3D, true, false), } } } diff --git a/wgpu-hal/src/lib.rs b/wgpu-hal/src/lib.rs index b289fdc2e6..9a324b8265 100644 --- a/wgpu-hal/src/lib.rs +++ b/wgpu-hal/src/lib.rs @@ -872,6 +872,26 @@ pub struct TextureDescriptor<'a> { pub view_formats: Vec, } +impl TextureDescriptor<'_> { + pub fn copy_extent(&self) -> CopyExtent { + CopyExtent::map_extent_to_copy_size(&self.size, self.dimension) + } + + pub fn is_cube_compatible(&self) -> bool { + self.dimension == wgt::TextureDimension::D2 + && self.size.depth_or_array_layers % 6 == 0 + && self.sample_count == 1 + && self.size.width == self.size.height + } + + pub fn array_layer_count(&self) -> u32 { + match self.dimension { + wgt::TextureDimension::D1 | wgt::TextureDimension::D3 => 1, + wgt::TextureDimension::D2 => self.size.depth_or_array_layers, + } + } +} + /// TextureView descriptor. /// /// Valid usage: diff --git a/wgpu-hal/src/metal/device.rs b/wgpu-hal/src/metal/device.rs index 59208d8245..fe9399c48e 100644 --- a/wgpu-hal/src/metal/device.rs +++ b/wgpu-hal/src/metal/device.rs @@ -292,21 +292,9 @@ impl crate::Device for super::Device { objc::rc::autoreleasepool(|| { let descriptor = mtl::TextureDescriptor::new(); - let mut array_layers = desc.size.depth_or_array_layers; - let mut copy_size = crate::CopyExtent { - width: desc.size.width, - height: desc.size.height, - depth: 1, - }; + let mtl_type = match desc.dimension { - wgt::TextureDimension::D1 => { - if desc.size.depth_or_array_layers > 1 { - descriptor.set_array_length(desc.size.depth_or_array_layers as u64); - mtl::MTLTextureType::D1Array - } else { - mtl::MTLTextureType::D1 - } - } + wgt::TextureDimension::D1 => mtl::MTLTextureType::D1, wgt::TextureDimension::D2 => { if desc.sample_count > 1 { descriptor.set_sample_count(desc.sample_count as u64); @@ -320,8 +308,6 @@ impl crate::Device for super::Device { } wgt::TextureDimension::D3 => { descriptor.set_depth(desc.size.depth_or_array_layers as u64); - array_layers = 1; - copy_size.depth = desc.size.depth_or_array_layers; mtl::MTLTextureType::D3 } }; @@ -344,8 +330,8 @@ impl crate::Device for super::Device { raw_format: mtl_format, raw_type: mtl_type, mip_levels: desc.mip_level_count, - array_layers, - copy_size, + array_layers: desc.array_layer_count(), + copy_size: desc.copy_extent(), }) }) } @@ -376,14 +362,14 @@ impl crate::Device for super::Device { // Also helps working around Metal bugs with aliased array textures. texture.raw.to_owned() } else { - let mip_level_count = match desc.range.mip_level_count { - Some(count) => count.get(), - None => texture.mip_levels - desc.range.base_mip_level, - }; - let array_layer_count = match desc.range.array_layer_count { - Some(count) => count.get(), - None => texture.array_layers - desc.range.base_array_layer, - }; + let mip_level_count = desc + .range + .mip_level_count + .unwrap_or(texture.mip_levels - desc.range.base_mip_level); + let array_layer_count = desc + .range + .array_layer_count + .unwrap_or(texture.array_layers - desc.range.base_array_layer); objc::rc::autoreleasepool(|| { let raw = texture.raw.new_texture_view_from_slice( diff --git a/wgpu-hal/src/vulkan/conv.rs b/wgpu-hal/src/vulkan/conv.rs index 259fc4cef1..8f6ea217ce 100644 --- a/wgpu-hal/src/vulkan/conv.rs +++ b/wgpu-hal/src/vulkan/conv.rs @@ -1,5 +1,4 @@ use ash::vk; -use std::num::NonZeroU32; impl super::PrivateCapabilities { pub fn map_texture_format(&self, format: wgt::TextureFormat) -> vk::Format { @@ -585,20 +584,6 @@ pub fn map_copy_extent(extent: &crate::CopyExtent) -> vk::Extent3D { } } -pub fn map_extent_to_copy_size( - extent: &wgt::Extent3d, - dim: wgt::TextureDimension, -) -> crate::CopyExtent { - crate::CopyExtent { - width: extent.width, - height: extent.height, - depth: match dim { - wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => 1, - wgt::TextureDimension::D3 => extent.depth_or_array_layers, - }, - } -} - pub fn map_subresource_range( range: &wgt::ImageSubresourceRange, texture_aspect: crate::FormatAspects, @@ -606,13 +591,11 @@ pub fn map_subresource_range( vk::ImageSubresourceRange { aspect_mask: map_aspects(crate::FormatAspects::from(range.aspect) & texture_aspect), base_mip_level: range.base_mip_level, - level_count: range - .mip_level_count - .map_or(vk::REMAINING_MIP_LEVELS, NonZeroU32::get), + level_count: range.mip_level_count.unwrap_or(vk::REMAINING_MIP_LEVELS), base_array_layer: range.base_array_layer, layer_count: range .array_layer_count - .map_or(vk::REMAINING_ARRAY_LAYERS, NonZeroU32::get), + .unwrap_or(vk::REMAINING_ARRAY_LAYERS), } } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 321a7362bc..6c59c97358 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -643,7 +643,7 @@ impl super::Device { aspects: crate::FormatAspects::from(desc.format), format_info: desc.format.describe(), raw_flags: vk::ImageCreateFlags::empty(), - copy_size: crate::CopyExtent::map_extent_to_copy_size(&desc.size, desc.dimension), + copy_size: desc.copy_extent(), } } @@ -900,18 +900,10 @@ impl crate::Device for super::Device { &self, desc: &crate::TextureDescriptor, ) -> Result { - let array_layer_count = match desc.dimension { - wgt::TextureDimension::D3 => 1, - _ => desc.size.depth_or_array_layers, - }; - let copy_size = conv::map_extent_to_copy_size(&desc.size, desc.dimension); + let copy_size = desc.copy_extent(); let mut raw_flags = vk::ImageCreateFlags::empty(); - if desc.dimension == wgt::TextureDimension::D2 - && desc.size.depth_or_array_layers % 6 == 0 - && desc.sample_count == 1 - && desc.size.width == desc.size.height - { + if desc.is_cube_compatible() { raw_flags |= vk::ImageCreateFlags::CUBE_COMPATIBLE; } @@ -937,13 +929,9 @@ impl crate::Device for super::Device { .flags(raw_flags) .image_type(conv::map_texture_dimension(desc.dimension)) .format(original_format) - .extent(vk::Extent3D { - width: copy_size.width, - height: copy_size.height, - depth: copy_size.depth, - }) + .extent(conv::map_copy_extent(©_size)) .mip_levels(desc.mip_level_count) - .array_layers(array_layer_count) + .array_layers(desc.array_layer_count()) .samples(vk::SampleCountFlags::from_raw(desc.sample_count)) .tiling(vk::ImageTiling::OPTIMAL) .usage(conv::map_texture_usage(desc.usage)) diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index bb0e333098..1f4015f5d1 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -10,8 +10,6 @@ use ash::{ vk, }; -use super::conv; - unsafe extern "system" fn debug_utils_messenger_callback( message_severity: vk::DebugUtilsMessageSeverityFlagsEXT, message_type: vk::DebugUtilsMessageTypeFlagsEXT, @@ -794,10 +792,11 @@ impl crate::Surface for super::Surface { aspects: crate::FormatAspects::COLOR, format_info: sc.config.format.describe(), raw_flags: vk::ImageCreateFlags::empty(), - copy_size: conv::map_extent_to_copy_size( - &sc.config.extent, - wgt::TextureDimension::D2, - ), + copy_size: crate::CopyExtent { + width: sc.config.extent.width, + height: sc.config.extent.height, + depth: 1, + }, }, }; Ok(Some(crate::AcquiredSurfaceTexture { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 2fa8f62fee..374f5f35cc 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -749,8 +749,7 @@ pub struct Limits { /// Defaults to 2048. Higher is "better". #[cfg_attr(feature = "serde", serde(rename = "maxTextureDimension3D"))] 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`. + /// Maximum allowed value for the `size.depth_or_array_layers` of a texture created with `TextureDimension::D2`. /// Defaults to 256. 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". @@ -4363,8 +4362,9 @@ impl Extent3d { _ => u32::max(1, self.height >> level), }, depth_or_array_layers: match dim { + TextureDimension::D1 => 1, + TextureDimension::D2 => self.depth_or_array_layers, TextureDimension::D3 => u32::max(1, self.depth_or_array_layers >> level), - _ => self.depth_or_array_layers, }, } } @@ -4504,9 +4504,12 @@ pub struct TextureDescriptor { pub view_formats: V, } -impl TextureDescriptor { +impl TextureDescriptor { /// Takes a closure and maps the label of the texture descriptor into another. - pub fn map_label(&self, fun: impl FnOnce(&L) -> K) -> TextureDescriptor { + pub fn map_label(&self, fun: impl FnOnce(&L) -> K) -> TextureDescriptor + where + V: Clone, + { TextureDescriptor { label: fun(&self.label), size: self.size, @@ -4524,7 +4527,10 @@ impl TextureDescriptor { &self, l_fun: impl FnOnce(&L) -> K, v_fun: impl FnOnce(V) -> M, - ) -> TextureDescriptor { + ) -> TextureDescriptor + where + V: Clone, + { TextureDescriptor { label: l_fun(&self.label), size: self.size, @@ -5372,13 +5378,13 @@ pub struct ImageSubresourceRange { /// Mip level count. /// If `Some(count)`, `base_mip_level + count` must be less or equal to underlying texture mip count. /// If `None`, considered to include the rest of the mipmap levels, but at least 1 in total. - pub mip_level_count: Option, + pub mip_level_count: Option, /// Base array layer. pub base_array_layer: u32, /// Layer count. /// If `Some(count)`, `base_array_layer + count` must be less or equal to the underlying array count. /// If `None`, considered to include the rest of the array layers, but at least 1 in total. - pub array_layer_count: Option, + pub array_layer_count: Option, } impl ImageSubresourceRange { @@ -5387,7 +5393,6 @@ impl ImageSubresourceRange { /// /// ```rust /// # use wgpu_types as wgpu; - /// use std::num::NonZeroU32; /// /// let range_none = wgpu::ImageSubresourceRange { /// aspect: wgpu::TextureAspect::All, @@ -5401,9 +5406,9 @@ impl ImageSubresourceRange { /// let range_some = wgpu::ImageSubresourceRange { /// aspect: wgpu::TextureAspect::All, /// base_mip_level: 0, - /// mip_level_count: NonZeroU32::new(5), + /// mip_level_count: Some(5), /// base_array_layer: 0, - /// array_layer_count: NonZeroU32::new(10), + /// array_layer_count: Some(10), /// }; /// assert_eq!(range_some.is_full_resource(5, 10), true); /// @@ -5411,7 +5416,7 @@ impl ImageSubresourceRange { /// aspect: wgpu::TextureAspect::All, /// base_mip_level: 0, /// // Only partial resource - /// mip_level_count: NonZeroU32::new(3), + /// mip_level_count: Some(3), /// base_array_layer: 0, /// array_layer_count: None, /// }; @@ -5419,8 +5424,8 @@ impl ImageSubresourceRange { /// ``` pub fn is_full_resource(&self, mip_levels: u32, array_layers: u32) -> bool { // Mip level count and array layer count need to deal with both the None and Some(count) case. - let mip_level_count = self.mip_level_count.map_or(mip_levels, NonZeroU32::get); - let array_layer_count = self.array_layer_count.map_or(array_layers, NonZeroU32::get); + let mip_level_count = self.mip_level_count.unwrap_or(mip_levels); + let array_layer_count = self.array_layer_count.unwrap_or(array_layers); let aspect_eq = self.aspect == TextureAspect::All; @@ -5438,24 +5443,18 @@ impl ImageSubresourceRange { } /// Returns the mip level range of a subresource range describes for a specific texture. - pub fn mip_range(&self, texture_desc: &TextureDescriptor) -> Range { + pub fn mip_range(&self, mip_level_count: u32) -> Range { self.base_mip_level..match self.mip_level_count { - Some(mip_level_count) => self.base_mip_level + mip_level_count.get(), - None => texture_desc.mip_level_count, + Some(mip_level_count) => self.base_mip_level + mip_level_count, + None => mip_level_count, } } /// Returns the layer range of a subresource range describes for a specific texture. - pub fn layer_range(&self, texture_desc: &TextureDescriptor) -> Range { + pub fn layer_range(&self, array_layer_count: u32) -> Range { self.base_array_layer..match self.array_layer_count { - Some(array_layer_count) => self.base_array_layer + array_layer_count.get(), - None => { - if texture_desc.dimension == TextureDimension::D3 { - self.base_array_layer + 1 - } else { - texture_desc.size.depth_or_array_layers - } - } + Some(array_layer_count) => self.base_array_layer + array_layer_count, + None => array_layer_count, } } } diff --git a/wgpu/examples/mipmap/main.rs b/wgpu/examples/mipmap/main.rs index d5afa2e2f7..9e3cbdee2b 100644 --- a/wgpu/examples/mipmap/main.rs +++ b/wgpu/examples/mipmap/main.rs @@ -126,7 +126,7 @@ impl Example { dimension: None, aspect: wgpu::TextureAspect::All, base_mip_level: mip, - mip_level_count: NonZeroU32::new(1), + mip_level_count: Some(1), base_array_layer: 0, array_layer_count: None, }) diff --git a/wgpu/examples/shadow/main.rs b/wgpu/examples/shadow/main.rs index 3b1f10d404..e65d44a988 100644 --- a/wgpu/examples/shadow/main.rs +++ b/wgpu/examples/shadow/main.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, f32::consts, iter, mem, num::NonZeroU32, ops::Range, rc::Rc}; +use std::{borrow::Cow, f32::consts, iter, mem, ops::Range, rc::Rc}; #[path = "../framework.rs"] mod framework; @@ -400,7 +400,7 @@ impl framework::Example for Example { base_mip_level: 0, mip_level_count: None, base_array_layer: i as u32, - array_layer_count: NonZeroU32::new(1), + array_layer_count: Some(1), })) }) .collect::>(); diff --git a/wgpu/src/backend/web.rs b/wgpu/src/backend/web.rs index 871bbf166c..fee2819c95 100644 --- a/wgpu/src/backend/web.rs +++ b/wgpu/src/backend/web.rs @@ -1809,11 +1809,11 @@ impl crate::context::Context for Context { mapped.aspect(map_texture_aspect(desc.aspect)); mapped.base_array_layer(desc.base_array_layer); if let Some(count) = desc.array_layer_count { - mapped.array_layer_count(count.get()); + mapped.array_layer_count(count); } mapped.base_mip_level(desc.base_mip_level); if let Some(count) = desc.mip_level_count { - mapped.mip_level_count(count.get()); + mapped.mip_level_count(count); } if let Some(label) = desc.label { mapped.label(label); diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index aa2463e2f3..9fd36fa2c7 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -948,13 +948,13 @@ pub struct TextureViewDescriptor<'a> { /// Mip level count. /// If `Some(count)`, `base_mip_level + count` must be less or equal to underlying texture mip count. /// If `None`, considered to include the rest of the mipmap levels, but at least 1 in total. - pub mip_level_count: Option, + pub mip_level_count: Option, /// Base array layer. pub base_array_layer: u32, /// Layer count. /// If `Some(count)`, `base_array_layer + count` must be less or equal to the underlying array count. /// If `None`, considered to include the rest of the array layers, but at least 1 in total. - pub array_layer_count: Option, + pub array_layer_count: Option, } static_assertions::assert_impl_all!(TextureViewDescriptor: Send, Sync);