diff --git a/crates/renderer/src/commands.rs b/crates/renderer/src/commands.rs index e9afe9c..77d8698 100644 --- a/crates/renderer/src/commands.rs +++ b/crates/renderer/src/commands.rs @@ -920,6 +920,10 @@ mod command_pools { level: this.level, }) } + + pub fn raw(&self) -> vk::CommandBuffer { + self.handle() + } } pub struct CommandBufferFuture { diff --git a/crates/renderer/src/images.rs b/crates/renderer/src/images.rs index dce665e..ec40427 100644 --- a/crates/renderer/src/images.rs +++ b/crates/renderer/src/images.rs @@ -605,6 +605,14 @@ impl MipRange { self.end } + pub fn start(&self) -> u32 { + self.start + } + + pub fn end(&self) -> u32 { + self.end + } + pub fn fits_in(&self, total_mips: u32) -> bool { self.start < total_mips && (self.end == vk::REMAINING_MIP_LEVELS || self.end <= total_mips) } diff --git a/crates/renderer/src/render_graph/commands.rs b/crates/renderer/src/render_graph/commands.rs index 62d59a4..9087e3c 100644 --- a/crates/renderer/src/render_graph/commands.rs +++ b/crates/renderer/src/render_graph/commands.rs @@ -1,4 +1,3 @@ -#![allow(dead_code)] //! This module defines the commands that can be recorded in the render //! graph. //! Commands can be allocated, and then recorded into a command @@ -13,29 +12,32 @@ //! recorded sequentially, in the order they were inserted into a command //! buffer. During command insertion -use crate::render_graph::recorder::{CommandMeta, CommandRecorder, SideEffectMap}; +use crate::{ + device::DeviceOwned, + render_graph::recorder::{CommandRecorder, SideEffectMap}, +}; use super::resources::*; -pub struct CopyBuffers { - pub src: Read, - pub dst: Write, -} +// pub struct CopyBuffers { +// pub src: Read, +// pub dst: Write, +// } -pub struct CopyTextures { - pub src: Read, - pub dst: Write, -} +// pub struct CopyTextures { +// pub src: Read, +// pub dst: Write, +// } -pub struct CopyBufferToTexture { - pub src: Read, - pub dst: Write, -} +// pub struct CopyBufferToTexture { +// pub src: Read, +// pub dst: Write, +// } -pub struct CopyTextureToBuffer { - pub src: Read, - pub dst: Write, -} +// pub struct CopyTextureToBuffer { +// pub src: Read, +// pub dst: Write, +// } pub struct Copy { pub src: Read, @@ -43,48 +45,122 @@ pub struct Copy { } impl Copy { fn side_effects_inner(&self, mut map: SideEffectMap) { - map.insert( - self.src.id(), - ResourceAccess { - range: self.src.into_access(), - access: vk::AccessFlags2::TRANSFER_READ, - }, - ); - map.insert( - self.dst.id(), - ResourceAccess { - range: self.dst.into_access(), - access: vk::AccessFlags2::TRANSFER_WRITE, - }, - ); + self.src + .side_effect(map.reborrow(), vk::AccessFlags2::TRANSFER_READ); + self.dst + .side_effect(map.reborrow(), vk::AccessFlags2::TRANSFER_WRITE); } } -impl Command for Copy { +impl Command for Copy { fn side_effects(&self, map: SideEffectMap) { self.side_effects_inner(map) } - fn apply(self, _recorder: &mut CommandRecorder) { - // CopyBufferToTexture {src, dst}.apply(recorder) + fn apply(self, recorder: &mut CommandRecorder) { + let cmd = recorder.cmd_buffer(); + let dev = &cmd.device().raw; + + let regions = &[vk::BufferImageCopy2::default() + .buffer_offset(self.src.row.offset) + .buffer_row_length(self.src.row.row_size) + .buffer_image_height(self.src.row.row_count) + .image_offset(self.dst.range.offset()) + .image_extent(self.dst.range.extent()) + .image_subresource( + vk::ImageSubresourceLayers::default() + .aspect_mask(self.dst.range.aspect) + .mip_level(self.dst.range.mip_level) + .base_array_layer(self.dst.range.array_layers.start()) + .layer_count(self.dst.range.array_layers.count()), + )]; + + let info = vk::CopyBufferToImageInfo2::default() + .src_buffer(recorder.get_buffer_handle(self.src.id())) + .dst_image(recorder.get_image_handle(self.dst.id())) + .dst_image_layout(recorder.get_image_layout(self.dst.id())) + .regions(regions); + + unsafe { + dev.cmd_copy_buffer_to_image2(cmd.raw(), &info); + } } } -impl Command for Copy { + +impl Command for Copy { fn side_effects(&self, map: SideEffectMap) { self.side_effects_inner(map) } - fn apply(self, _recorder: &mut CommandRecorder) { - // CopyTextureToBuffer {src, dst}.apply(recorder) + fn apply(self, recorder: &mut CommandRecorder) { + let cmd = recorder.cmd_buffer(); + let dev = &cmd.device().raw; + + let regions = &self + .src + .rows + .iter() + .zip(self.dst.ranges.iter()) + .map(|(src_row, dst_range)| { + vk::BufferImageCopy2::default() + .buffer_offset(src_row.offset) + .buffer_row_length(src_row.row_size) + .buffer_image_height(src_row.row_count) + .image_offset(dst_range.offset()) + .image_extent(dst_range.extent()) + .image_subresource( + vk::ImageSubresourceLayers::default() + .aspect_mask(dst_range.aspect) + .mip_level(dst_range.mip_level) + .base_array_layer(dst_range.array_layers.start()) + .layer_count(dst_range.array_layers.count()), + ) + }) + .collect::>(); + + let info = vk::CopyBufferToImageInfo2::default() + .src_buffer(recorder.get_buffer_handle(self.src.id())) + .dst_image(recorder.get_image_handle(self.dst.id())) + .dst_image_layout(recorder.get_image_layout(self.dst.id())) + .regions(regions); + + unsafe { + dev.cmd_copy_buffer_to_image2(cmd.raw(), &info); + } + } +} + +impl Command for Copy { + fn side_effects(&self, map: SideEffectMap) { + self.side_effects_inner(map) } - fn get_meta(&self) -> CommandMeta { - CommandMeta { - apply_command: |recorder, command_ptr, cursor| { - let command = unsafe { command_ptr.cast::().read() }; - *cursor += std::mem::size_of::(); - command.apply(recorder); - }, + fn apply(self, recorder: &mut CommandRecorder) { + let cmd = recorder.cmd_buffer(); + let dev = &cmd.device().raw; + + let regions = &[vk::BufferImageCopy2::default() + .buffer_offset(self.dst.row.offset) + .buffer_row_length(self.dst.row.row_size) + .buffer_image_height(self.dst.row.row_count) + .image_offset(self.src.range.offset()) + .image_extent(self.src.range.extent()) + .image_subresource( + vk::ImageSubresourceLayers::default() + .aspect_mask(self.src.range.aspect) + .mip_level(self.src.range.mip_level) + .base_array_layer(self.src.range.array_layers.start()) + .layer_count(self.src.range.array_layers.count()), + )]; + + let info = vk::CopyImageToBufferInfo2::default() + .dst_buffer(recorder.get_buffer_handle(self.dst.id())) + .src_image(recorder.get_image_handle(self.src.id())) + .src_image_layout(recorder.get_image_layout(self.src.id())) + .regions(regions); + + unsafe { + dev.cmd_copy_image_to_buffer2(cmd.raw(), &info); } } } @@ -93,8 +169,39 @@ impl Command for Copy { self.side_effects_inner(map) } - fn apply(self, _recorder: &mut CommandRecorder) { - // CopyTextures {src, dst}.apply(recorder) + fn apply(self, recorder: &mut CommandRecorder) { + let cmd = recorder.cmd_buffer(); + let dev = &cmd.device().raw; + + let regions = &[vk::ImageCopy2::default() + .extent(self.src.range.extent()) + .dst_offset(self.dst.range.offset()) + .src_offset(self.src.range.offset()) + .dst_subresource( + vk::ImageSubresourceLayers::default() + .aspect_mask(self.dst.range.aspect) + .mip_level(self.dst.range.mip_level) + .base_array_layer(self.dst.range.array_layers.start()) + .layer_count(self.dst.range.array_layers.count()), + ) + .src_subresource( + vk::ImageSubresourceLayers::default() + .aspect_mask(self.src.range.aspect) + .mip_level(self.src.range.mip_level) + .base_array_layer(self.src.range.array_layers.start()) + .layer_count(self.src.range.array_layers.count()), + )]; + + let info = vk::CopyImageInfo2::default() + .dst_image(recorder.get_image_handle(self.dst.id())) + .dst_image_layout(recorder.get_image_layout(self.dst.id())) + .src_image(recorder.get_image_handle(self.src.id())) + .src_image_layout(recorder.get_image_layout(self.src.id())) + .regions(regions); + + unsafe { + dev.cmd_copy_image2(cmd.raw(), &info); + } } } impl Command for Copy { @@ -102,8 +209,25 @@ impl Command for Copy { self.side_effects_inner(map) } - fn apply(self, _recorder: &mut CommandRecorder) { - // CopyBuffers {src, dst}.apply(recorder) + fn apply(self, recorder: &mut CommandRecorder) { + let cmd = recorder.cmd_buffer(); + let dev = &cmd.device().raw; + + debug_assert_eq!(self.src.range.size, self.dst.range.size); + + let regions = &[vk::BufferCopy2::default() + .dst_offset(self.dst.range.offset) + .src_offset(self.src.range.offset) + .size(self.src.range.size)]; + + let info = vk::CopyBufferInfo2::default() + .dst_buffer(recorder.get_buffer_handle(self.dst.id())) + .src_buffer(recorder.get_buffer_handle(self.src.id())) + .regions(regions); + + unsafe { + dev.cmd_copy_buffer2(cmd.raw(), &info); + } } } @@ -114,13 +238,8 @@ pub struct ClearTexture { impl Command for ClearTexture { fn side_effects(&self, mut map: SideEffectMap) { - map.insert( - self.dst.id(), - ResourceAccess { - range: self.dst.into_access(), - access: vk::AccessFlags2::TRANSFER_WRITE, - }, - ); + self.dst + .side_effect(map.reborrow(), vk::AccessFlags2::TRANSFER_WRITE); } fn apply(self, _recorder: &mut CommandRecorder) {} @@ -133,19 +252,14 @@ pub struct UpdateBuffer { impl Command for UpdateBuffer { fn side_effects(&self, mut map: SideEffectMap) { - map.insert( - self.dst.id(), - ResourceAccess { - range: self.dst.into_access(), - access: vk::AccessFlags2::TRANSFER_WRITE, - }, - ); + self.dst + .side_effect(map.reborrow(), vk::AccessFlags2::TRANSFER_WRITE); } fn apply(self, _recorder: &mut CommandRecorder) {} } -pub struct RenderPass { +pub struct BeginRendering { pub color_attachments: Vec>, pub depth_attachment: Option>, pub stencil_attachment: Option>, @@ -153,33 +267,21 @@ pub struct RenderPass { pub layers: u32, } -impl Command for RenderPass { +impl Command for BeginRendering { fn side_effects(&self, mut map: SideEffectMap) { for attachment in &self.color_attachments { - map.insert( - attachment.id(), - ResourceAccess { - range: attachment.into_access(), - access: vk::AccessFlags2::COLOR_ATTACHMENT_WRITE, - }, - ); + attachment.side_effect(map.reborrow(), vk::AccessFlags2::COLOR_ATTACHMENT_WRITE); } if let Some(depth) = &self.depth_attachment { - map.insert( - depth.id(), - ResourceAccess { - range: depth.into_access(), - access: vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_WRITE, - }, + depth.side_effect( + map.reborrow(), + vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_WRITE, ); } if let Some(stencil) = &self.stencil_attachment { - map.insert( - stencil.id(), - ResourceAccess { - range: stencil.into_access(), - access: vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_WRITE, - }, + stencil.side_effect( + map.reborrow(), + vk::AccessFlags2::DEPTH_STENCIL_ATTACHMENT_WRITE, ); } } @@ -187,6 +289,16 @@ impl Command for RenderPass { fn apply(self, _recorder: &mut CommandRecorder) {} } +pub struct EndRendering; + +impl Command for EndRendering { + fn side_effects(&self, _map: SideEffectMap) { + // No resource access, but ends the render pass + } + + fn apply(self, _recorder: &mut CommandRecorder) {} +} + pub struct BindPipeline(pub Pipeline); impl Command for BindPipeline { @@ -204,13 +316,7 @@ pub struct BindVertexBuffers { impl Command for BindVertexBuffers { fn side_effects(&self, mut map: SideEffectMap) { for buffer in &self.buffers { - map.insert( - buffer.id(), - ResourceAccess { - range: buffer.into_access(), - access: vk::AccessFlags2::VERTEX_ATTRIBUTE_READ, - }, - ); + buffer.side_effect(map.reborrow(), vk::AccessFlags2::VERTEX_ATTRIBUTE_READ); } } @@ -221,13 +327,8 @@ pub struct BindIndexBuffer(pub Read, pub IndexFormat); impl Command for BindIndexBuffer { fn side_effects(&self, mut map: SideEffectMap) { - map.insert( - self.0.id(), - ResourceAccess { - range: self.0.into_access(), - access: vk::AccessFlags2::INDEX_READ, - }, - ); + self.0 + .side_effect(map.reborrow(), vk::AccessFlags2::INDEX_READ); } fn apply(self, _recorder: &mut CommandRecorder) {} @@ -330,31 +431,13 @@ impl Command for Draw { fn side_effects(&self, mut map: SideEffectMap) { self.data.side_effects(map.reborrow()); for vertex_buffer in &self.vertex_buffers { - map.insert( - vertex_buffer.id(), - ResourceAccess { - range: vertex_buffer.into_access(), - access: vk::AccessFlags2::VERTEX_ATTRIBUTE_READ, - }, - ); + vertex_buffer.side_effect(map.reborrow(), vk::AccessFlags2::VERTEX_ATTRIBUTE_READ); } if let Some((index_buffer, _)) = &self.index_buffer { - map.insert( - index_buffer.id(), - ResourceAccess { - range: index_buffer.into_access(), - access: vk::AccessFlags2::INDEX_READ, - }, - ); + index_buffer.side_effect(map.reborrow(), vk::AccessFlags2::VERTEX_ATTRIBUTE_READ); } if let Some(count_buffer) = &self.count_buffer { - map.insert( - count_buffer.id(), - ResourceAccess { - range: count_buffer.into_access(), - access: vk::AccessFlags2::INDIRECT_COMMAND_READ, - }, - ); + count_buffer.side_effect(map.reborrow(), vk::AccessFlags2::VERTEX_ATTRIBUTE_READ); } } @@ -364,15 +447,6 @@ impl Command for Draw { pub trait Command: Sized { fn side_effects(&self, map: SideEffectMap); fn apply(self, recorder: &mut CommandRecorder); - fn get_meta(&self) -> CommandMeta { - CommandMeta { - apply_command: |recorder, command_ptr, cursor| { - let command = unsafe { command_ptr.cast::().read() }; - *cursor += std::mem::size_of::(); - command.apply(recorder); - }, - } - } } mod sealed { @@ -383,34 +457,25 @@ mod sealed { pub trait OutsideRenderPass {} } use ash::vk; -use sealed::*; +pub(super) use sealed::*; impl IsDrawData for DrawData {} impl IsDrawData for DrawIndexedData {} impl IsDrawData for DrawIndirectData { fn side_effects(&self, mut map: SideEffectMap) { - map.insert( - self.indirect_buffer.id(), - ResourceAccess { - range: self.indirect_buffer.into_access(), - access: vk::AccessFlags2::INDIRECT_COMMAND_READ, - }, - ); + self.indirect_buffer + .side_effect(map.reborrow(), vk::AccessFlags2::INDIRECT_COMMAND_READ); } } impl IsDrawData for DrawIndexedIndirectData { fn side_effects(&self, mut map: SideEffectMap) { - map.insert( - self.indirect_buffer.id(), - ResourceAccess { - range: self.indirect_buffer.into_access(), - access: vk::AccessFlags2::INDIRECT_COMMAND_READ, - }, - ); + self.indirect_buffer + .side_effect(map.reborrow(), vk::AccessFlags2::INDIRECT_COMMAND_READ); } } -impl OutsideRenderPass for RenderPass {} +impl OutsideRenderPass for BeginRendering {} +impl InsideRenderPass for EndRendering {} impl OutsideRenderPass for Copy {} impl OutsideRenderPass for ClearTexture {} impl OutsideRenderPass for UpdateBuffer {} diff --git a/crates/renderer/src/render_graph/mod.rs b/crates/renderer/src/render_graph/mod.rs index 373f988..12016f8 100644 --- a/crates/renderer/src/render_graph/mod.rs +++ b/crates/renderer/src/render_graph/mod.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + mod legacy; pub use legacy::*; diff --git a/crates/renderer/src/render_graph/recorder.rs b/crates/renderer/src/render_graph/recorder.rs index 441e3e3..dc814ea 100644 --- a/crates/renderer/src/render_graph/recorder.rs +++ b/crates/renderer/src/render_graph/recorder.rs @@ -4,16 +4,42 @@ use std::{ ptr::NonNull, }; -use crate::render_graph::{ - commands::Command, - resources::{ResourceAccess, ResourceId}, +use ash::vk; + +use crate::{ + commands::CommandBuffer, + render_graph::{ + commands::{Command, InsideRenderPass, OutsideRenderPass}, + resources::{ResourceAccess, ResourceId, TextureRegion, Write}, + }, }; pub struct CommandRecorder; -pub struct RenderPassRecorder; -pub struct CommandMeta { - pub(crate) apply_command: unsafe fn(&mut CommandRecorder, NonNull<()>, cursor: &mut usize), +impl CommandRecorder { + pub fn cmd_buffer(&self) -> &CommandBuffer { + unimplemented!() + } + + pub fn get_buffer_handle(&self, _id: ResourceId) -> vk::Buffer { + unimplemented!() + } + + pub fn get_image_handle(&self, _id: ResourceId) -> vk::Image { + unimplemented!() + } + + pub fn get_image_layout(&self, _id: ResourceId) -> vk::ImageLayout { + unimplemented!() + } + + pub fn get_image_view_handle(&self, _id: ResourceId) -> vk::ImageView { + unimplemented!() + } +} + +struct CommandMeta { + apply_command: unsafe fn(&mut CommandRecorder, NonNull<()>, cursor: &mut usize), } pub struct SideEffectMap<'a>(&'a mut BTreeMap<(ResourceId, u32), ResourceAccess>, u32); @@ -35,6 +61,20 @@ pub struct CommandList { side_effects: BTreeMap<(ResourceId, u32), ResourceAccess>, } +pub struct RenderPass<'a> { + cmd_list: &'a mut CommandList, +} + +impl<'a> RenderPass<'a> { + pub fn finalise(self) { + self.cmd_list.push_inner(super::commands::EndRendering); + } + + pub fn push(&mut self, command: C) { + self.cmd_list.push_inner(command); + } +} + impl CommandList { pub fn new() -> Self { Self { @@ -44,7 +84,29 @@ impl CommandList { } } - pub fn push(&mut self, command: C) { + pub fn begin_rendering( + &mut self, + color_attachments: Vec>, + depth_attachment: Option>, + stencil_attachment: Option>, + area: (u32, u32), + layers: u32, + ) -> RenderPass<'_> { + self.push(super::commands::BeginRendering { + color_attachments, + depth_attachment, + stencil_attachment, + area, + layers, + }); + RenderPass { cmd_list: self } + } + + pub fn push(&mut self, command: C) { + self.push_inner(command); + } + + fn push_inner(&mut self, command: C) { struct Packed { meta: CommandMeta, command: C, diff --git a/crates/renderer/src/render_graph/resources.rs b/crates/renderer/src/render_graph/resources.rs index c1417cb..9352b92 100644 --- a/crates/renderer/src/render_graph/resources.rs +++ b/crates/renderer/src/render_graph/resources.rs @@ -1,13 +1,12 @@ +use std::ops::Deref; + use ash::vk; -use crate::images::MipRange; +use crate::{images::MipRange, render_graph::recorder::SideEffectMap}; -pub trait Resource: Sized + AsResourceRange { +pub trait Resource: Sized { fn id(&self) -> ResourceId; -} - -pub trait AsResourceRange { - fn into_access(&self) -> ResourceRange; + fn side_effect(&self, map: SideEffectMap, access: vk::AccessFlags2); } mod impls { @@ -17,93 +16,165 @@ mod impls { fn id(&self) -> ResourceId { self.0 } + + fn side_effect(&self, mut map: SideEffectMap, access: vk::AccessFlags2) { + map.insert( + self.id(), + ResourceAccess { + range: BufferRange::full().into(), + access, + }, + ); + } } + + impl Resource for BufferSlice { + fn id(&self) -> ResourceId { + self.buffer.id() + } + + fn side_effect(&self, mut map: SideEffectMap, access: vk::AccessFlags2) { + map.insert( + self.id(), + ResourceAccess { + range: self.range.into(), + access, + }, + ); + } + } + impl Resource for BufferSlices { + fn id(&self) -> ResourceId { + self.buffer.id() + } + + fn side_effect(&self, mut map: SideEffectMap, access: vk::AccessFlags2) { + for range in &self.ranges { + map.insert( + self.id(), + ResourceAccess { + range: (*range).into(), + access, + }, + ); + } + } + } + impl Resource for BufferRowSlice { + fn id(&self) -> ResourceId { + self.buffer.id() + } + + fn side_effect(&self, mut map: SideEffectMap, access: vk::AccessFlags2) { + map.insert( + self.id(), + ResourceAccess { + range: BufferRange { + offset: self.row.offset, + size: (self.row.row_count as u64) * (self.row.row_size as u64), + } + .into(), + access, + }, + ); + } + } + impl Resource for BufferRowSlices { + fn id(&self) -> ResourceId { + self.buffer.id() + } + + fn side_effect(&self, mut map: SideEffectMap, access: vk::AccessFlags2) { + for row in &self.rows { + map.insert( + self.id(), + ResourceAccess { + range: BufferRange { + offset: row.offset, + size: (row.row_count as u64) * (row.row_size as u64), + } + .into(), + access, + }, + ); + } + } + } + impl Resource for Texture { fn id(&self) -> ResourceId { self.0 } - } - impl Resource for BufferSlice { - fn id(&self) -> ResourceId { - self.buffer.id() + + fn side_effect(&self, mut map: SideEffectMap, access: vk::AccessFlags2) { + map.insert( + self.id(), + ResourceAccess { + range: TextureRange::full().into(), + access, + }, + ); } } impl Resource for TextureRegion { fn id(&self) -> ResourceId { self.texture.id() } - } - impl AsResourceRange for BufferSlice { - fn into_access(&self) -> ResourceRange { - ResourceRange::Buffer { - offset: self.offset, - size: self.size, + fn side_effect(&self, mut map: SideEffectMap, access: vk::AccessFlags2) { + map.insert( + self.id(), + ResourceAccess { + range: self.range.into(), + access, + }, + ); + } + } + impl Resource for TextureRegions { + fn id(&self) -> ResourceId { + self.texture.id() + } + + fn side_effect(&self, mut map: SideEffectMap, access: vk::AccessFlags2) { + for range in &self.ranges { + map.insert( + self.id(), + ResourceAccess { + range: (*range).into(), + access, + }, + ); } } } - impl AsResourceRange for TextureRegion { - fn into_access(&self) -> ResourceRange { - ResourceRange::Texture { - aspect: self.aspect, - mip_level: self.mip_level, - array_layers: self.array_layers, - origin: self.origin, - extent: self.extent, - } - } - } - - impl AsResourceRange for Texture { - fn into_access(&self) -> ResourceRange { - ResourceRange::Texture { - aspect: vk::ImageAspectFlags::NONE, - mip_level: 0, - array_layers: MipRange::default(), - origin: (0, 0, 0), - extent: (u32::MAX, u32::MAX, u32::MAX), - } - } - } - - impl AsResourceRange for Buffer { - fn into_access(&self) -> ResourceRange { - ResourceRange::Buffer { - offset: 0, - size: u64::MAX, - } - } - } - impl AsResourceRange for Read { - fn into_access(&self) -> ResourceRange { - self.0.into_access() - } - } - impl AsResourceRange for Write { - fn into_access(&self) -> ResourceRange { - self.0.into_access() - } - } - impl AsResourceRange for ReadWrite { - fn into_access(&self) -> ResourceRange { - self.0.into_access() - } - } impl Resource for Read { fn id(&self) -> ResourceId { self.0.id() } + + fn side_effect(&self, map: SideEffectMap, access: vk::AccessFlags2) { + self.0.side_effect(map, access); + } } impl Resource for Write { fn id(&self) -> ResourceId { self.0.id() } + + fn side_effect(&self, map: SideEffectMap, access: vk::AccessFlags2) { + self.0.side_effect(map, access); + } } impl Resource for ReadWrite { fn id(&self) -> ResourceId { self.0.id() } + + fn side_effect(&self, map: SideEffectMap, access: vk::AccessFlags2) { + self.0.side_effect(map, access); + } } } @@ -127,27 +198,151 @@ pub enum ResourceRange { aspect: vk::ImageAspectFlags, mip_level: u32, array_layers: MipRange, - origin: (u32, u32, u32), + origin: (i32, i32, i32), extent: (u32, u32, u32), }, } -pub struct Buffer(ResourceId); -pub struct Texture(ResourceId); -pub struct BufferSlice { - pub buffer: Buffer, +#[derive(Debug, Clone, Copy)] +pub struct BufferRange { pub offset: u64, pub size: u64, } -pub struct TextureRegion { - pub texture: Texture, + +impl BufferRange { + pub fn full() -> Self { + Self { + offset: 0, + size: u64::MAX, + } + } +} + +#[derive(Debug, Clone, Copy)] +pub struct BufferRows { + pub offset: u64, + pub row_count: u32, + pub row_size: u32, +} + +#[derive(Debug, Clone, Copy)] +pub struct TextureRange { pub aspect: vk::ImageAspectFlags, pub mip_level: u32, pub array_layers: MipRange, - pub origin: (u32, u32, u32), + pub origin: (i32, i32, i32), pub extent: (u32, u32, u32), } +impl TextureRange { + pub fn offset(&self) -> vk::Offset3D { + vk::Offset3D { + x: self.origin.0, + y: self.origin.1, + z: self.origin.2, + } + } + pub fn extent(&self) -> vk::Extent3D { + vk::Extent3D { + width: self.extent.0, + height: self.extent.1, + depth: self.extent.2, + } + } +} + +impl From for ResourceRange { + fn from(value: TextureRange) -> Self { + ResourceRange::Texture { + aspect: value.aspect, + mip_level: value.mip_level, + array_layers: value.array_layers, + origin: value.origin, + extent: value.extent, + } + } +} + +impl From for ResourceRange { + fn from(value: BufferRange) -> Self { + ResourceRange::Buffer { + offset: value.offset, + size: value.size, + } + } +} + +impl TextureRange { + pub fn full() -> Self { + Self { + aspect: vk::ImageAspectFlags::COLOR + | vk::ImageAspectFlags::DEPTH + | vk::ImageAspectFlags::STENCIL, + mip_level: 0, + array_layers: MipRange::default(), + origin: (0, 0, 0), + extent: (u32::MAX, u32::MAX, u32::MAX), + } + } +} + +pub struct Buffer(ResourceId); +pub struct Texture(ResourceId); + +pub struct BufferSlice { + pub buffer: Buffer, + pub range: BufferRange, +} + +pub struct BufferSlices { + pub buffer: Buffer, + pub ranges: Vec, +} + +pub struct BufferRowSlice { + pub buffer: Buffer, + pub row: BufferRows, +} + +pub struct BufferRowSlices { + pub buffer: Buffer, + pub rows: Vec, +} + +pub struct TextureRegion { + pub texture: Texture, + pub range: TextureRange, +} + +pub struct TextureRegions { + pub texture: Texture, + pub ranges: Vec, +} + pub struct Read(pub T); pub struct Write(pub T); pub struct ReadWrite(pub T); + +impl Deref for Read { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Deref for Write { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Deref for ReadWrite { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.0 + } +}