command impls

This commit is contained in:
janis 2026-04-12 10:33:59 +02:00
parent 15afc00e51
commit 666e05bb8e
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
6 changed files with 558 additions and 222 deletions

View file

@ -920,6 +920,10 @@ mod command_pools {
level: this.level,
})
}
pub fn raw(&self) -> vk::CommandBuffer {
self.handle()
}
}
pub struct CommandBufferFuture {

View file

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

View file

@ -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<BufferSlice>,
pub dst: Write<BufferSlice>,
}
// pub struct CopyBuffers {
// pub src: Read<BufferSlice>,
// pub dst: Write<BufferSlice>,
// }
pub struct CopyTextures {
pub src: Read<TextureRegion>,
pub dst: Write<TextureRegion>,
}
// pub struct CopyTextures {
// pub src: Read<TextureRegion>,
// pub dst: Write<TextureRegion>,
// }
pub struct CopyBufferToTexture {
pub src: Read<BufferSlice>,
pub dst: Write<TextureRegion>,
}
// pub struct CopyBufferToTexture {
// pub src: Read<BufferSlice>,
// pub dst: Write<TextureRegion>,
// }
pub struct CopyTextureToBuffer {
pub src: Read<TextureRegion>,
pub dst: Write<BufferSlice>,
}
// pub struct CopyTextureToBuffer {
// pub src: Read<TextureRegion>,
// pub dst: Write<BufferSlice>,
// }
pub struct Copy<T: Resource, U: Resource> {
pub src: Read<T>,
@ -43,48 +45,122 @@ pub struct Copy<T: Resource, U: Resource> {
}
impl<T: Resource, U: Resource> Copy<T, U> {
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<BufferSlice, TextureRegion> {
impl Command for Copy<BufferRowSlice, TextureRegion> {
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<TextureRegion, BufferSlice> {
}
impl Command for Copy<BufferRowSlices, TextureRegions> {
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::<Vec<_>>();
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);
}
}
}
fn get_meta(&self) -> CommandMeta {
CommandMeta {
apply_command: |recorder, command_ptr, cursor| {
let command = unsafe { command_ptr.cast::<Self>().read() };
*cursor += std::mem::size_of::<Self>();
command.apply(recorder);
},
impl Command for Copy<TextureRegion, BufferRowSlice> {
fn side_effects(&self, map: SideEffectMap) {
self.side_effects_inner(map)
}
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<TextureRegion, TextureRegion> {
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<BufferSlice, BufferSlice> {
@ -102,8 +209,25 @@ impl Command for Copy<BufferSlice, BufferSlice> {
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<Write<TextureRegion>>,
pub depth_attachment: Option<Write<TextureRegion>>,
pub stencil_attachment: Option<Write<TextureRegion>>,
@ -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<BufferSlice>, 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<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 {
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<T: IsDrawData> Command for Draw<T> {
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::<Self>().read() };
*cursor += std::mem::size_of::<Self>();
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<T: Resource, U: Resource> OutsideRenderPass for Copy<T, U> {}
impl OutsideRenderPass for ClearTexture {}
impl OutsideRenderPass for UpdateBuffer {}

View file

@ -1,3 +1,5 @@
#![allow(dead_code)]
mod legacy;
pub use legacy::*;

View file

@ -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<C: Command + InsideRenderPass>(&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<C: Command>(&mut self, command: C) {
pub fn begin_rendering(
&mut self,
color_attachments: Vec<Write<TextureRegion>>,
depth_attachment: Option<Write<TextureRegion>>,
stencil_attachment: Option<Write<TextureRegion>>,
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<C: Command + OutsideRenderPass>(&mut self, command: C) {
self.push_inner(command);
}
fn push_inner<C: Command>(&mut self, command: C) {
struct Packed<C> {
meta: CommandMeta,
command: C,

View file

@ -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()
}
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()
}
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) {
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<T: AsResourceRange> AsResourceRange for Read<T> {
fn into_access(&self) -> ResourceRange {
self.0.into_access()
}
}
impl<T: AsResourceRange> AsResourceRange for Write<T> {
fn into_access(&self) -> ResourceRange {
self.0.into_access()
}
}
impl<T: AsResourceRange> AsResourceRange for ReadWrite<T> {
fn into_access(&self) -> ResourceRange {
self.0.into_access()
}
}
impl<T: Resource> Resource for Read<T> {
fn id(&self) -> ResourceId {
self.0.id()
}
fn side_effect(&self, map: SideEffectMap, access: vk::AccessFlags2) {
self.0.side_effect(map, access);
}
}
impl<T: Resource> Resource for Write<T> {
fn id(&self) -> ResourceId {
self.0.id()
}
fn side_effect(&self, map: SideEffectMap, access: vk::AccessFlags2) {
self.0.side_effect(map, access);
}
}
impl<T: Resource> Resource for ReadWrite<T> {
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<TextureRange> 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<BufferRange> 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<BufferRange>,
}
pub struct BufferRowSlice {
pub buffer: Buffer,
pub row: BufferRows,
}
pub struct BufferRowSlices {
pub buffer: Buffer,
pub rows: Vec<BufferRows>,
}
pub struct TextureRegion {
pub texture: Texture,
pub range: TextureRange,
}
pub struct TextureRegions {
pub texture: Texture,
pub ranges: Vec<TextureRange>,
}
pub struct Read<T>(pub T);
pub struct Write<T>(pub T);
pub struct ReadWrite<T>(pub T);
impl<T> Deref for Read<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> Deref for Write<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> Deref for ReadWrite<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}