From 4e6f1a8e40f474d6fe43742ded1577c96d1fa654 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Wed, 29 Dec 2021 19:35:56 -0500 Subject: [PATCH] Improve detection and validation of cubemap views --- wgpu-core/src/device/mod.rs | 18 +++++++++++++++--- wgpu-core/src/resource.rs | 6 ++++-- wgpu-hal/src/gles/device.rs | 1 + wgpu-hal/src/vulkan/device.rs | 6 +++++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index f2f86fbcda..0e7f3b4dbe 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -637,11 +637,14 @@ impl Device { ) -> Result, resource::CreateTextureError> { let format_desc = desc.format.describe(); - // Depth volume textures can't be written to - depth forbids COPY_DST and volume textures can't be rendered to - therefore they aren't allowed. + // Depth textures can only be 2D if format_desc.sample_type == wgt::TextureSampleType::Depth - && desc.dimension == wgt::TextureDimension::D3 + && desc.dimension != wgt::TextureDimension::D2 { - return Err(resource::CreateTextureError::CannotCreateDepthVolumeTexture(desc.format)); + return Err(resource::CreateTextureError::InvalidDepthKind( + desc.dimension, + desc.format, + )); } let format_features = self @@ -779,6 +782,7 @@ impl Device { let view_dim = match desc.dimension { Some(dim) => { + // check if the dimension is compatible with the texture if texture.desc.dimension != dim.compatible_texture_dimension() { return Err( resource::CreateTextureViewError::InvalidTextureViewDimension { @@ -787,6 +791,14 @@ impl Device { }, ); } + // check if multisampled texture is seen as anything but 2D + match dim { + wgt::TextureViewDimension::D2 | wgt::TextureViewDimension::D2Array => {} + _ if texture.desc.sample_count > 1 => { + return Err(resource::CreateTextureViewError::InvalidMultisampledTextureViewDimension(dim)); + } + _ => {} + } dim } None => match texture.desc.dimension { diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 6c3085f17d..77df1f1a84 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -295,12 +295,12 @@ pub enum TextureDimensionError { pub enum CreateTextureError { #[error(transparent)] Device(#[from] DeviceError), - #[error("Depth Texture format {0:?} can't be used for volume textures")] - CannotCreateDepthVolumeTexture(wgt::TextureFormat), #[error("Textures cannot have empty usage flags")] EmptyUsage, #[error(transparent)] 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:?}")] @@ -382,6 +382,8 @@ pub enum CreateTextureViewError { view: wgt::TextureViewDimension, texture: wgt::TextureDimension, }, + #[error("Invalid texture view dimension `{0:?}` of a multisampled texture")] + InvalidMultisampledTextureViewDimension(wgt::TextureViewDimension), #[error("Invalid texture depth `{depth}` for texture view of dimension `Cubemap`. Cubemap views must use images of size 6.")] InvalidCubemapTextureDepth { depth: u32 }, #[error("Invalid texture depth `{depth}` for texture view of dimension `CubemapArray`. Cubemap views must use images with sizes which are a multiple of 6.")] diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 722041048a..00b7f3cdf8 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -563,6 +563,7 @@ impl crate::Device for super::Device { //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 { diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index fd1b49853c..0d58864287 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -806,7 +806,11 @@ impl crate::Device for super::Device { let copy_size = conv::map_extent_to_copy_size(&desc.size, desc.dimension); let mut raw_flags = vk::ImageCreateFlags::empty(); - if desc.dimension == wgt::TextureDimension::D2 && desc.size.depth_or_array_layers % 6 == 0 { + if desc.dimension == wgt::TextureDimension::D2 + && desc.size.depth_or_array_layers % 6 == 0 + && desc.sample_count == 1 + && desc.size.width == desc.size.height + { raw_flags |= vk::ImageCreateFlags::CUBE_COMPATIBLE; }