From 1b0903d3783a69c3eacbc525871cfa14184c886e Mon Sep 17 00:00:00 2001 From: marc0246 <40955683+marc0246@users.noreply.github.com> Date: Sun, 10 Dec 2023 19:43:19 +0100 Subject: [PATCH] Allow executing raw secondary command buffers (#2422) --- vulkano/src/command_buffer/auto/mod.rs | 6 ++++ .../src/command_buffer/commands/secondary.rs | 28 ++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/vulkano/src/command_buffer/auto/mod.rs b/vulkano/src/command_buffer/auto/mod.rs index f8ef5e20..cbd6b93d 100644 --- a/vulkano/src/command_buffer/auto/mod.rs +++ b/vulkano/src/command_buffer/auto/mod.rs @@ -171,6 +171,12 @@ impl Debug for SecondaryAutoCommandBuffer { } impl SecondaryAutoCommandBuffer { + /// Returns the inner raw command buffer. + #[inline] + pub fn inner(&self) -> &RawCommandBuffer { + &self.inner + } + /// Returns the usage of this command buffer. #[inline] pub fn usage(&self) -> CommandBufferUsage { diff --git a/vulkano/src/command_buffer/commands/secondary.rs b/vulkano/src/command_buffer/commands/secondary.rs index e7a247d1..786f8d41 100644 --- a/vulkano/src/command_buffer/commands/secondary.rs +++ b/vulkano/src/command_buffer/commands/secondary.rs @@ -1,7 +1,7 @@ use crate::{ command_buffer::{ auto::{RenderPassStateType, Resource, ResourceUseRef2}, - sys::RawRecordingCommandBuffer, + sys::{RawCommandBuffer, RawRecordingCommandBuffer}, CommandBufferInheritanceRenderPassType, CommandBufferLevel, RecordingCommandBuffer, ResourceInCommand, SecondaryAutoCommandBuffer, SecondaryCommandBufferBufferUsage, SecondaryCommandBufferImageUsage, SecondaryCommandBufferResourcesUsage, SubpassContents, @@ -11,7 +11,7 @@ use crate::{ Requires, RequiresAllOf, RequiresOneOf, SafeDeref, ValidationError, VulkanObject, }; use smallvec::{smallvec, SmallVec}; -use std::{cmp::min, iter, ops::Deref, sync::Arc}; +use std::{cmp::min, iter, sync::Arc}; /// # Commands to execute a secondary command buffer inside a primary command buffer. /// @@ -58,7 +58,7 @@ impl RecordingCommandBuffer { command_buffers: impl Iterator + Clone, ) -> Result<(), Box> { self.inner - .validate_execute_commands(command_buffers.clone())?; + .validate_execute_commands(command_buffers.clone().map(|cb| cb.inner()))?; if let Some(render_pass_state) = &self.builder_state.render_pass { if render_pass_state.contents != SubpassContents::SecondaryCommandBuffers { @@ -552,16 +552,16 @@ impl RawRecordingCommandBuffer { #[inline] pub unsafe fn execute_commands( &mut self, - command_buffers: &[Arc], + command_buffers: &[&RawCommandBuffer], ) -> Result<&mut Self, Box> { - self.validate_execute_commands(command_buffers.iter().map(Deref::deref))?; + self.validate_execute_commands(command_buffers.iter().copied())?; Ok(self.execute_commands_unchecked(command_buffers)) } fn validate_execute_commands<'a>( &self, - command_buffers: impl Iterator, + command_buffers: impl Iterator, ) -> Result<(), Box> { if self.level() != CommandBufferLevel::Primary { return Err(Box::new(ValidationError { @@ -585,10 +585,19 @@ impl RawRecordingCommandBuffer { })); } - for (_command_buffer_index, command_buffer) in command_buffers.enumerate() { + for (command_buffer_index, command_buffer) in command_buffers.enumerate() { // VUID-vkCmdExecuteCommands-commonparent assert_eq!(self.device(), command_buffer.device()); + if command_buffer.level() != CommandBufferLevel::Secondary { + return Err(Box::new(ValidationError { + context: format!("command_buffers[{}]", command_buffer_index).into(), + problem: "is not a secondary command buffer".into(), + vuids: &["VUID-vkCmdExecuteCommands-pCommandBuffers-00088"], + ..Default::default() + })); + } + // TODO: // VUID-vkCmdExecuteCommands-pCommandBuffers-00094 } @@ -599,9 +608,8 @@ impl RawRecordingCommandBuffer { // VUID-vkCmdExecuteCommands-pCommandBuffers-00093 // VUID-vkCmdExecuteCommands-pCommandBuffers-00105 - // VUID-vkCmdExecuteCommands-pCommandBuffers-00088 // VUID-vkCmdExecuteCommands-pCommandBuffers-00089 - // Ensured by the SecondaryCommandBuffer trait. + // Partially ensured by the `RawCommandBuffer` type. Ok(()) } @@ -609,7 +617,7 @@ impl RawRecordingCommandBuffer { #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] pub unsafe fn execute_commands_unchecked( &mut self, - command_buffers: &[Arc], + command_buffers: &[&RawCommandBuffer], ) -> &mut Self { if command_buffers.is_empty() { return self;