iiiiiii dooooooooont know.......

This commit is contained in:
janis 2026-04-17 20:35:04 +02:00
parent 30fc9f9f44
commit c20a4fa1a3
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
4 changed files with 305 additions and 450 deletions

View file

@ -12,6 +12,8 @@
//! recorded sequentially, in the order they were inserted into a command
//! buffer. During command insertion
use std::marker::PhantomData;
use crate::{
device::DeviceOwned,
render_graph::recorder::{CommandRecorder, SideEffectMap},
@ -21,6 +23,7 @@ use super::resources::*;
pub struct ImportResource<T: Resource> {
pub resource: T,
pub range: Option<Subresource>,
pub access: vk::AccessFlags2,
pub stage: vk::PipelineStageFlags2,
pub layout: Option<vk::ImageLayout>,
@ -28,12 +31,9 @@ pub struct ImportResource<T: Resource> {
impl<T: Resource> Command for ImportResource<T> {
fn side_effects(&self, mut map: SideEffectMap) {
self.resource
.side_effect(map.reborrow().into_side_effect_map2(
self.stage,
self.access,
self.layout,
));
let range = self.range.unwrap_or_else(|| self.resource.full_range());
map.with(self.stage, self.access, self.layout)
.insert_range(self.resource.id(), range);
}
fn apply(self, _recorder: &mut CommandRecorder) {
@ -55,16 +55,16 @@ impl<T: AsRef<[BufferRows]>> BufferImageBufferCopyRegion for T {
}
}
pub trait ImageCopyRegion {
fn regions(&self) -> &[TextureRegion];
pub trait ImageCopyRegion<T: IntoImageSubresourceRange> {
fn regions(&self) -> &[TextureRegion<T>];
}
impl ImageCopyRegion for TextureRegion {
fn regions(&self) -> &[TextureRegion] {
impl<T: IntoImageSubresourceRange> ImageCopyRegion<T> for TextureRegion<T> {
fn regions(&self) -> &[TextureRegion<T>] {
core::slice::from_ref(self)
}
}
impl<T: AsRef<[TextureRegion]>> ImageCopyRegion for T {
fn regions(&self) -> &[TextureRegion] {
impl<U: IntoImageSubresourceRange, T: AsRef<[TextureRegion<U>]>> ImageCopyRegion<U> for T {
fn regions(&self) -> &[TextureRegion<U>] {
self.as_ref()
}
}
@ -90,39 +90,43 @@ pub struct CopyBuffers<T: BufferCopyRegion> {
pub dst_region: T,
}
pub struct CopyTextures<T: ImageCopyRegion> {
pub struct CopyTextures<T: ImageCopyRegion<R>, R: IntoImageSubresourceRange> {
pub src: Texture,
pub src_region: T,
pub dst: Texture,
pub dst_region: T,
_pd: PhantomData<R>,
}
pub struct CopyBufferToTexture<T: BufferImageBufferCopyRegion, U: ImageCopyRegion> {
pub struct CopyBufferToTexture<
T: BufferImageBufferCopyRegion,
U: ImageCopyRegion<R>,
R: IntoImageSubresourceLayers,
> {
pub src: Buffer,
pub src_region: T,
pub dst: Texture,
pub dst_region: U,
_pd: PhantomData<R>,
}
pub struct CopyTextureToBuffer<T: ImageCopyRegion, U: BufferImageBufferCopyRegion> {
pub struct CopyTextureToBuffer<
T: ImageCopyRegion<R>,
U: BufferImageBufferCopyRegion,
R: IntoImageSubresourceLayers,
> {
pub src: Texture,
pub src_region: T,
pub dst: Buffer,
pub dst_region: U,
_pd: PhantomData<R>,
}
fn copy_side_effects_inner<T, U>(_src: &T, _dst: &U, _map: SideEffectMap)
where
T: Resource,
U: Resource,
{
unimplemented!()
}
impl<T, U> Command for CopyBufferToTexture<T, U>
impl<T, U, R> Command for CopyBufferToTexture<T, U, R>
where
T: BufferImageBufferCopyRegion,
U: ImageCopyRegion,
U: ImageCopyRegion<R>,
R: IntoImageSubresourceLayers,
{
fn side_effects(&self, mut map: SideEffectMap) {
let block_size = self.dst.format().block_size() as u64;
@ -170,7 +174,7 @@ where
vk::AccessFlags2::TRANSFER_WRITE,
Some(vk::ImageLayout::TRANSFER_DST_OPTIMAL),
)
.insert_range(dst_id, dst_region.range);
.insert_range(dst_id, dst_region.range.into_range());
}
}
@ -190,13 +194,7 @@ where
.buffer_image_height(src_region.row_count)
.image_offset(dst_region.offset)
.image_extent(dst_region.extent)
.image_subresource(
vk::ImageSubresourceLayers::default()
.aspect_mask(dst_region.range.aspect)
.mip_level(dst_region.range.mip_level)
.base_array_layer(dst_region.range.array_layers.start())
.layer_count(dst_region.range.array_layers.len()),
)
.image_subresource(dst_region.range.into_layers())
})
.collect::<Box<[_]>>();
@ -212,10 +210,11 @@ where
}
}
impl<T, U> Command for CopyTextureToBuffer<T, U>
impl<T, U, R> Command for CopyTextureToBuffer<T, U, R>
where
T: ImageCopyRegion,
T: ImageCopyRegion<R>,
U: BufferImageBufferCopyRegion,
R: IntoImageSubresourceLayers,
{
fn side_effects(&self, mut map: SideEffectMap) {
let block_size = self.src.format().block_size() as u64;
@ -250,7 +249,7 @@ where
vk::AccessFlags2::TRANSFER_READ,
Some(vk::ImageLayout::TRANSFER_SRC_OPTIMAL),
)
.insert_range(dst_id, src_region.range);
.insert_range(dst_id, src_region.range.into_range());
map.with(
vk::PipelineStageFlags2::COPY,
@ -283,13 +282,7 @@ where
.buffer_image_height(dst_region.row_count)
.image_offset(src_region.offset)
.image_extent(src_region.extent)
.image_subresource(
vk::ImageSubresourceLayers::default()
.aspect_mask(src_region.range.aspect)
.mip_level(src_region.range.mip_level)
.base_array_layer(src_region.range.array_layers.start())
.layer_count(src_region.range.array_layers.len()),
)
.image_subresource(src_region.range.into_layers())
})
.collect::<Box<[_]>>();
@ -357,9 +350,10 @@ where
}
}
impl<T> Command for CopyTextures<T>
impl<T, R> Command for CopyTextures<T, R>
where
T: ImageCopyRegion,
T: ImageCopyRegion<R>,
R: IntoImageSubresourceLayers,
{
fn side_effects(&self, mut map: SideEffectMap) {
for region in self.src_region.regions() {
@ -368,7 +362,7 @@ where
vk::AccessFlags2::TRANSFER_READ,
None,
)
.insert_range(self.src.id(), region.range);
.insert_range(self.src.id(), region.range.into_range());
}
for region in self.dst_region.regions() {
@ -377,7 +371,7 @@ where
vk::AccessFlags2::TRANSFER_WRITE,
None,
)
.insert_range(self.dst.id(), region.range);
.insert_range(self.dst.id(), region.range.into_range());
}
}
@ -393,9 +387,9 @@ where
.map(|(src_region, dst_region)| {
vk::ImageCopy2::default()
.src_offset(src_region.offset)
.src_subresource(src_region.range.into())
.src_subresource(src_region.range.into_layers())
.dst_offset(dst_region.offset)
.dst_subresource(dst_region.range.into())
.dst_subresource(dst_region.range.into_layers())
.extent(src_region.extent)
})
.collect::<Box<[_]>>();
@ -413,20 +407,20 @@ where
}
}
pub struct ClearTexture {
pub struct ClearTexture<R: IntoImageSubresourceRange> {
pub dst: Texture,
pub dst_region: TextureRegion,
pub dst_region: TextureRegion<R>,
pub clear_value: [f32; 4],
}
impl Command for ClearTexture {
impl<R: IntoImageSubresourceRange> Command for ClearTexture<R> {
fn side_effects(&self, mut map: SideEffectMap) {
map.with(
vk::PipelineStageFlags2::CLEAR,
vk::AccessFlags2::TRANSFER_WRITE,
Some(vk::ImageLayout::TRANSFER_DST_OPTIMAL),
)
.insert_range(self.dst.id(), self.dst_region.range);
.insert_range(self.dst.id(), self.dst_region.range.into_range());
}
fn apply(self, recorder: &mut CommandRecorder) {
@ -443,33 +437,43 @@ impl Command for ClearTexture {
recorder.get_image_handle(self.dst.id()),
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&values,
&[self.dst_region.range.into()],
&[self.dst_region.range.into_range()],
);
}
}
}
pub struct UpdateBuffer {
pub dst: Write<BufferSlice>,
pub dst: Buffer,
pub dst_region: BufferRange,
pub data: Vec<u8>,
}
impl Command for UpdateBuffer {
fn side_effects(&self, mut map: SideEffectMap) {
self.dst.side_effect(map.reborrow().into_side_effect_map2(
map.with(
vk::PipelineStageFlags2::TRANSFER,
vk::AccessFlags2::TRANSFER_WRITE,
None,
));
)
.insert_range(self.dst.id(), self.dst_region);
}
fn apply(self, _recorder: &mut CommandRecorder) {}
}
pub struct RenderAttachment {
pub texture: Texture,
pub region: vk::ImageSubresourceRange,
pub layout: vk::ImageLayout,
pub load_op: vk::AttachmentLoadOp,
pub store_op: vk::AttachmentStoreOp,
}
pub struct BeginRendering {
pub color_attachments: Vec<TextureRegion>,
pub depth_attachment: Option<TextureRegion>,
pub stencil_attachment: Option<TextureRegion>,
pub color_attachments: Vec<RenderAttachment>,
pub depth_attachment: Option<RenderAttachment>,
pub stencil_attachment: Option<RenderAttachment>,
pub area: (u32, u32),
pub layers: u32,
}
@ -482,26 +486,40 @@ impl Command for BeginRendering {
// pass instance referencing framebuffer-local stages must contain
// only framebuffer-local stages.
// TODO: consider loadop and storeop?
attachment.side_effect(map.reborrow().into_side_effect_map2(
map.with(
vk::PipelineStageFlags2::COLOR_ATTACHMENT_OUTPUT,
vk::AccessFlags2::COLOR_ATTACHMENT_READ,
Some(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL),
));
if attachment.load_op == vk::AttachmentLoadOp::LOAD {
vk::AccessFlags2::COLOR_ATTACHMENT_READ
} else {
vk::AccessFlags2::empty()
},
Some(attachment.layout),
)
.insert_range(attachment.texture.id(), attachment.region);
}
if let Some(depth) = &self.depth_attachment {
depth.side_effect(map.reborrow().into_side_effect_map2(
map.with(
vk::PipelineStageFlags2::EARLY_FRAGMENT_TESTS,
vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_READ,
Some(vk::ImageLayout::DEPTH_ATTACHMENT_OPTIMAL),
));
if depth.load_op == vk::AttachmentLoadOp::LOAD {
vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_READ
} else {
vk::AccessFlags2::empty()
},
Some(depth.layout),
)
.insert_range(depth.texture.id(), depth.region);
}
if let Some(stencil) = &self.stencil_attachment {
stencil.side_effect(map.reborrow().into_side_effect_map2(
map.with(
vk::PipelineStageFlags2::EARLY_FRAGMENT_TESTS,
vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_READ,
Some(vk::ImageLayout::STENCIL_ATTACHMENT_OPTIMAL),
));
if stencil.load_op == vk::AttachmentLoadOp::LOAD {
vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_READ
} else {
vk::AccessFlags2::empty()
},
Some(stencil.layout),
)
.insert_range(stencil.texture.id(), stencil.region);
}
}
@ -512,7 +530,7 @@ pub struct EndRendering;
impl Command for EndRendering {
fn side_effects(&self, _map: SideEffectMap) {
// No resource access, but ends the render pass
// TODO: need the beginrendering struct to declare the store-op dependencies.
}
fn apply(self, _recorder: &mut CommandRecorder) {}
@ -543,11 +561,12 @@ pub struct BindVertexBuffers {
impl Command for BindVertexBuffers {
fn side_effects(&self, mut map: SideEffectMap) {
for buffer in &self.buffers {
buffer.side_effect(map.reborrow().into_side_effect_map2(
map.with(
vk::PipelineStageFlags2::VERTEX_ATTRIBUTE_INPUT,
vk::AccessFlags2::VERTEX_ATTRIBUTE_READ,
None,
));
)
.insert_range(buffer.id(), buffer.range);
}
}
@ -577,11 +596,12 @@ pub struct BindIndexBuffer(pub BufferSlice, pub IndexFormat);
impl Command for BindIndexBuffer {
fn side_effects(&self, mut map: SideEffectMap) {
self.0.side_effect(map.reborrow().into_side_effect_map2(
map.with(
vk::PipelineStageFlags2::INDEX_INPUT,
vk::AccessFlags2::INDEX_READ,
None,
));
)
.insert_range(self.0.id(), self.0.range);
}
fn apply(self, recorder: &mut CommandRecorder) {
@ -726,27 +746,11 @@ pub enum IndexFormat {
pub struct Draw<T: IsDrawData> {
pub data: T,
pub vertex_buffers: Vec<BufferSlice>,
pub index_buffer: Option<(BufferSlice, IndexFormat)>,
}
impl<T: IsDrawData> Command for Draw<T> {
fn side_effects(&self, mut map: SideEffectMap) {
self.data.side_effects(map.reborrow());
for vertex_buffer in &self.vertex_buffers {
vertex_buffer.side_effect(map.reborrow().into_side_effect_map2(
vk::PipelineStageFlags2::VERTEX_ATTRIBUTE_INPUT,
vk::AccessFlags2::VERTEX_ATTRIBUTE_READ,
None,
));
}
if let Some((index_buffer, _)) = &self.index_buffer {
index_buffer.side_effect(map.reborrow().into_side_effect_map2(
vk::PipelineStageFlags2::INDEX_INPUT,
vk::AccessFlags2::INDEX_READ,
None,
));
}
}
fn apply(self, _recorder: &mut CommandRecorder) {}
@ -782,29 +786,28 @@ impl IsDrawData for DrawData {}
impl IsDrawData for DrawIndexedData {}
impl IsDrawData for DrawIndirectData {
fn side_effects(&self, mut map: SideEffectMap) {
self.indirect_buffer
.side_effect(map.reborrow().into_side_effect_map2(
vk::PipelineStageFlags2::DRAW_INDIRECT,
vk::AccessFlags2::INDIRECT_COMMAND_READ,
None,
));
map.with(
vk::PipelineStageFlags2::DRAW_INDIRECT,
vk::AccessFlags2::INDIRECT_COMMAND_READ,
None,
)
.insert_range(self.indirect_buffer.id(), self.indirect_buffer.range);
}
}
impl IsDrawData for DrawIndexedIndirectData {
fn side_effects(&self, mut map: SideEffectMap) {
self.indirect_buffer
.side_effect(map.reborrow().into_side_effect_map2(
vk::PipelineStageFlags2::DRAW_INDIRECT,
vk::AccessFlags2::INDIRECT_COMMAND_READ,
None,
));
map.with(
vk::PipelineStageFlags2::DRAW_INDIRECT,
vk::AccessFlags2::INDIRECT_COMMAND_READ,
None,
)
.insert_range(self.indirect_buffer.id(), self.indirect_buffer.range);
}
}
impl OutsideRenderPass for BeginRendering {}
impl InsideRenderPass for EndRendering {}
impl<T: Resource, U: Resource> OutsideRenderPass for Copy<T, U> {}
impl OutsideRenderPass for ClearTexture {}
impl<T: IntoImageSubresourceRange> OutsideRenderPass for ClearTexture<T> {}
impl OutsideRenderPass for UpdateBuffer {}
impl InsideRenderPass for BindPipeline {}

View file

@ -80,7 +80,11 @@ impl<'r> GraphBuilder<'r> {
mod api_demo {
use crate::{EguiState, pipeline::Pipeline, render_graph::commands};
use crate::{
EguiState,
pipeline::Pipeline,
render_graph::{commands, resources::TextureRegion},
};
use super::*;
use ash::vk::{self, BufferUsageFlags};
@ -180,84 +184,86 @@ mod api_demo {
);
let mut cmd = builder.make_command_list();
cmd.push(commands::Copy {
src: resources::BufferSlice {
buffer: resources::Buffer(staging.id),
range: resources::BufferRange {
offset: 0,
size: vertex_size as u64,
},
},
dst: resources::BufferSlice {
buffer: resources::Buffer(vertex_buffer.id),
range: resources::BufferRange {
offset: 0,
size: vertex_size as u64,
},
},
});
// cmd.push(commands::Copy {
// src: resources::BufferSlice {
// buffer: resources::Buffer(staging.id),
// range: resources::BufferRange {
// offset: 0,
// size: vertex_size as u64,
// },
// },
// dst: resources::BufferSlice {
// buffer: resources::Buffer(vertex_buffer.id),
// range: resources::BufferRange {
// offset: 0,
// size: vertex_size as u64,
// },
// },
// });
cmd.push(commands::Copy {
src: resources::BufferSlice {
buffer: resources::Buffer(staging.id),
range: resources::BufferRange {
offset: vertex_size as u64,
size: (vertex_size + index_size) as u64,
},
},
dst: resources::BufferSlice {
buffer: resources::Buffer(index_buffer.id),
range: resources::BufferRange {
offset: 0,
size: index_size as u64,
},
},
});
// cmd.push(commands::Copy {
// src: resources::BufferSlice {
// buffer: resources::Buffer(staging.id),
// range: resources::BufferRange {
// offset: vertex_size as u64,
// size: (vertex_size + index_size) as u64,
// },
// },
// dst: resources::BufferSlice {
// buffer: resources::Buffer(index_buffer.id),
// range: resources::BufferRange {
// offset: 0,
// size: index_size as u64,
// },
// },
// });
cmd.push(commands::Copy {
src: resources::BufferSlice {
buffer: resources::Buffer(staging.id),
range: resources::BufferRange {
offset: (vertex_size + index_size) as u64,
size: draw_calls_size as u64,
},
},
dst: resources::BufferSlice {
buffer: resources::Buffer(indirect_buffer.id),
range: resources::BufferRange {
offset: 0,
size: draw_calls_size as u64,
},
},
});
// cmd.push(commands::Copy {
// src: resources::BufferSlice {
// buffer: resources::Buffer(staging.id),
// range: resources::BufferRange {
// offset: (vertex_size + index_size) as u64,
// size: draw_calls_size as u64,
// },
// },
// dst: resources::BufferSlice {
// buffer: resources::Buffer(indirect_buffer.id),
// range: resources::BufferRange {
// offset: 0,
// size: draw_calls_size as u64,
// },
// },
// });
cmd.push(commands::Copy {
src: resources::BufferSlice {
buffer: resources::Buffer(staging.id),
range: resources::BufferRange {
offset: (vertex_size + index_size + draw_calls_size) as u64,
size: textures_indices_size as u64,
},
},
dst: resources::BufferSlice {
buffer: resources::Buffer(texture_indices.id),
range: resources::BufferRange {
offset: 0,
size: textures_indices_size as u64,
},
},
});
// cmd.push(commands::Copy {
// src: resources::BufferSlice {
// buffer: resources::Buffer(staging.id),
// range: resources::BufferRange {
// offset: (vertex_size + index_size + draw_calls_size) as u64,
// size: textures_indices_size as u64,
// },
// },
// dst: resources::BufferSlice {
// buffer: resources::Buffer(texture_indices.id),
// range: resources::BufferRange {
// offset: 0,
// size: textures_indices_size as u64,
// },
// },
// });
let mut pass_cmd = cmd.begin_rendering(
vec![resources::TextureRegion {
vec![commands::RenderAttachment {
texture: resources::Texture(render_target),
range: resources::TextureRange {
aspect: vk::ImageAspectFlags::COLOR,
mip_levels: (0..).into(),
array_layers: (0..).into(),
origin: (0, 0, 0),
extent: (extent.0, extent.1, 1),
},
region: vk::ImageSubresourceRange::default()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.base_mip_level(0)
.level_count(1)
.base_array_layer(0)
.layer_count(1),
layout: vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
load_op: vk::AttachmentLoadOp::LOAD,
store_op: vk::AttachmentStoreOp::STORE,
}],
None,
None,
@ -301,29 +307,32 @@ mod api_demo {
&[extent.0 as f32, extent.1 as f32].map(f32::to_bits),
),
});
pass_cmd.push(commands::Draw {
data: commands::DrawIndexedIndirectData {
indirect_buffer: resources::Buffer(indirect_buffer.id).full_slice(),
count: draw_calls.len() as u32,
stride: size_of::<DrawCall>() as u32,
},
vertex_buffers: vec![resources::BufferSlice {
pass_cmd.push(commands::BindVertexBuffers {
buffers: vec![resources::BufferSlice {
buffer: resources::Buffer(vertex_buffer.id),
range: resources::BufferRange {
offset: 0,
size: vertex_size as u64,
},
}],
index_buffer: Some((
resources::BufferSlice {
buffer: resources::Buffer(index_buffer.id),
range: resources::BufferRange {
offset: 0,
size: index_size as u64,
},
first_binding: 0,
});
pass_cmd.push(commands::BindIndexBuffer(
resources::BufferSlice {
buffer: resources::Buffer(index_buffer.id),
range: resources::BufferRange {
offset: 0,
size: index_size as u64,
},
commands::IndexFormat::Uint32,
)),
},
commands::IndexFormat::Uint32,
));
pass_cmd.push(commands::Draw {
data: commands::DrawIndexedIndirectData {
indirect_buffer: resources::Buffer(indirect_buffer.id).full_slice(),
count: draw_calls.len() as u32,
stride: size_of::<DrawCall>() as u32,
},
});
pass_cmd.finalise();

View file

@ -11,7 +11,7 @@ use crate::{
commands::CommandBuffer,
images::ImageDesc,
render_graph::{
commands::{Command, InsideRenderPass, OutsideRenderPass},
commands::{Command, InsideRenderPass, OutsideRenderPass, RenderAttachment},
resources::{
ResourceId, Subresource, SubresourceScope, SubresourceScopeInner, TextureRegion,
},
@ -83,6 +83,12 @@ impl<T> VecOrSingle<T> {
VecOrSingle::Single(item) => core::slice::from_ref::<T>(item).iter(),
}
}
fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> {
match self {
VecOrSingle::Vec(items) => items.as_mut_slice().iter_mut(),
VecOrSingle::Single(item) => core::slice::from_mut::<T>(item).iter_mut(),
}
}
}
#[derive(Default)]
@ -94,13 +100,35 @@ struct SideEffects {
pub struct SideEffectMap<'a>(&'a mut SideEffects, u32);
impl<'a> SideEffectMap<'a> {
pub fn insert(&mut self, id: ResourceId, scope: SubresourceScope) {
pub fn insert(&mut self, id: ResourceId, new_scope: SubresourceScope) {
self.0.resources.insert(id);
self.0
.map
.entry((id, self.1))
.and_modify(|entry| entry.push(scope))
.or_insert_with(|| scope.into());
'inserted: {
'outer: for ((_rid, _cid), scopes) in self.0.map.range_mut((id, 0)..=(id, self.1)).rev()
{
for scope in scopes.iter_mut().rev() {
if scope.try_merge(&new_scope) {
// if we can fold this scope with a previous one, we can
// stop iterating, as the barrier already exists if
// needed
break 'inserted;
} else if scope.conflicts(&new_scope) {
// if this scope conflicts with a previous one, we need
// to insert a barrier before the current command index;
// we can stop iterating, as we can no longer fold into
// any scopes before this conflict
break 'outer;
}
}
}
// if we couldn't fold this scope with any previous one, add it as a new entry
self.0
.map
.entry((id, self.1))
.and_modify(|entry| entry.push(new_scope))
.or_insert_with(|| new_scope.into());
}
}
pub fn reborrow(&mut self) -> SideEffectMap<'_> {
@ -219,9 +247,9 @@ impl<'cmd> CommandList<'cmd> {
pub fn begin_rendering(
&mut self,
color_attachments: Vec<TextureRegion>,
depth_attachment: Option<TextureRegion>,
stencil_attachment: Option<TextureRegion>,
color_attachments: Vec<RenderAttachment>,
depth_attachment: Option<RenderAttachment>,
stencil_attachment: Option<RenderAttachment>,
area: (u32, u32),
layers: u32,
) -> RenderPass<'cmd, '_> {

View file

@ -6,7 +6,7 @@ use crate::{images::MipRange, render_graph::recorder::SideEffectMap2};
pub trait Resource: Sized {
fn id(&self) -> ResourceId;
fn side_effect(&self, map: SideEffectMap2);
fn full_range(&self) -> Subresource;
}
mod sealed {
@ -28,7 +28,27 @@ pub use sealed::{Buffer as AsBuffer, Texture as AsTexture};
#[derive(Debug, Clone, Copy)]
pub enum Subresource {
Buffer(BufferRange),
Texture(TextureRange),
Texture(vk::ImageSubresourceRange),
}
impl Subresource {
pub fn full_buffer() -> Self {
Self::Buffer(BufferRange {
offset: 0,
size: vk::WHOLE_SIZE,
})
}
pub fn full_texture(format: vk::Format) -> Self {
use ash_formats::FormatExt;
Self::Texture(vk::ImageSubresourceRange {
aspect_mask: format.aspect_flags(),
base_mip_level: 0,
level_count: vk::REMAINING_MIP_LEVELS,
base_array_layer: 0,
layer_count: vk::REMAINING_ARRAY_LAYERS,
})
}
}
#[derive(Debug, Clone, Copy)]
@ -44,7 +64,7 @@ pub enum SubresourceScopeInner {
subresource: BufferRange,
},
Texture {
subresource: TextureRange,
subresource: vk::ImageSubresourceRange,
layout: vk::ImageLayout,
},
}
@ -94,18 +114,18 @@ impl SubresourceScope {
// think), however: if a previous access requires a less general
// barrier, then is it better to split?
let overlaps = lhs.aspect.intersects(rhs.aspect)
&& lhs.mip_levels.intersects(rhs.mip_levels)
&& lhs.array_layers.intersects(rhs.array_layers);
let overlaps = lhs.aspect_mask.intersects(rhs.aspect_mask)
&& lhs.mip_levels().intersects(rhs.mip_levels())
&& lhs.layers().intersects(rhs.layers());
// non-overlapping sub-resources shouldn't be merged.
if !overlaps {
return false;
}
let lhs_contains_rhs = lhs.aspect.contains(rhs.aspect)
&& lhs.mip_levels.contains(rhs.mip_levels)
&& lhs.array_layers.contains(rhs.array_layers);
let lhs_contains_rhs = lhs.aspect_mask.contains(rhs.aspect_mask)
&& lhs.mip_levels().contains(rhs.mip_levels())
&& lhs.layers().contains(rhs.layers());
// other is not a subresource of self, so we can't merge them.
if !lhs_contains_rhs {
@ -146,9 +166,9 @@ impl SubresourceScope {
) => {
// image subresource ranges overlap if they share mip levels and
// array layers with the same aspects.
let overlaps = lhs.aspect.intersects(rhs.aspect)
&& lhs.mip_levels.intersects(rhs.mip_levels)
&& lhs.array_layers.intersects(rhs.array_layers);
let overlaps = lhs.aspect_mask.intersects(rhs.aspect_mask)
&& lhs.mip_levels().intersects(rhs.mip_levels())
&& lhs.layers().intersects(rhs.layers());
if !overlaps {
return false;
@ -174,8 +194,6 @@ mod impls {
use super::*;
impl sealed::Texture for Texture {}
impl sealed::Texture for TextureRegion {}
impl sealed::Texture for TextureView {}
impl sealed::Buffer for Buffer {}
impl sealed::Buffer for BufferSlice {}
@ -185,130 +203,25 @@ mod impls {
self.0
}
fn side_effect(&self, mut map: SideEffectMap2) {
map.insert_range(self.id(), BufferRange::full());
fn full_range(&self) -> Subresource {
Subresource::full_buffer()
}
}
impl Resource for BufferSlice {
fn id(&self) -> ResourceId {
self.buffer.id()
}
fn side_effect(&self, mut map: SideEffectMap2) {
map.insert_range(self.id(), self.range);
fn full_range(&self) -> Subresource {
self.buffer.full_range()
}
}
impl Resource for BufferSlices {
fn id(&self) -> ResourceId {
self.buffer.id()
}
fn side_effect(&self, mut map: SideEffectMap2) {
for range in &self.ranges {
map.insert_range(self.id(), *range);
}
}
}
// TODO: the rows are not in bytes, so this is plain wrong. A BufferRowSlice needs to be generic over Buffer/BufferSlice, or commands taking a BufferRowSlice need to take the row parameters separately.
impl Resource for BufferRowSlice {
fn id(&self) -> ResourceId {
self.buffer.id()
}
fn side_effect(&self, mut map: SideEffectMap2) {
map.insert_range(
self.id(),
BufferRange {
offset: self.row.offset,
size: vk::WHOLE_SIZE,
},
);
}
}
impl Resource for BufferRowSlices {
fn id(&self) -> ResourceId {
self.buffer.id()
}
fn side_effect(&self, mut map: SideEffectMap2) {
for row in &self.rows {
map.insert_range(
self.id(),
BufferRange {
offset: row.offset,
size: vk::WHOLE_SIZE,
},
);
}
}
}
impl Resource for Texture {
fn id(&self) -> ResourceId {
self.0
}
fn side_effect(&self, mut map: SideEffectMap2) {
map.insert_range(self.id(), TextureRange::full());
}
}
impl Resource for TextureRegion {
fn id(&self) -> ResourceId {
self.texture.id()
}
fn side_effect(&self, mut map: SideEffectMap2) {
map.insert_range(self.id(), self.range);
}
}
impl Resource for TextureRegions {
fn id(&self) -> ResourceId {
self.texture.id()
}
fn side_effect(&self, mut map: SideEffectMap2) {
for range in &self.ranges {
map.insert_range(self.id(), range.0);
}
}
}
impl Resource for TextureView {
fn id(&self) -> ResourceId {
self.texture.id()
}
fn side_effect(&self, mut map: SideEffectMap2) {
map.insert_range(self.id(), self.range);
}
}
impl<T: Resource> Resource for Read<T> {
fn id(&self) -> ResourceId {
self.0.id()
}
fn side_effect(&self, map: SideEffectMap2) {
self.0.side_effect(map);
}
}
impl<T: Resource> Resource for Write<T> {
fn id(&self) -> ResourceId {
self.0.id()
}
fn side_effect(&self, map: SideEffectMap2) {
self.0.side_effect(map);
}
}
impl<T: Resource> Resource for ReadWrite<T> {
fn id(&self) -> ResourceId {
self.0.id()
}
fn side_effect(&self, map: SideEffectMap2) {
self.0.side_effect(map);
fn full_range(&self) -> Subresource {
Subresource::full_texture(vk::Format::UNDEFINED)
}
}
}
@ -368,32 +281,16 @@ pub struct BufferRows {
pub row_size: u32,
}
#[derive(Debug, Default, Clone, Copy)]
#[repr(C)]
pub struct TextureRange {
pub aspect: vk::ImageAspectFlags,
pub mip_levels: MipRange,
pub array_layers: MipRange,
}
#[derive(Debug, Default, Clone, Copy)]
#[repr(C)]
pub struct TextureLayers {
pub aspect: vk::ImageAspectFlags,
pub mip_level: u32,
pub array_layers: MipRange,
}
pub trait IntoImageSubresourceLayers {
fn into_layers(self) -> vk::ImageSubresourceLayers;
fn into_layers(&self) -> vk::ImageSubresourceLayers;
}
pub trait IntoImageSubresourceRange {
fn into_range(self) -> vk::ImageSubresourceRange;
fn into_range(&self) -> vk::ImageSubresourceRange;
}
impl IntoImageSubresourceLayers for vk::ImageSubresource {
fn into_layers(self) -> vk::ImageSubresourceLayers {
fn into_layers(&self) -> vk::ImageSubresourceLayers {
vk::ImageSubresourceLayers {
aspect_mask: self.aspect_mask,
mip_level: self.mip_level,
@ -403,20 +300,17 @@ impl IntoImageSubresourceLayers for vk::ImageSubresource {
}
}
impl IntoImageSubresourceRange for vk::ImageSubresource {
fn into_range(self) -> vk::ImageSubresourceRange {
vk::ImageSubresourceRange {
aspect_mask: self.aspect_mask,
base_mip_level: self.mip_level,
level_count: 1,
base_array_layer: self.array_layer,
layer_count: 1,
}
impl<T> IntoImageSubresourceRange for T
where
T: IntoImageSubresourceLayers,
{
fn into_range(&self) -> vk::ImageSubresourceRange {
self.into_layers().into_range()
}
}
impl IntoImageSubresourceRange for vk::ImageSubresourceLayers {
fn into_range(self) -> vk::ImageSubresourceRange {
fn into_range(&self) -> vk::ImageSubresourceRange {
vk::ImageSubresourceRange {
aspect_mask: self.aspect_mask,
base_mip_level: self.mip_level,
@ -427,6 +321,12 @@ impl IntoImageSubresourceRange for vk::ImageSubresourceLayers {
}
}
impl IntoImageSubresourceRange for vk::ImageSubresourceRange {
fn into_range(&self) -> vk::ImageSubresourceRange {
*self
}
}
pub trait ImageSubresourceExt {
fn aspects(self) -> vk::ImageAspectFlags;
fn layers(self) -> MipRange;
@ -478,63 +378,8 @@ impl ImageSubresourceExt for vk::ImageSubresource {
}
}
impl From<TextureLayers> for vk::ImageSubresourceLayers {
fn from(value: TextureLayers) -> Self {
vk::ImageSubresourceLayers {
aspect_mask: value.aspect,
mip_level: value.mip_level,
base_array_layer: value.array_layers.start,
layer_count: value.array_layers.end - value.array_layers.start,
}
}
}
impl From<TextureLayers> for vk::ImageSubresourceRange {
fn from(value: TextureLayers) -> Self {
vk::ImageSubresourceRange {
aspect_mask: value.aspect,
base_mip_level: value.mip_level,
level_count: 1,
base_array_layer: value.array_layers.start,
layer_count: value.array_layers.end - value.array_layers.start,
}
}
}
impl From<TextureRange> for vk::ImageSubresourceRange {
fn from(value: TextureRange) -> Self {
vk::ImageSubresourceRange {
aspect_mask: value.aspect,
base_mip_level: value.mip_levels.start,
level_count: value.mip_levels.end - value.mip_levels.start,
base_array_layer: value.array_layers.start,
layer_count: value.array_layers.end - value.array_layers.start,
}
}
}
impl From<TextureLayers> for TextureRange {
fn from(value: TextureLayers) -> Self {
Self {
aspect: value.aspect,
mip_levels: MipRange::single(value.mip_level),
array_layers: value.array_layers,
}
}
}
impl From<TextureLayers> for Subresource {
fn from(value: TextureLayers) -> Self {
Subresource::Texture(TextureRange {
aspect: value.aspect,
mip_levels: MipRange::single(value.mip_level),
array_layers: value.array_layers,
})
}
}
impl From<TextureRange> for Subresource {
fn from(value: TextureRange) -> Self {
impl From<vk::ImageSubresourceRange> for Subresource {
fn from(value: vk::ImageSubresourceRange) -> Self {
Subresource::Texture(value)
}
}
@ -548,17 +393,6 @@ impl From<(BufferRange, vk::ImageLayout)> for ResourceRange {
}
}
impl From<(TextureRange, vk::ImageLayout)> for ResourceRange {
fn from((value, layout): (TextureRange, vk::ImageLayout)) -> Self {
ResourceRange::Texture {
aspect: value.aspect,
mip_level: value.mip_levels,
array_layers: value.array_layers,
layout,
}
}
}
impl From<BufferRange> for ResourceRange {
fn from(value: BufferRange) -> Self {
ResourceRange::Buffer {
@ -568,18 +402,6 @@ impl From<BufferRange> for ResourceRange {
}
}
impl TextureRange {
pub fn full() -> Self {
Self {
aspect: vk::ImageAspectFlags::COLOR
| vk::ImageAspectFlags::DEPTH
| vk::ImageAspectFlags::STENCIL,
mip_levels: MipRange::default(),
array_layers: MipRange::default(),
}
}
}
pub struct Buffer(pub ResourceId);
impl Buffer {
@ -616,19 +438,12 @@ pub struct BufferRowSlices {
pub rows: Vec<BufferRows>,
}
pub struct TextureRegion {
pub range: TextureLayers,
pub struct TextureRegion<T: IntoImageSubresourceRange = vk::ImageSubresourceRange> {
pub range: T,
pub offset: vk::Offset3D,
pub extent: vk::Extent3D,
}
pub struct TextureView {
pub texture: Texture,
pub format: vk::Format,
pub mapping: vk::ComponentMapping,
pub range: TextureRange,
}
pub struct Read<T>(pub T);
pub struct Write<T>(pub T);
pub struct ReadWrite<T>(pub T);