diff --git a/CHANGELOG.md b/CHANGELOG.md index 692774ed4d..42e7a686c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -120,6 +120,7 @@ Additionally `Surface::get_default_config` now returns an Option and returns Non #### WebGPU - Implement `queue_validate_write_buffer` by @jinleili in [#3098](https://github.com/gfx-rs/wgpu/pull/3098) +- Sync depth/stencil copy restrictions with the spec by @teoxoy in [#3314](https://github.com/gfx-rs/wgpu/pull/3314) #### GLES diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 063e33a0a0..b8c8cde0bf 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -92,10 +92,16 @@ pub enum TransferError { InvalidRowsPerImage, #[error("source and destination layers have different aspects")] MismatchedAspects, - #[error("copying from textures with format {0:?} is forbidden")] - CopyFromForbiddenTextureFormat(wgt::TextureFormat), - #[error("copying to textures with format {0:?} is forbidden")] - CopyToForbiddenTextureFormat(wgt::TextureFormat), + #[error("copying from textures with format {format:?} and aspect {aspect:?} is forbidden")] + CopyFromForbiddenTextureFormat { + format: wgt::TextureFormat, + aspect: wgt::TextureAspect, + }, + #[error("copying to textures with format {format:?} and aspect {aspect:?} is forbidden")] + CopyToForbiddenTextureFormat { + format: wgt::TextureFormat, + aspect: wgt::TextureAspect, + }, #[error("the entire texture must be copied when copying from depth texture")] InvalidDepthTextureExtent, #[error( @@ -771,10 +777,12 @@ impl Global { true, )?; - if !conv::is_valid_copy_dst_texture_format(dst_texture.desc.format) { - return Err( - TransferError::CopyToForbiddenTextureFormat(dst_texture.desc.format).into(), - ); + if !conv::is_valid_copy_dst_texture_format(dst_texture.desc.format, destination.aspect) { + return Err(TransferError::CopyToForbiddenTextureFormat { + format: dst_texture.desc.format, + aspect: destination.aspect, + } + .into()); } cmd_buf @@ -917,10 +925,12 @@ impl Global { true, )?; - if !conv::is_valid_copy_src_texture_format(src_texture.desc.format) { - return Err( - TransferError::CopyFromForbiddenTextureFormat(src_texture.desc.format).into(), - ); + if !conv::is_valid_copy_src_texture_format(src_texture.desc.format, source.aspect) { + return Err(TransferError::CopyFromForbiddenTextureFormat { + format: src_texture.desc.format, + aspect: source.aspect, + } + .into()); } if format_desc.sample_type == wgt::TextureSampleType::Depth diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index 6a0da9d29a..e83c0b6c79 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -8,23 +8,27 @@ pub fn is_power_of_two_u32(val: u32) -> bool { val != 0 && (val & (val - 1)) == 0 } -pub fn is_valid_copy_src_texture_format(format: wgt::TextureFormat) -> bool { +pub fn is_valid_copy_src_texture_format( + format: wgt::TextureFormat, + aspect: wgt::TextureAspect, +) -> bool { + use wgt::TextureAspect as Ta; use wgt::TextureFormat as Tf; - match format { - Tf::Depth24Plus | Tf::Depth24PlusStencil8 => false, + match (format, aspect) { + (Tf::Depth24Plus, _) | (Tf::Depth24PlusStencil8, Ta::DepthOnly) => false, _ => true, } } -pub fn is_valid_copy_dst_texture_format(format: wgt::TextureFormat) -> bool { +pub fn is_valid_copy_dst_texture_format( + format: wgt::TextureFormat, + aspect: wgt::TextureAspect, +) -> bool { + use wgt::TextureAspect as Ta; use wgt::TextureFormat as Tf; - match format { - //Tf::Stencil8 | - Tf::Depth16Unorm - | Tf::Depth32Float - | Tf::Depth32FloatStencil8 - | Tf::Depth24Plus - | Tf::Depth24PlusStencil8 => false, + match (format, aspect) { + (Tf::Depth24Plus | Tf::Depth32Float, _) + | (Tf::Depth24PlusStencil8 | Tf::Depth32FloatStencil8, Ta::DepthOnly) => false, _ => true, } } diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index ccb6c8838f..ba0fb053da 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -624,8 +624,12 @@ impl Global { false, )?; - if !conv::is_valid_copy_dst_texture_format(texture_format) { - return Err(TransferError::CopyToForbiddenTextureFormat(texture_format).into()); + if !conv::is_valid_copy_dst_texture_format(texture_format, destination.aspect) { + return Err(TransferError::CopyToForbiddenTextureFormat { + format: texture_format, + aspect: destination.aspect, + } + .into()); } let (block_width, block_height) = format_desc.block_dimensions; let width_blocks = size.width / block_width as u32;