Remove array layers from texture copies

This commit is contained in:
Dzmitry Malyshau 2020-05-23 22:25:14 -04:00 committed by Dzmitry Malyshau
parent dff37bb65d
commit 679dba044b
5 changed files with 63 additions and 62 deletions

View File

@ -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<B: hal::Backend>(
&self,
aspects: hal::format::Aspects,
) -> hal::image::SubresourceRange {
texture_guard: &Storage<Texture<B>, 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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
// 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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
);
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 {

View File

@ -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,
},
}
}

View File

@ -477,6 +477,7 @@ impl<B: GfxBackend> Device<B> {
ref_count: self.life_guard.add_ref(),
},
usage: desc.usage,
dimension: desc.dimension,
kind,
format: desc.format,
full_range: hal::image::SubresourceRange {

View File

@ -200,7 +200,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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<G: GlobalIdentityHandlerFactory> Global<G> {
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(

View File

@ -170,6 +170,7 @@ pub struct Texture<B: hal::Backend> {
pub(crate) raw: B::Image,
pub(crate) device_id: Stored<DeviceId>,
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,