mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
Remove array layers from texture copies
This commit is contained in:
parent
dff37bb65d
commit
679dba044b
@ -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 {
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user