mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Stop using render pass boundary usages for resource transitions
This commit is contained in:
@@ -15,6 +15,7 @@ use crate::{
|
||||
memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction},
|
||||
pipeline::PipelineFlags,
|
||||
resource::{Texture, TextureView, TextureViewSource},
|
||||
swap_chain::SwapChain,
|
||||
track::{StatefulTrackerSubset, TextureSelector, UsageConflict},
|
||||
validation::{
|
||||
check_buffer_usage, check_texture_usage, MissingBufferUsageError, MissingTextureUsageError,
|
||||
@@ -491,11 +492,11 @@ where
|
||||
struct RenderAttachment<'a> {
|
||||
texture_id: &'a Stored<id::TextureId>,
|
||||
selector: &'a TextureSelector,
|
||||
previous_use: Option<hal::TextureUses>,
|
||||
new_use: hal::TextureUses,
|
||||
usage: hal::TextureUses,
|
||||
}
|
||||
|
||||
type AttachmentDataVec<T> = ArrayVec<T, { hal::MAX_COLOR_TARGETS + hal::MAX_COLOR_TARGETS + 1 }>;
|
||||
const MAX_TOTAL_ATTACHMENTS: usize = hal::MAX_COLOR_TARGETS + hal::MAX_COLOR_TARGETS + 1;
|
||||
type AttachmentDataVec<T> = ArrayVec<T, MAX_TOTAL_ATTACHMENTS>;
|
||||
|
||||
struct RenderPassInfo<'a, A: hal::Api> {
|
||||
context: RenderPassContext,
|
||||
@@ -514,6 +515,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
depth_stencil_attachment: Option<&RenderPassDepthStencilAttachment>,
|
||||
cmd_buf: &mut CommandBuffer<A>,
|
||||
view_guard: &'a Storage<TextureView<A>, id::TextureViewId>,
|
||||
swap_chain_guard: &'a Storage<SwapChain<A>, id::SwapChainId>,
|
||||
) -> Result<Self, RenderPassErrorInner> {
|
||||
profiling::scope!("start", "RenderPassInfo");
|
||||
|
||||
@@ -527,7 +529,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
let mut attachment_type_name = "";
|
||||
let mut extent = None;
|
||||
let mut sample_count = 0;
|
||||
let mut used_swap_chain = None::<Stored<id::SwapChainId>>;
|
||||
let mut used_swap_chain = None::<(Stored<id::SwapChainId>, hal::TextureUses)>;
|
||||
|
||||
let mut add_view = |view: &TextureView<A>, type_name| {
|
||||
if let Some(ex) = extent {
|
||||
@@ -577,12 +579,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
}
|
||||
};
|
||||
|
||||
// Using render pass for transition.
|
||||
let previous_use = cmd_buf
|
||||
.trackers
|
||||
.textures
|
||||
.query(source_id.value, view.selector.clone());
|
||||
let new_use = if at.is_read_only(ds_aspects)? {
|
||||
let usage = if at.is_read_only(ds_aspects)? {
|
||||
is_ds_read_only = true;
|
||||
hal::TextureUses::DEPTH_STENCIL_READ | hal::TextureUses::SAMPLED
|
||||
} else {
|
||||
@@ -591,16 +588,13 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
render_attachments.push(RenderAttachment {
|
||||
texture_id: source_id,
|
||||
selector: &view.selector,
|
||||
previous_use,
|
||||
new_use,
|
||||
usage,
|
||||
});
|
||||
|
||||
let old_use = previous_use.unwrap_or(new_use);
|
||||
depth_stencil = Some(hal::DepthStencilAttachment {
|
||||
target: hal::Attachment {
|
||||
view: &view.raw,
|
||||
usage: new_use,
|
||||
boundary_usage: old_use..new_use,
|
||||
usage,
|
||||
},
|
||||
depth_ops: at.depth.hal_ops(),
|
||||
stencil_ops: at.stencil.hal_ops(),
|
||||
@@ -626,33 +620,22 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
));
|
||||
}
|
||||
|
||||
let boundary_usage = match color_view.source {
|
||||
match color_view.source {
|
||||
TextureViewSource::Native(ref source_id) => {
|
||||
let previous_use = cmd_buf
|
||||
.trackers
|
||||
.textures
|
||||
.query(source_id.value, color_view.selector.clone());
|
||||
let new_use = hal::TextureUses::COLOR_TARGET;
|
||||
render_attachments.push(RenderAttachment {
|
||||
texture_id: source_id,
|
||||
selector: &color_view.selector,
|
||||
previous_use,
|
||||
new_use,
|
||||
usage: hal::TextureUses::COLOR_TARGET,
|
||||
});
|
||||
|
||||
let old_use = previous_use.unwrap_or(new_use);
|
||||
old_use..new_use
|
||||
}
|
||||
TextureViewSource::SwapChain(ref source_id) => {
|
||||
assert!(used_swap_chain.is_none());
|
||||
used_swap_chain = Some(source_id.clone());
|
||||
|
||||
let end = hal::TextureUses::empty();
|
||||
let start = match at.channel.load_op {
|
||||
//HACK: guess the start usage based on the load op
|
||||
let start_usage = match at.channel.load_op {
|
||||
LoadOp::Load => hal::TextureUses::empty(),
|
||||
LoadOp::Clear => hal::TextureUses::UNINITIALIZED,
|
||||
LoadOp::Load => end,
|
||||
};
|
||||
start..end
|
||||
assert!(used_swap_chain.is_none());
|
||||
used_swap_chain = Some((source_id.clone(), start_usage));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -676,34 +659,25 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
return Err(RenderPassErrorInner::InvalidResolveTargetSampleCount);
|
||||
}
|
||||
|
||||
let boundary_usage = match resolve_view.source {
|
||||
match resolve_view.source {
|
||||
TextureViewSource::Native(ref source_id) => {
|
||||
let previous_use = cmd_buf
|
||||
.trackers
|
||||
.textures
|
||||
.query(source_id.value, resolve_view.selector.clone());
|
||||
let new_use = hal::TextureUses::COLOR_TARGET;
|
||||
render_attachments.push(RenderAttachment {
|
||||
texture_id: source_id,
|
||||
selector: &resolve_view.selector,
|
||||
previous_use,
|
||||
new_use,
|
||||
usage: hal::TextureUses::COLOR_TARGET,
|
||||
});
|
||||
|
||||
let old_use = previous_use.unwrap_or(new_use);
|
||||
old_use..new_use
|
||||
}
|
||||
TextureViewSource::SwapChain(ref source_id) => {
|
||||
//HACK: guess the start usage
|
||||
let start_usage = hal::TextureUses::UNINITIALIZED;
|
||||
assert!(used_swap_chain.is_none());
|
||||
used_swap_chain = Some(source_id.clone());
|
||||
hal::TextureUses::UNINITIALIZED..hal::TextureUses::empty()
|
||||
used_swap_chain = Some((source_id.clone(), start_usage));
|
||||
}
|
||||
};
|
||||
|
||||
hal_resolve_target = Some(hal::Attachment {
|
||||
view: &resolve_view.raw,
|
||||
usage: hal::TextureUses::COLOR_TARGET,
|
||||
boundary_usage,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -711,7 +685,6 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
target: hal::Attachment {
|
||||
view: &color_view.raw,
|
||||
usage: hal::TextureUses::COLOR_TARGET,
|
||||
boundary_usage,
|
||||
},
|
||||
resolve_target: hal_resolve_target,
|
||||
ops: at.channel.hal_ops(),
|
||||
@@ -723,6 +696,21 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
return Err(RenderPassErrorInner::InvalidSampleCount(sample_count));
|
||||
}
|
||||
|
||||
if let Some((ref sc_id, start_usage)) = used_swap_chain {
|
||||
let &(_, ref suf_texture) = swap_chain_guard[sc_id.value]
|
||||
.acquired_texture
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let barrier = hal::TextureBarrier {
|
||||
texture: std::borrow::Borrow::borrow(suf_texture),
|
||||
usage: start_usage..hal::TextureUses::COLOR_TARGET,
|
||||
range: wgt::ImageSubresourceRange::default(),
|
||||
};
|
||||
unsafe {
|
||||
cmd_buf.encoder.raw.transition_textures(iter::once(barrier));
|
||||
}
|
||||
}
|
||||
|
||||
let view_data = AttachmentData {
|
||||
colors: color_attachments
|
||||
.iter()
|
||||
@@ -756,7 +744,7 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
context,
|
||||
trackers: StatefulTrackerSubset::new(A::VARIANT),
|
||||
render_attachments,
|
||||
used_swap_chain,
|
||||
used_swap_chain: used_swap_chain.map(|(sc_id, _)| sc_id),
|
||||
is_ds_read_only,
|
||||
extent,
|
||||
_phantom: PhantomData,
|
||||
@@ -767,9 +755,28 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
mut self,
|
||||
raw: &mut A::CommandEncoder,
|
||||
texture_guard: &Storage<Texture<A>, id::TextureId>,
|
||||
swap_chain_guard: &Storage<SwapChain<A>, id::SwapChainId>,
|
||||
) -> Result<(StatefulTrackerSubset, Option<Stored<id::SwapChainId>>), RenderPassErrorInner>
|
||||
{
|
||||
profiling::scope!("finish", "RenderPassInfo");
|
||||
unsafe {
|
||||
raw.end_render_pass();
|
||||
}
|
||||
|
||||
if let Some(ref sc_id) = self.used_swap_chain {
|
||||
let &(_, ref suf_texture) = swap_chain_guard[sc_id.value]
|
||||
.acquired_texture
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let barrier = hal::TextureBarrier {
|
||||
texture: std::borrow::Borrow::borrow(suf_texture),
|
||||
usage: hal::TextureUses::COLOR_TARGET..hal::TextureUses::empty(),
|
||||
range: wgt::ImageSubresourceRange::default(),
|
||||
};
|
||||
unsafe {
|
||||
raw.transition_textures(iter::once(barrier));
|
||||
}
|
||||
}
|
||||
|
||||
for ra in self.render_attachments {
|
||||
let texture = &texture_guard[ra.texture_id.value];
|
||||
@@ -782,29 +789,11 @@ impl<'a, A: HalApi> RenderPassInfo<'a, A> {
|
||||
ra.texture_id.value,
|
||||
&ra.texture_id.ref_count,
|
||||
ra.selector.clone(),
|
||||
ra.new_use,
|
||||
ra.usage,
|
||||
)
|
||||
.map_err(UsageConflict::from)?;
|
||||
|
||||
if let Some(usage) = ra.previous_use {
|
||||
// Make the attachment tracks to be aware of the internal
|
||||
// transition done by the render pass, by registering the
|
||||
// previous usage as the initial state.
|
||||
self.trackers
|
||||
.textures
|
||||
.prepend(
|
||||
ra.texture_id.value,
|
||||
&ra.texture_id.ref_count,
|
||||
ra.selector.clone(),
|
||||
usage,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
raw.end_render_pass();
|
||||
}
|
||||
Ok((self.trackers, self.used_swap_chain))
|
||||
}
|
||||
}
|
||||
@@ -842,7 +831,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
|
||||
let (pass_raw, trackers, query_reset_state) = {
|
||||
// read-only lock guard
|
||||
let (swap_chain_guard, mut token) = hub.swap_chains.read(&mut token);
|
||||
let (mut cmb_guard, mut token) = hub.command_buffers.write(&mut token);
|
||||
|
||||
let cmd_buf =
|
||||
@@ -886,6 +875,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
depth_stencil_attachment,
|
||||
cmd_buf,
|
||||
&*view_guard,
|
||||
&*swap_chain_guard,
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
@@ -1744,8 +1734,10 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
}
|
||||
|
||||
log::trace!("Merging {:?} with the render pass", encoder_id);
|
||||
let (trackers, used_swapchain) =
|
||||
info.finish(raw, &*texture_guard).map_pass_err(scope)?;
|
||||
let (trackers, used_swapchain) = info
|
||||
.finish(raw, &*texture_guard, &*swap_chain_guard)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
let raw_cmd_buf = unsafe {
|
||||
raw.end_encoding()
|
||||
.map_err(|_| RenderPassErrorInner::OutOfMemory)
|
||||
|
||||
@@ -75,25 +75,6 @@ impl ResourceState for BufferState {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepend(
|
||||
&mut self,
|
||||
id: Valid<Self::Id>,
|
||||
_selector: Self::Selector,
|
||||
usage: Self::Usage,
|
||||
) -> Result<(), PendingTransition<Self>> {
|
||||
match self.first {
|
||||
Some(old) if old != usage => Err(PendingTransition {
|
||||
id,
|
||||
selector: (),
|
||||
usage: old..usage,
|
||||
}),
|
||||
_ => {
|
||||
self.first = Some(usage);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn merge(
|
||||
&mut self,
|
||||
id: Valid<Self::Id>,
|
||||
@@ -205,30 +186,4 @@ mod test {
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prepend() {
|
||||
let mut bs = Unit {
|
||||
first: None,
|
||||
last: BufferUses::VERTEX,
|
||||
};
|
||||
let id = Id::dummy();
|
||||
bs.prepend(id, (), BufferUses::INDEX).unwrap();
|
||||
bs.prepend(id, (), BufferUses::INDEX).unwrap();
|
||||
assert_eq!(
|
||||
bs.prepend(id, (), BufferUses::STORAGE_LOAD),
|
||||
Err(PendingTransition {
|
||||
id,
|
||||
selector: (),
|
||||
usage: BufferUses::INDEX..BufferUses::STORAGE_LOAD,
|
||||
})
|
||||
);
|
||||
assert_eq!(
|
||||
bs,
|
||||
Unit {
|
||||
first: Some(BufferUses::INDEX),
|
||||
last: BufferUses::VERTEX,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,14 +76,6 @@ pub(crate) trait ResourceState: Clone + Default {
|
||||
output: Option<&mut Vec<PendingTransition<Self>>>,
|
||||
) -> Result<(), PendingTransition<Self>>;
|
||||
|
||||
/// Sets up the first usage of the selected sub-resources.
|
||||
fn prepend(
|
||||
&mut self,
|
||||
id: Valid<Self::Id>,
|
||||
selector: Self::Selector,
|
||||
usage: Self::Usage,
|
||||
) -> Result<(), PendingTransition<Self>>;
|
||||
|
||||
/// Merge the state of this resource tracked by a different instance
|
||||
/// with the current one.
|
||||
///
|
||||
@@ -309,6 +301,7 @@ impl<S: ResourceState> ResourceTracker<S> {
|
||||
///
|
||||
/// Returns `Some(Usage)` only if this usage is consistent
|
||||
/// across the given selector.
|
||||
#[allow(unused)] // TODO: figure out if this needs to be removed
|
||||
pub fn query(&self, id: Valid<S::Id>, selector: S::Selector) -> Option<S::Usage> {
|
||||
let (index, epoch, backend) = id.0.unzip();
|
||||
debug_assert_eq!(backend, self.backend);
|
||||
@@ -397,21 +390,6 @@ impl<S: ResourceState> ResourceTracker<S> {
|
||||
self.temp.drain(..)
|
||||
}
|
||||
|
||||
/// Turn the tracking from the "expand" mode into the "replace" one,
|
||||
/// installing the selected usage as the "first".
|
||||
/// This is a special operation only used by the render pass attachments.
|
||||
pub(crate) fn prepend(
|
||||
&mut self,
|
||||
id: Valid<S::Id>,
|
||||
ref_count: &RefCount,
|
||||
selector: S::Selector,
|
||||
usage: S::Usage,
|
||||
) -> Result<(), PendingTransition<S>> {
|
||||
Self::get_or_insert(self.backend, &mut self.map, id, ref_count)
|
||||
.state
|
||||
.prepend(id, selector, usage)
|
||||
}
|
||||
|
||||
/// Merge another tracker into `self` by extending the current states
|
||||
/// without any transitions.
|
||||
pub(crate) fn merge_extend(&mut self, other: &Self) -> Result<(), PendingTransition<S>> {
|
||||
@@ -528,15 +506,6 @@ impl<I: Copy + fmt::Debug + TypedId> ResourceState for PhantomData<I> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepend(
|
||||
&mut self,
|
||||
_id: Valid<Self::Id>,
|
||||
_selector: Self::Selector,
|
||||
_usage: Self::Usage,
|
||||
) -> Result<(), PendingTransition<Self>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn merge(
|
||||
&mut self,
|
||||
_id: Valid<Self::Id>,
|
||||
|
||||
@@ -136,40 +136,6 @@ impl ResourceState for TextureState {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prepend(
|
||||
&mut self,
|
||||
id: Valid<Self::Id>,
|
||||
selector: Self::Selector,
|
||||
usage: Self::Usage,
|
||||
) -> Result<(), PendingTransition<Self>> {
|
||||
assert!(self.mips.len() >= selector.levels.end as usize);
|
||||
for (mip_id, mip) in self.mips[selector.levels.start as usize..selector.levels.end as usize]
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
{
|
||||
let level = selector.levels.start + mip_id as u32;
|
||||
let layers = mip.isolate(&selector.layers, Unit::new(usage));
|
||||
for &mut (ref range, ref mut unit) in layers {
|
||||
match unit.first {
|
||||
Some(old) if old != usage => {
|
||||
return Err(PendingTransition {
|
||||
id,
|
||||
selector: TextureSelector {
|
||||
levels: level..level + 1,
|
||||
layers: range.clone(),
|
||||
},
|
||||
usage: old..usage,
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
unit.first = Some(usage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn merge(
|
||||
&mut self,
|
||||
id: Valid<Self::Id>,
|
||||
|
||||
@@ -593,11 +593,18 @@ impl<A: hal::Api> Example<A> {
|
||||
|
||||
let ctx = &mut self.contexts[self.context_index];
|
||||
|
||||
let surface_tex = unsafe { self.surface.acquire_texture(!0).unwrap().unwrap().texture };
|
||||
|
||||
let target_barrier0 = hal::TextureBarrier {
|
||||
texture: surface_tex.borrow(),
|
||||
range: wgt::ImageSubresourceRange::default(),
|
||||
usage: hal::TextureUses::UNINITIALIZED..hal::TextureUses::COLOR_TARGET,
|
||||
};
|
||||
unsafe {
|
||||
ctx.encoder.begin_encoding(Some("frame")).unwrap();
|
||||
ctx.encoder.transition_textures(iter::once(target_barrier0));
|
||||
}
|
||||
|
||||
let surface_tex = unsafe { self.surface.acquire_texture(!0).unwrap().unwrap().texture };
|
||||
let surface_view_desc = hal::TextureViewDescriptor {
|
||||
label: None,
|
||||
format: self.surface_format,
|
||||
@@ -622,7 +629,6 @@ impl<A: hal::Api> Example<A> {
|
||||
target: hal::Attachment {
|
||||
view: &surface_tex_view,
|
||||
usage: hal::TextureUses::COLOR_TARGET,
|
||||
boundary_usage: hal::TextureUses::UNINITIALIZED..hal::TextureUses::empty(),
|
||||
},
|
||||
resolve_target: None,
|
||||
ops: hal::AttachmentOps::STORE,
|
||||
@@ -655,8 +661,17 @@ impl<A: hal::Api> Example<A> {
|
||||
ctx.frames_recorded += 1;
|
||||
let do_fence = ctx.frames_recorded > COMMAND_BUFFER_PER_CONTEXT;
|
||||
|
||||
let target_barrier1 = hal::TextureBarrier {
|
||||
texture: surface_tex.borrow(),
|
||||
range: wgt::ImageSubresourceRange::default(),
|
||||
usage: hal::TextureUses::COLOR_TARGET..hal::TextureUses::empty(),
|
||||
};
|
||||
unsafe {
|
||||
ctx.encoder.end_render_pass();
|
||||
ctx.encoder.transition_textures(iter::once(target_barrier1));
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let cmd_buf = ctx.encoder.end_encoding().unwrap();
|
||||
let fence_param = if do_fence {
|
||||
Some((&mut ctx.fence, ctx.fence_value))
|
||||
|
||||
@@ -349,7 +349,7 @@ pub struct PipelineLayout {
|
||||
total_slots: u32,
|
||||
// Storing for each associated bind group, which tables we created
|
||||
// in the root signature. This is required for binding descriptor sets.
|
||||
elements: arrayvec::ArrayVec<[RootElement; crate::MAX_BIND_GROUPS]>,
|
||||
elements: arrayvec::ArrayVec<RootElement, crate::MAX_BIND_GROUPS>,
|
||||
}
|
||||
|
||||
unsafe impl Send for PipelineLayout {}
|
||||
|
||||
@@ -1044,13 +1044,9 @@ pub struct BufferTextureCopy {
|
||||
#[derive(Debug)]
|
||||
pub struct Attachment<'a, A: Api> {
|
||||
pub view: &'a A::TextureView,
|
||||
/// Contains either a single mutating usage as a target, or a valid combination
|
||||
/// of read-only usages.
|
||||
/// Contains either a single mutating usage as a target,
|
||||
/// or a valid combination of read-only usages.
|
||||
pub usage: TextureUses,
|
||||
/// Defines the boundary usages for the attachment.
|
||||
/// It is expected to begin a render pass with `boundary_usage.start` usage,
|
||||
/// and will end it with `boundary_usage.end` usage.
|
||||
pub boundary_usage: Range<TextureUses>,
|
||||
}
|
||||
|
||||
// Rust gets confused about the impl requirements for `A`
|
||||
@@ -1059,7 +1055,6 @@ impl<A: Api> Clone for Attachment<'_, A> {
|
||||
Self {
|
||||
view: self.view,
|
||||
usage: self.usage,
|
||||
boundary_usage: self.boundary_usage.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,9 +119,7 @@ impl crate::Attachment<'_, super::Api> {
|
||||
let aspects = self.view.aspects();
|
||||
super::AttachmentKey {
|
||||
format: caps.map_texture_format(self.view.attachment.view_format),
|
||||
layout_pre: derive_image_layout(self.boundary_usage.start, aspects),
|
||||
layout_in: derive_image_layout(self.usage, aspects),
|
||||
layout_post: derive_image_layout(self.boundary_usage.end, aspects),
|
||||
layout: derive_image_layout(self.usage, aspects),
|
||||
ops,
|
||||
}
|
||||
}
|
||||
@@ -250,7 +248,7 @@ pub fn map_texture_usage_to_barrier(
|
||||
access |= vk::AccessFlags::SHADER_WRITE;
|
||||
}
|
||||
|
||||
if usage == crate::TextureUses::UNINITIALIZED {
|
||||
if usage == crate::TextureUses::UNINITIALIZED || usage.is_empty() {
|
||||
(
|
||||
vk::PipelineStageFlags::TOP_OF_PIPE,
|
||||
vk::AccessFlags::empty(),
|
||||
|
||||
@@ -74,7 +74,7 @@ impl super::DeviceShared {
|
||||
for cat in e.key().colors.iter() {
|
||||
color_refs.push(vk::AttachmentReference {
|
||||
attachment: vk_attachments.len() as u32,
|
||||
layout: cat.base.layout_in,
|
||||
layout: cat.base.layout,
|
||||
});
|
||||
vk_attachments.push({
|
||||
let (load_op, store_op) = conv::map_attachment_ops(cat.base.ops);
|
||||
@@ -83,14 +83,14 @@ impl super::DeviceShared {
|
||||
.samples(samples)
|
||||
.load_op(load_op)
|
||||
.store_op(store_op)
|
||||
.initial_layout(cat.base.layout_pre)
|
||||
.final_layout(cat.base.layout_post)
|
||||
.initial_layout(cat.base.layout)
|
||||
.final_layout(cat.base.layout)
|
||||
.build()
|
||||
});
|
||||
let at_ref = if let Some(ref rat) = cat.resolve {
|
||||
let at_ref = vk::AttachmentReference {
|
||||
attachment: vk_attachments.len() as u32,
|
||||
layout: rat.layout_in,
|
||||
layout: rat.layout,
|
||||
};
|
||||
let (load_op, store_op) = conv::map_attachment_ops(rat.ops);
|
||||
let vk_attachment = vk::AttachmentDescription::builder()
|
||||
@@ -98,8 +98,8 @@ impl super::DeviceShared {
|
||||
.samples(vk::SampleCountFlags::TYPE_1)
|
||||
.load_op(load_op)
|
||||
.store_op(store_op)
|
||||
.initial_layout(rat.layout_pre)
|
||||
.final_layout(rat.layout_post)
|
||||
.initial_layout(rat.layout)
|
||||
.final_layout(rat.layout)
|
||||
.build();
|
||||
vk_attachments.push(vk_attachment);
|
||||
at_ref
|
||||
@@ -115,7 +115,7 @@ impl super::DeviceShared {
|
||||
if let Some(ref ds) = e.key().depth_stencil {
|
||||
ds_ref = Some(vk::AttachmentReference {
|
||||
attachment: vk_attachments.len() as u32,
|
||||
layout: ds.base.layout_in,
|
||||
layout: ds.base.layout,
|
||||
});
|
||||
let (load_op, store_op) = conv::map_attachment_ops(ds.base.ops);
|
||||
let (stencil_load_op, stencil_store_op) =
|
||||
@@ -127,8 +127,8 @@ impl super::DeviceShared {
|
||||
.store_op(store_op)
|
||||
.stencil_load_op(stencil_load_op)
|
||||
.stencil_store_op(stencil_store_op)
|
||||
.initial_layout(ds.base.layout_pre)
|
||||
.final_layout(ds.base.layout_post)
|
||||
.initial_layout(ds.base.layout)
|
||||
.final_layout(ds.base.layout)
|
||||
.build();
|
||||
vk_attachments.push(vk_attachment);
|
||||
}
|
||||
|
||||
@@ -162,20 +162,16 @@ struct PrivateCapabilities {
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
struct AttachmentKey {
|
||||
format: vk::Format,
|
||||
layout_pre: vk::ImageLayout,
|
||||
layout_in: vk::ImageLayout,
|
||||
layout_post: vk::ImageLayout,
|
||||
layout: vk::ImageLayout,
|
||||
ops: crate::AttachmentOps,
|
||||
}
|
||||
|
||||
impl AttachmentKey {
|
||||
/// Returns an attachment key for a compatible attachment.
|
||||
fn compatible(format: vk::Format, layout_in: vk::ImageLayout) -> Self {
|
||||
fn compatible(format: vk::Format, layout: vk::ImageLayout) -> Self {
|
||||
Self {
|
||||
format,
|
||||
layout_pre: vk::ImageLayout::GENERAL,
|
||||
layout_in,
|
||||
layout_post: vk::ImageLayout::GENERAL,
|
||||
layout,
|
||||
ops: crate::AttachmentOps::all(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user