diff --git a/wgpu-core/src/command/transfer.rs b/wgpu-core/src/command/transfer.rs index 7b0797fcd..7714b27dd 100644 --- a/wgpu-core/src/command/transfer.rs +++ b/wgpu-core/src/command/transfer.rs @@ -7,9 +7,9 @@ use crate::device::trace::Command as TraceCommand; use crate::{ conv, device::{all_buffer_stages, all_image_stages}, - hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Token}, + hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Storage, Token}, id::{BufferId, CommandEncoderId, TextureId}, - resource::{BufferUse, TextureUse}, + resource::{BufferUse, Texture, TextureUse}, }; use hal::command::CommandBuffer as _; @@ -25,48 +25,50 @@ pub(crate) const BITS_PER_BYTE: u32 = 8; pub struct TextureCopyView { pub texture: TextureId, pub mip_level: u32, - pub array_layer: u32, pub origin: Origin3d, } impl TextureCopyView { //TODO: we currently access each texture twice for a transfer, // once only to get the aspect flags, which is unfortunate. - pub(crate) fn to_selector( + pub(crate) fn to_hal( &self, - aspects: hal::format::Aspects, - ) -> hal::image::SubresourceRange { + texture_guard: &Storage, TextureId>, + ) -> ( + hal::image::SubresourceLayers, + hal::image::SubresourceRange, + hal::image::Offset, + ) { + let texture = &texture_guard[self.texture]; + let aspects = texture.full_range.aspects; let level = self.mip_level as hal::image::Level; - let layer = self.array_layer as hal::image::Layer; + let (layer, z) = match texture.dimension { + wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => { + (self.origin.z as hal::image::Layer, 0) + } + wgt::TextureDimension::D3 => (0, self.origin.z as i32), + }; // TODO: Can't satisfy clippy here unless we modify // `hal::image::SubresourceRange` in gfx to use `std::ops::RangeBounds`. #[allow(clippy::range_plus_one)] - { - hal::image::SubresourceRange { - aspects, - levels: level..level + 1, - layers: layer..layer + 1, - } - } - } - - pub(crate) fn to_sub_layers( - &self, - aspects: hal::format::Aspects, - ) -> hal::image::SubresourceLayers { - let layer = self.array_layer as hal::image::Layer; - // TODO: Can't satisfy clippy here unless we modify - // `hal::image::SubresourceLayers` in gfx to use - // `std::ops::RangeBounds`. - #[allow(clippy::range_plus_one)] - { + ( hal::image::SubresourceLayers { aspects, level: self.mip_level as hal::image::Level, layers: layer..layer + 1, - } - } + }, + hal::image::SubresourceRange { + aspects, + levels: level..level + 1, + layers: layer..layer + 1, + }, + hal::image::Offset { + x: self.origin.x as i32, + y: self.origin.y as i32, + z, + }, + ) } } @@ -154,7 +156,7 @@ impl Global { let cmb = &mut cmb_guard[command_encoder_id]; let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, _) = hub.textures.read(&mut token); - let aspects = texture_guard[destination.texture].full_range.aspects; + let (dst_layers, dst_range, dst_offset) = destination.to_hal(&*texture_guard); #[cfg(feature = "trace")] match cmb.commands { @@ -177,7 +179,7 @@ impl Global { let (dst_texture, dst_pending) = cmb.trackers.textures.use_replace( &*texture_guard, destination.texture, - destination.to_selector(aspects), + dst_range, TextureUse::COPY_DST, ); assert!(dst_texture.usage.contains(TextureUsage::COPY_DST)); @@ -199,9 +201,9 @@ impl Global { buffer_offset: source_layout.offset, buffer_width, buffer_height: source_layout.rows_per_image, - image_layers: destination.to_sub_layers(aspects), - image_offset: conv::map_origin(destination.origin), - image_extent: conv::map_extent(copy_size), + image_layers: dst_layers, + image_offset: dst_offset, + image_extent: conv::map_extent(copy_size, dst_texture.dimension), }; let cmb_raw = cmb.raw.last_mut().unwrap(); unsafe { @@ -233,7 +235,7 @@ impl Global { let cmb = &mut cmb_guard[command_encoder_id]; let (buffer_guard, mut token) = hub.buffers.read(&mut token); let (texture_guard, _) = hub.textures.read(&mut token); - let aspects = texture_guard[source.texture].full_range.aspects; + let (src_layers, src_range, src_offset) = source.to_hal(&*texture_guard); #[cfg(feature = "trace")] match cmb.commands { @@ -249,7 +251,7 @@ impl Global { let (src_texture, src_pending) = cmb.trackers.textures.use_replace( &*texture_guard, source.texture, - source.to_selector(aspects), + src_range, TextureUse::COPY_SRC, ); assert!( @@ -286,9 +288,9 @@ impl Global { buffer_offset: destination_layout.offset, buffer_width, buffer_height: destination_layout.rows_per_image, - image_layers: source.to_sub_layers(aspects), - image_offset: conv::map_origin(source.origin), - image_extent: conv::map_extent(copy_size), + image_layers: src_layers, + image_offset: src_offset, + image_extent: conv::map_extent(copy_size, src_texture.dimension), }; let cmb_raw = cmb.raw.last_mut().unwrap(); unsafe { @@ -323,8 +325,9 @@ impl Global { // we can't hold both src_pending and dst_pending in scope because they // borrow the buffer tracker mutably... let mut barriers = Vec::new(); - let aspects = texture_guard[source.texture].full_range.aspects - & texture_guard[destination.texture].full_range.aspects; + let (src_layers, src_range, src_offset) = source.to_hal(&*texture_guard); + let (dst_layers, dst_range, dst_offset) = destination.to_hal(&*texture_guard); + assert_eq!(src_layers.aspects, dst_layers.aspects); #[cfg(feature = "trace")] match cmb.commands { @@ -339,7 +342,7 @@ impl Global { let (src_texture, src_pending) = cmb.trackers.textures.use_replace( &*texture_guard, source.texture, - source.to_selector(aspects), + src_range, TextureUse::COPY_SRC, ); assert!( @@ -352,7 +355,7 @@ impl Global { let (dst_texture, dst_pending) = cmb.trackers.textures.use_replace( &*texture_guard, destination.texture, - destination.to_selector(aspects), + dst_range, TextureUse::COPY_DST, ); assert!( @@ -362,12 +365,13 @@ impl Global { ); barriers.extend(dst_pending.map(|pending| pending.into_hal(dst_texture))); + assert_eq!(src_texture.dimension, dst_texture.dimension); let region = hal::command::ImageCopy { - src_subresource: source.to_sub_layers(aspects), - src_offset: conv::map_origin(source.origin), - dst_subresource: destination.to_sub_layers(aspects), - dst_offset: conv::map_origin(destination.origin), - extent: conv::map_extent(copy_size), + src_subresource: src_layers, + src_offset, + dst_subresource: dst_layers, + dst_offset, + extent: conv::map_extent(copy_size, src_texture.dimension), }; let cmb_raw = cmb.raw.last_mut().unwrap(); unsafe { diff --git a/wgpu-core/src/conv.rs b/wgpu-core/src/conv.rs index b76d38ac3..f60742a41 100644 --- a/wgpu-core/src/conv.rs +++ b/wgpu-core/src/conv.rs @@ -129,19 +129,14 @@ pub fn map_shader_stage_flags(shader_stage_flags: wgt::ShaderStage) -> hal::pso: value } -pub fn map_origin(origin: wgt::Origin3d) -> hal::image::Offset { - hal::image::Offset { - x: origin.x as i32, - y: origin.y as i32, - z: origin.z as i32, - } -} - -pub fn map_extent(extent: wgt::Extent3d) -> hal::image::Extent { +pub fn map_extent(extent: wgt::Extent3d, dim: wgt::TextureDimension) -> hal::image::Extent { hal::image::Extent { width: extent.width, height: extent.height, - depth: extent.depth, + depth: match dim { + wgt::TextureDimension::D1 | wgt::TextureDimension::D2 => 1, + wgt::TextureDimension::D3 => extent.depth, + }, } } diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 97b419b30..cadf2ab72 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -477,6 +477,7 @@ impl Device { ref_count: self.life_guard.add_ref(), }, usage: desc.usage, + dimension: desc.dimension, kind, format: desc.format, full_range: hal::image::SubresourceRange { diff --git a/wgpu-core/src/device/queue.rs b/wgpu-core/src/device/queue.rs index a9af87aa6..677431001 100644 --- a/wgpu-core/src/device/queue.rs +++ b/wgpu-core/src/device/queue.rs @@ -200,7 +200,7 @@ impl Global { let (mut device_guard, mut token) = hub.devices.write(&mut token); let device = &mut device_guard[queue_id]; let (texture_guard, _) = hub.textures.read(&mut token); - let aspects = texture_guard[destination.texture].full_range.aspects; + let (image_layers, image_range, image_offset) = destination.to_hal(&*texture_guard); #[cfg(feature = "trace")] match device.trace { @@ -223,7 +223,7 @@ impl Global { let (dst, transition) = trackers.textures.use_replace( &*texture_guard, destination.texture, - destination.to_selector(aspects), + image_range, TextureUse::COPY_DST, ); assert!( @@ -251,9 +251,9 @@ impl Global { buffer_offset: 0, buffer_width, buffer_height: data_layout.rows_per_image, - image_layers: destination.to_sub_layers(aspects), - image_offset: conv::map_origin(destination.origin), - image_extent: conv::map_extent(size), + image_layers, + image_offset, + image_extent: conv::map_extent(size, dst.dimension), }; unsafe { stage.comb.pipeline_barrier( diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 227cd1af5..97d686a92 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -170,6 +170,7 @@ pub struct Texture { pub(crate) raw: B::Image, pub(crate) device_id: Stored, pub(crate) usage: TextureUsage, + pub(crate) dimension: wgt::TextureDimension, pub(crate) kind: hal::image::Kind, pub(crate) format: TextureFormat, pub(crate) full_range: hal::image::SubresourceRange,