1007: Improve cubemap validation r=kvark a=cwfitzgerald

**Connections**

Closes #952.

**Description**

We were missing depth-size and texture dimension validation when creating Cubemap and CubemapArray views.

I split the depth-size errors so I can give a more helpful error message in both cases.

**Testing**

Tested on the skybox example when made intensionally incorrect.

Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
This commit is contained in:
bors[bot]
2020-10-26 03:16:31 +00:00
committed by GitHub
3 changed files with 67 additions and 11 deletions

View File

@@ -27,7 +27,9 @@ use hal::{
};
use parking_lot::{Mutex, MutexGuard};
use thiserror::Error;
use wgt::{BufferAddress, BufferSize, InputStepMode, TextureDimension, TextureFormat};
use wgt::{
BufferAddress, BufferSize, InputStepMode, TextureDimension, TextureFormat, TextureViewDimension,
};
use std::{
borrow::Cow,
@@ -1477,16 +1479,50 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
.ok_or(resource::CreateTextureViewError::InvalidTexture)?;
let device = &device_guard[texture.device_id.value];
let view_kind = match desc.dimension {
Some(dim) => conv::map_texture_view_dimension(dim),
None => match texture.kind {
hal::image::Kind::D1(_, 1) => hal::image::ViewKind::D1,
hal::image::Kind::D1(..) => hal::image::ViewKind::D1Array,
hal::image::Kind::D2(_, _, 1, _) => hal::image::ViewKind::D2,
hal::image::Kind::D2(..) => hal::image::ViewKind::D2Array,
hal::image::Kind::D3(..) => hal::image::ViewKind::D3,
},
};
let view_kind =
match desc.dimension {
Some(dim) => {
use hal::image::Kind;
let required_tex_dim = dim.compatible_texture_dimension();
if required_tex_dim != texture.dimension {
return Err(
resource::CreateTextureViewError::InvalidTextureViewDimension {
view: dim,
image: texture.dimension,
},
);
}
if let Kind::D2(_, _, depth, _) = texture.kind {
match dim {
TextureViewDimension::Cube if depth != 6 => {
return Err(
resource::CreateTextureViewError::InvalidCubemapTextureDepth {
depth,
},
)
}
TextureViewDimension::CubeArray if depth % 6 != 0 => return Err(
resource::CreateTextureViewError::InvalidCubemapArrayTextureDepth {
depth,
},
),
_ => {}
}
}
conv::map_texture_view_dimension(dim)
}
None => match texture.kind {
hal::image::Kind::D1(_, 1) => hal::image::ViewKind::D1,
hal::image::Kind::D1(..) => hal::image::ViewKind::D1Array,
hal::image::Kind::D2(_, _, 1, _) => hal::image::ViewKind::D2,
hal::image::Kind::D2(..) => hal::image::ViewKind::D2Array,
hal::image::Kind::D3(..) => hal::image::ViewKind::D3,
},
};
let required_level_count =
desc.base_mip_level + desc.level_count.map_or(1, |count| count.get());
let required_layer_count =

View File

@@ -317,6 +317,15 @@ pub enum CreateTextureViewError {
InvalidTexture,
#[error("not enough memory left")]
OutOfMemory,
#[error("Invalid texture view dimension `{view:?}` with texture of dimension `{image:?}`")]
InvalidTextureViewDimension {
view: wgt::TextureViewDimension,
image: wgt::TextureDimension,
},
#[error("Invalid texture depth `{depth}` for texture view of dimension `Cubemap`. Cubemap views must use images of size 6.")]
InvalidCubemapTextureDepth { depth: u16 },
#[error("Invalid texture depth `{depth}` for texture view of dimension `CubemapArray`. Cubemap views must use images with sizes which are a multiple of 6.")]
InvalidCubemapArrayTextureDepth { depth: u16 },
#[error(
"TextureView mip level count + base mip level {requested} must be <= Texture mip level count {total}"
)]

View File

@@ -434,6 +434,17 @@ pub enum TextureViewDimension {
D3,
}
impl TextureViewDimension {
/// Get the texture dimension required fo this texture view dimension.
pub fn compatible_texture_dimension(self) -> TextureDimension {
match self {
Self::D1 => TextureDimension::D1,
Self::D2 | Self::D2Array | Self::Cube | Self::CubeArray => TextureDimension::D2,
Self::D3 => TextureDimension::D3,
}
}
}
/// Alpha blend factor.
///
/// Alpha blending is very complicated: see the OpenGL or Vulkan spec for more information.