Skip to content

Commit

Permalink
Limits 1D texture mips to 1
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Jan 10, 2022
1 parent f8a63c4 commit 01f62ba
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 35 deletions.
8 changes: 6 additions & 2 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,12 @@ impl<A: HalApi> Device<A> {
)?;

let mips = desc.mip_level_count;
if mips == 0 || mips > hal::MAX_MIP_LEVELS || mips > desc.size.max_mips() {
return Err(resource::CreateTextureError::InvalidMipLevelCount(mips));
let max_levels_allowed = desc.size.max_mips(desc.dimension).min(hal::MAX_MIP_LEVELS);
if mips == 0 || mips > max_levels_allowed {
return Err(resource::CreateTextureError::InvalidMipLevelCount {
requested: mips,
maximum: max_levels_allowed,
});
}

// Enforce having COPY_DST/DEPTH_STENCIL_WRIT/COLOR_TARGET otherwise we wouldn't be able to initialize the texture.
Expand Down
8 changes: 5 additions & 3 deletions wgpu-core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,11 @@ pub enum CreateTextureError {
InvalidDimension(#[from] TextureDimensionError),
#[error("Depth texture kind {0:?} of format {0:?} can't be created")]
InvalidDepthKind(wgt::TextureDimension, wgt::TextureFormat),
#[error("texture descriptor mip level count ({0}) is invalid")]
InvalidMipLevelCount(u32),
#[error("The texture usages {0:?} are not allowed on a texture of type {1:?}")]
#[error(
"Texture descriptor mip level count {requested} is invalid, maximum allowed is {maximum}"
)]
InvalidMipLevelCount { requested: u32, maximum: u32 },
#[error("Texture usages {0:?} are not allowed on a texture of type {1:?}")]
InvalidUsages(wgt::TextureUsages, wgt::TextureFormat),
#[error("Texture format {0:?} can't be used")]
MissingFeatures(wgt::TextureFormat, #[source] MissingFeatures),
Expand Down
139 changes: 110 additions & 29 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2848,25 +2848,6 @@ impl Extent3d {
///
/// This is the texture extent that you must upload at when uploading to _mipmaps_ of compressed textures.
///
/// ```rust
/// # use wgpu_types as wgpu;
/// let format = wgpu::TextureFormat::Bc1RgbaUnormSrgb; // 4x4 blocks
/// assert_eq!(
/// 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_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_or_array_layers: 1 }.physical_size(format),
/// wgpu::Extent3d { width: 8, height: 10, depth_or_array_layers: 1 }
/// );
/// ```
///
/// [physical size]: https://gpuweb.github.io/gpuweb/#physical-size
pub fn physical_size(&self, format: TextureFormat) -> Self {
let (block_width, block_height) = format.describe().block_dimensions;
Expand All @@ -2887,16 +2868,18 @@ impl Extent3d {
///
/// Treats the depth as part of the mipmaps. If calculating
/// for a 2DArray texture, which does not mipmap depth, set depth to 1.
///
/// ```rust
/// # use wgpu_types as wgpu;
/// 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) -> u32 {
let max_dim = self.width.max(self.height.max(self.depth_or_array_layers));
32 - max_dim.leading_zeros()
pub fn max_mips(&self, dim: TextureDimension) -> u32 {
match dim {
TextureDimension::D1 => 1,
TextureDimension::D2 => {
let max_dim = self.width.max(self.height);
32 - max_dim.leading_zeros()
}
TextureDimension::D3 => {
let max_dim = self.width.max(self.height.max(self.depth_or_array_layers));
32 - max_dim.leading_zeros()
}
}
}

/// Calculates the extent at a given mip level.
Expand All @@ -2913,6 +2896,104 @@ impl Extent3d {
}
}

#[test]
fn test_physical_size() {
let format = TextureFormat::Bc1RgbaUnormSrgb; // 4x4 blocks
assert_eq!(
Extent3d {
width: 7,
height: 7,
depth_or_array_layers: 1
}
.physical_size(format),
Extent3d {
width: 8,
height: 8,
depth_or_array_layers: 1
}
);
// Doesn't change, already aligned
assert_eq!(
Extent3d {
width: 8,
height: 8,
depth_or_array_layers: 1
}
.physical_size(format),
Extent3d {
width: 8,
height: 8,
depth_or_array_layers: 1
}
);
let format = TextureFormat::Astc8x5RgbaUnorm; // 8x5 blocks
assert_eq!(
Extent3d {
width: 7,
height: 7,
depth_or_array_layers: 1
}
.physical_size(format),
Extent3d {
width: 8,
height: 10,
depth_or_array_layers: 1
}
);
}

#[test]
fn test_max_mips() {
// 1D
assert_eq!(
Extent3d {
width: 240,
height: 1,
depth_or_array_layers: 1
}
.max_mips(TextureDimension::D1),
1
);
// 2D
assert_eq!(
Extent3d {
width: 1,
height: 1,
depth_or_array_layers: 1
}
.max_mips(TextureDimension::D2),
1
);
assert_eq!(
Extent3d {
width: 60,
height: 60,
depth_or_array_layers: 1
}
.max_mips(TextureDimension::D2),
6
);
assert_eq!(
Extent3d {
width: 240,
height: 1,
depth_or_array_layers: 1000
}
.max_mips(TextureDimension::D2),
8
);
// 3D
assert_eq!(
Extent3d {
width: 16,
height: 30,
depth_or_array_layers: 60
}
.max_mips(TextureDimension::D3),
6
);
}

/// Describes a [`Texture`].
#[repr(C)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
Expand Down
2 changes: 1 addition & 1 deletion wgpu/examples/skybox/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ impl framework::Example for Skybox {
depth_or_array_layers: 1,
..size
};
let max_mips = layer_size.max_mips();
let max_mips = layer_size.max_mips(wgpu::TextureDimension::D2);

log::debug!(
"Copying {:?} skybox images of size {}, {}, 6 with {} mips to gpu",
Expand Down

0 comments on commit 01f62ba

Please sign in to comment.