Change type of mip_level_count and array_layer_count (members of TextureViewDescriptor and ImageSubresourceRange) from Option<NonZeroU32> to Option<u32> (#3445)

Clean up duplicated code related to texture layers/mips.
This commit is contained in:
Teodor Tanasoaia 2023-02-03 15:03:34 +01:00 committed by GitHub
parent 6399dd4866
commit 41de797c74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 168 additions and 269 deletions

View File

@ -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<NonZeroU32>` to `Option<u32>`. By @teoxoy in [#3445](https://github.com/gfx-rs/wgpu/pull/3445)
### Changes
#### WebGPU

View File

@ -73,11 +73,8 @@ pub struct CreateTextureViewArgs {
label: Option<String>,
format: Option<wgpu_types::TextureFormat>,
dimension: Option<wgpu_types::TextureViewDimension>,
aspect: wgpu_types::TextureAspect,
base_mip_level: u32,
mip_level_count: Option<u32>,
base_array_layer: u32,
array_layer_count: Option<u32>,
#[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(

View File

@ -53,14 +53,14 @@ whereas subesource range specified start {subresource_base_mip_level} and count
InvalidTextureLevelRange {
texture_level_range: Range<u32>,
subresource_base_mip_level: u32,
subresource_mip_level_count: Option<NonZeroU32>,
subresource_mip_level_count: Option<u32>,
},
#[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<u32>,
subresource_base_array_layer: u32,
subresource_array_layer_count: Option<NonZeroU32>,
subresource_array_layer_count: Option<u32>,
},
}
@ -188,12 +188,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
};
// 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<G: GlobalIdentityHandlerFactory> Global<G> {
});
}
// 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<G: GlobalIdentityHandlerFactory> Global<G> {
&*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,

View File

@ -191,7 +191,8 @@ pub(crate) fn extract_texture_selector<A: hal::Api>(
}
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<wgt::TextureFormat>>,
@ -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),
};

View File

@ -931,9 +931,9 @@ impl<A: HalApi> Device<A> {
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<A: HalApi> Device<A> {
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<A: HalApi> Device<A> {
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<A: HalApi> Device<A> {
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,
});

View File

@ -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<hal::TextureUses> {
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,
}

View File

@ -384,20 +384,12 @@ impl crate::CommandEncoder<super::Api> 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<super::Api> 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);
}

View File

@ -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,
}
}

View File

@ -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),
}
}
}

View File

@ -101,9 +101,7 @@ impl super::Device {
desc: &crate::TextureDescriptor,
drop_guard: Option<crate::DropGuard>,
) -> 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<crate::DropGuard>,
) -> 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<super::Api> 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<super::Api> 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<super::Api> 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<super::Api> for super::Device {
texture: &super::Texture,
desc: &crate::TextureViewDescriptor,
) -> Result<super::TextureView, crate::DeviceError> {
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,
})
}

View File

@ -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),
}
}
}

View File

@ -872,6 +872,26 @@ pub struct TextureDescriptor<'a> {
pub view_formats: Vec<wgt::TextureFormat>,
}
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:

View File

@ -292,21 +292,9 @@ impl crate::Device<super::Api> 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<super::Api> 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<super::Api> 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<super::Api> 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(

View File

@ -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),
}
}

View File

@ -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<super::Api> for super::Device {
&self,
desc: &crate::TextureDescriptor,
) -> Result<super::Texture, crate::DeviceError> {
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<super::Api> 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(&copy_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))

View File

@ -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<super::Api> 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 {

View File

@ -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<L, V> {
pub view_formats: V,
}
impl<L, V: Clone> TextureDescriptor<L, V> {
impl<L, V> TextureDescriptor<L, V> {
/// Takes a closure and maps the label of the texture descriptor into another.
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> TextureDescriptor<K, V> {
pub fn map_label<K>(&self, fun: impl FnOnce(&L) -> K) -> TextureDescriptor<K, V>
where
V: Clone,
{
TextureDescriptor {
label: fun(&self.label),
size: self.size,
@ -4524,7 +4527,10 @@ impl<L, V: Clone> TextureDescriptor<L, V> {
&self,
l_fun: impl FnOnce(&L) -> K,
v_fun: impl FnOnce(V) -> M,
) -> TextureDescriptor<K, M> {
) -> TextureDescriptor<K, M>
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<NonZeroU32>,
pub mip_level_count: Option<u32>,
/// 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<NonZeroU32>,
pub array_layer_count: Option<u32>,
}
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<L, V>(&self, texture_desc: &TextureDescriptor<L, V>) -> Range<u32> {
pub fn mip_range(&self, mip_level_count: u32) -> Range<u32> {
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<L, V>(&self, texture_desc: &TextureDescriptor<L, V>) -> Range<u32> {
pub fn layer_range(&self, array_layer_count: u32) -> Range<u32> {
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,
}
}
}

View File

@ -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,
})

View File

@ -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::<Vec<_>>();

View File

@ -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);

View File

@ -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<NonZeroU32>,
pub mip_level_count: Option<u32>,
/// 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<NonZeroU32>,
pub array_layer_count: Option<u32>,
}
static_assertions::assert_impl_all!(TextureViewDescriptor: Send, Sync);