mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
Limits 1D texture mips to 1
This commit is contained in:
parent
f8a63c4055
commit
01f62baad2
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
@ -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.
|
||||
@ -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)]
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user