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::{
|
use crate::{
|
||||||
define_device_owned_handle,
|
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! {
|
define_device_owned_handle! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub SingleUseCommand(vk::CommandBuffer) {
|
pub SingleUseCommand(vk::CommandBuffer) {
|
||||||
pool: Arc<SingleUseCommandPool>,
|
pool: Arc<SingleUseCommandPool>,
|
||||||
|
state: CommandBufferState2,
|
||||||
} => |this| unsafe {
|
} => |this| unsafe {
|
||||||
this.pool
|
this.pool
|
||||||
.pool
|
.pool
|
||||||
|
@ -147,7 +203,20 @@ impl SingleUseCommand {
|
||||||
buffer
|
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
|
/// Safety: commandbuffer must not be accessed from multiple threads at the same time
|
||||||
|
@ -169,6 +238,7 @@ impl SingleUseCommand {
|
||||||
new_layout: vk::ImageLayout,
|
new_layout: vk::ImageLayout,
|
||||||
queue_ownership_op: Option<QueueOwnership>,
|
queue_ownership_op: Option<QueueOwnership>,
|
||||||
) {
|
) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
let (src_family, dst_family) = queue_ownership_op
|
let (src_family, dst_family) = queue_ownership_op
|
||||||
.map(|t| (t.src, t.dst))
|
.map(|t| (t.src, t.dst))
|
||||||
.unwrap_or((vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED));
|
.unwrap_or((vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED));
|
||||||
|
@ -209,6 +279,7 @@ impl SingleUseCommand {
|
||||||
dst: &Image,
|
dst: &Image,
|
||||||
dst_region: util::Rect2D,
|
dst_region: util::Rect2D,
|
||||||
) {
|
) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_blit_image(
|
self.device().dev().cmd_blit_image(
|
||||||
self.buffer(),
|
self.buffer(),
|
||||||
|
@ -241,6 +312,7 @@ impl SingleUseCommand {
|
||||||
layout: vk::ImageLayout,
|
layout: vk::ImageLayout,
|
||||||
regions: &[vk::BufferImageCopy],
|
regions: &[vk::BufferImageCopy],
|
||||||
) {
|
) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_copy_buffer_to_image(
|
self.device().dev().cmd_copy_buffer_to_image(
|
||||||
self.handle(),
|
self.handle(),
|
||||||
|
@ -253,6 +325,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn copy_buffers(&self, src: vk::Buffer, dst: vk::Buffer, regions: &[vk::BufferCopy]) {
|
pub fn copy_buffers(&self, src: vk::Buffer, dst: vk::Buffer, regions: &[vk::BufferCopy]) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device()
|
self.device()
|
||||||
.dev()
|
.dev()
|
||||||
|
@ -268,6 +341,7 @@ impl SingleUseCommand {
|
||||||
dst_layout: vk::ImageLayout,
|
dst_layout: vk::ImageLayout,
|
||||||
regions: &[vk::ImageCopy],
|
regions: &[vk::ImageCopy],
|
||||||
) {
|
) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_copy_image(
|
self.device().dev().cmd_copy_image(
|
||||||
self.handle(),
|
self.handle(),
|
||||||
|
@ -288,6 +362,7 @@ impl SingleUseCommand {
|
||||||
color: crate::Rgba,
|
color: crate::Rgba,
|
||||||
subresources: &[vk::ImageSubresourceRange],
|
subresources: &[vk::ImageSubresourceRange],
|
||||||
) {
|
) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
let clear_colors = match format.get_component_kind() {
|
let clear_colors = match format.get_component_kind() {
|
||||||
crate::util::FormatComponentKind::Float => vk::ClearColorValue {
|
crate::util::FormatComponentKind::Float => vk::ClearColorValue {
|
||||||
float32: color.into_f32(),
|
float32: color.into_f32(),
|
||||||
|
@ -312,6 +387,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn begin_rendering(&self, rendering_info: vk::RenderingInfo<'_>) {
|
pub fn begin_rendering(&self, rendering_info: vk::RenderingInfo<'_>) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device()
|
self.device()
|
||||||
.dev()
|
.dev()
|
||||||
|
@ -320,6 +396,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_viewport(&self, viewports: &[vk::Viewport]) {
|
pub fn set_viewport(&self, viewports: &[vk::Viewport]) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device()
|
self.device()
|
||||||
.dev()
|
.dev()
|
||||||
|
@ -327,6 +404,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn set_scissors(&self, scissors: &[vk::Rect2D]) {
|
pub fn set_scissors(&self, scissors: &[vk::Rect2D]) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device()
|
self.device()
|
||||||
.dev()
|
.dev()
|
||||||
|
@ -340,6 +418,7 @@ impl SingleUseCommand {
|
||||||
offset: u32,
|
offset: u32,
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
) {
|
) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_push_constants(
|
self.device().dev().cmd_push_constants(
|
||||||
self.handle(),
|
self.handle(),
|
||||||
|
@ -351,6 +430,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn bind_pipeline(&self, pipeline: &Pipeline) {
|
pub fn bind_pipeline(&self, pipeline: &Pipeline) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_bind_pipeline(
|
self.device().dev().cmd_bind_pipeline(
|
||||||
self.buffer(),
|
self.buffer(),
|
||||||
|
@ -360,6 +440,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn bind_vertices(&self, buffer: vk::Buffer, offset: u64) {
|
pub fn bind_vertices(&self, buffer: vk::Buffer, offset: u64) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device()
|
self.device()
|
||||||
.dev()
|
.dev()
|
||||||
|
@ -367,6 +448,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn bind_indices(&self, buffer: vk::Buffer, offset: u64, kind: vk::IndexType) {
|
pub fn bind_indices(&self, buffer: vk::Buffer, offset: u64, kind: vk::IndexType) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device()
|
self.device()
|
||||||
.dev()
|
.dev()
|
||||||
|
@ -380,6 +462,7 @@ impl SingleUseCommand {
|
||||||
bind_point: vk::PipelineBindPoint,
|
bind_point: vk::PipelineBindPoint,
|
||||||
descriptor_sets: &[vk::DescriptorSet],
|
descriptor_sets: &[vk::DescriptorSet],
|
||||||
) {
|
) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
use crate::device::DeviceOwned;
|
use crate::device::DeviceOwned;
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_bind_descriptor_sets(
|
self.device().dev().cmd_bind_descriptor_sets(
|
||||||
|
@ -402,6 +485,7 @@ impl SingleUseCommand {
|
||||||
vertex_offset: i32,
|
vertex_offset: i32,
|
||||||
instance_offset: u32,
|
instance_offset: u32,
|
||||||
) {
|
) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_draw_indexed(
|
self.device().dev().cmd_draw_indexed(
|
||||||
self.buffer(),
|
self.buffer(),
|
||||||
|
@ -415,6 +499,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_indexed_indirect(&self, buffer: vk::Buffer, offset: u64, count: u32, stride: u32) {
|
pub fn draw_indexed_indirect(&self, buffer: vk::Buffer, offset: u64, count: u32, stride: u32) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_draw_indexed_indirect(
|
self.device().dev().cmd_draw_indexed_indirect(
|
||||||
self.buffer(),
|
self.buffer(),
|
||||||
|
@ -427,6 +512,7 @@ impl SingleUseCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end_rendering(&self) {
|
pub fn end_rendering(&self) {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe {
|
unsafe {
|
||||||
self.device().dev().cmd_end_rendering(self.buffer());
|
self.device().dev().cmd_end_rendering(self.buffer());
|
||||||
}
|
}
|
||||||
|
@ -438,6 +524,7 @@ impl SingleUseCommand {
|
||||||
signal: Option<vk::Semaphore>,
|
signal: Option<vk::Semaphore>,
|
||||||
fence: Option<vk::Fence>,
|
fence: Option<vk::Fence>,
|
||||||
) -> VkResult<()> {
|
) -> VkResult<()> {
|
||||||
|
assert_eq!(self.state(), CommandBufferState::Recording);
|
||||||
unsafe { self.device().dev().end_command_buffer(self.handle())? };
|
unsafe { self.device().dev().end_command_buffer(self.handle())? };
|
||||||
|
|
||||||
let buffers = [self.handle()];
|
let buffers = [self.handle()];
|
||||||
|
|
Loading…
Reference in a new issue