commandbuffer: tracking state and fn end()
This commit is contained in:
parent
f3cc43e49e
commit
2fc7d3e179
|
@ -1,4 +1,4 @@
|
|||
use std::sync::Arc;
|
||||
use std::sync::{atomic::AtomicU8, Arc};
|
||||
|
||||
use crate::{
|
||||
define_device_owned_handle,
|
||||
|
@ -116,10 +116,66 @@ impl<T: CommandBuffer> CommandList<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum CommandBufferState {
|
||||
Initial = 0,
|
||||
Recording,
|
||||
Executable,
|
||||
Pending,
|
||||
Invalid,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(transparent)]
|
||||
struct CommandBufferState2(AtomicU8);
|
||||
impl CommandBufferState2 {
|
||||
fn initial() -> Self {
|
||||
Self(AtomicU8::new(CommandBufferState::Initial as u8))
|
||||
}
|
||||
fn recording() -> Self {
|
||||
Self(AtomicU8::new(CommandBufferState::Recording as u8))
|
||||
}
|
||||
|
||||
fn state(&self) -> CommandBufferState {
|
||||
let value = self.0.load(std::sync::atomic::Ordering::Relaxed);
|
||||
unsafe { *<*const _>::from(&value).cast::<CommandBufferState>() }
|
||||
}
|
||||
|
||||
fn is_initial(&self) -> bool {
|
||||
self.0.load(std::sync::atomic::Ordering::Relaxed) == 0
|
||||
}
|
||||
fn set_executable(&self) {
|
||||
self.0.store(
|
||||
CommandBufferState::Executable as u8,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
);
|
||||
}
|
||||
fn set_recording(&self) {
|
||||
self.0.store(
|
||||
CommandBufferState::Recording as u8,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
);
|
||||
}
|
||||
fn set_pending(&self) {
|
||||
self.0.store(
|
||||
CommandBufferState::Pending as u8,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
);
|
||||
}
|
||||
fn set_invalid(&self) {
|
||||
self.0.store(
|
||||
CommandBufferState::Invalid as u8,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
define_device_owned_handle! {
|
||||
#[derive(Debug)]
|
||||
pub SingleUseCommand(vk::CommandBuffer) {
|
||||
pool: Arc<SingleUseCommandPool>,
|
||||
pool: Arc<SingleUseCommandPool>,
|
||||
state: CommandBufferState2,
|
||||
} => |this| unsafe {
|
||||
this.pool
|
||||
.pool
|
||||
|
@ -147,7 +203,20 @@ impl SingleUseCommand {
|
|||
buffer
|
||||
};
|
||||
|
||||
Self::construct(device, buffer, None, pool)
|
||||
Self::construct(device, buffer, None, pool, CommandBufferState2::recording())
|
||||
}
|
||||
|
||||
pub fn state(&self) -> CommandBufferState {
|
||||
self.state.state()
|
||||
}
|
||||
|
||||
pub fn end(&self) -> VkResult<()> {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.inner.dev().dev().end_command_buffer(self.handle())?;
|
||||
}
|
||||
self.state.set_executable();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Safety: commandbuffer must not be accessed from multiple threads at the same time
|
||||
|
@ -169,6 +238,7 @@ impl SingleUseCommand {
|
|||
new_layout: vk::ImageLayout,
|
||||
queue_ownership_op: Option<QueueOwnership>,
|
||||
) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
let (src_family, dst_family) = queue_ownership_op
|
||||
.map(|t| (t.src, t.dst))
|
||||
.unwrap_or((vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED));
|
||||
|
@ -209,6 +279,7 @@ impl SingleUseCommand {
|
|||
dst: &Image,
|
||||
dst_region: util::Rect2D,
|
||||
) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device().dev().cmd_blit_image(
|
||||
self.buffer(),
|
||||
|
@ -241,6 +312,7 @@ impl SingleUseCommand {
|
|||
layout: vk::ImageLayout,
|
||||
regions: &[vk::BufferImageCopy],
|
||||
) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device().dev().cmd_copy_buffer_to_image(
|
||||
self.handle(),
|
||||
|
@ -253,6 +325,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
|
||||
pub fn copy_buffers(&self, src: vk::Buffer, dst: vk::Buffer, regions: &[vk::BufferCopy]) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device()
|
||||
.dev()
|
||||
|
@ -268,6 +341,7 @@ impl SingleUseCommand {
|
|||
dst_layout: vk::ImageLayout,
|
||||
regions: &[vk::ImageCopy],
|
||||
) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device().dev().cmd_copy_image(
|
||||
self.handle(),
|
||||
|
@ -288,6 +362,7 @@ impl SingleUseCommand {
|
|||
color: crate::Rgba,
|
||||
subresources: &[vk::ImageSubresourceRange],
|
||||
) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
let clear_colors = match format.get_component_kind() {
|
||||
crate::util::FormatComponentKind::Float => vk::ClearColorValue {
|
||||
float32: color.into_f32(),
|
||||
|
@ -312,6 +387,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
|
||||
pub fn begin_rendering(&self, rendering_info: vk::RenderingInfo<'_>) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device()
|
||||
.dev()
|
||||
|
@ -320,6 +396,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
|
||||
pub fn set_viewport(&self, viewports: &[vk::Viewport]) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device()
|
||||
.dev()
|
||||
|
@ -327,6 +404,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
}
|
||||
pub fn set_scissors(&self, scissors: &[vk::Rect2D]) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device()
|
||||
.dev()
|
||||
|
@ -340,6 +418,7 @@ impl SingleUseCommand {
|
|||
offset: u32,
|
||||
bytes: &[u8],
|
||||
) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device().dev().cmd_push_constants(
|
||||
self.handle(),
|
||||
|
@ -351,6 +430,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
}
|
||||
pub fn bind_pipeline(&self, pipeline: &Pipeline) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device().dev().cmd_bind_pipeline(
|
||||
self.buffer(),
|
||||
|
@ -360,6 +440,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
}
|
||||
pub fn bind_vertices(&self, buffer: vk::Buffer, offset: u64) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device()
|
||||
.dev()
|
||||
|
@ -367,6 +448,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
}
|
||||
pub fn bind_indices(&self, buffer: vk::Buffer, offset: u64, kind: vk::IndexType) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device()
|
||||
.dev()
|
||||
|
@ -380,6 +462,7 @@ impl SingleUseCommand {
|
|||
bind_point: vk::PipelineBindPoint,
|
||||
descriptor_sets: &[vk::DescriptorSet],
|
||||
) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
use crate::device::DeviceOwned;
|
||||
unsafe {
|
||||
self.device().dev().cmd_bind_descriptor_sets(
|
||||
|
@ -402,6 +485,7 @@ impl SingleUseCommand {
|
|||
vertex_offset: i32,
|
||||
instance_offset: u32,
|
||||
) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device().dev().cmd_draw_indexed(
|
||||
self.buffer(),
|
||||
|
@ -415,6 +499,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
|
||||
pub fn draw_indexed_indirect(&self, buffer: vk::Buffer, offset: u64, count: u32, stride: u32) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device().dev().cmd_draw_indexed_indirect(
|
||||
self.buffer(),
|
||||
|
@ -427,6 +512,7 @@ impl SingleUseCommand {
|
|||
}
|
||||
|
||||
pub fn end_rendering(&self) {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe {
|
||||
self.device().dev().cmd_end_rendering(self.buffer());
|
||||
}
|
||||
|
@ -438,6 +524,7 @@ impl SingleUseCommand {
|
|||
signal: Option<vk::Semaphore>,
|
||||
fence: Option<vk::Fence>,
|
||||
) -> VkResult<()> {
|
||||
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||
unsafe { self.device().dev().end_command_buffer(self.handle())? };
|
||||
|
||||
let buffers = [self.handle()];
|
||||
|
|
Loading…
Reference in a new issue