Allow executing raw secondary command buffers (#2422)

This commit is contained in:
marc0246 2023-12-10 19:43:19 +01:00 committed by GitHub
parent dd2918f12e
commit 1b0903d378
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 10 deletions

View File

@ -171,6 +171,12 @@ impl Debug for SecondaryAutoCommandBuffer {
} }
impl SecondaryAutoCommandBuffer { impl SecondaryAutoCommandBuffer {
/// Returns the inner raw command buffer.
#[inline]
pub fn inner(&self) -> &RawCommandBuffer {
&self.inner
}
/// Returns the usage of this command buffer. /// Returns the usage of this command buffer.
#[inline] #[inline]
pub fn usage(&self) -> CommandBufferUsage { pub fn usage(&self) -> CommandBufferUsage {

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
command_buffer::{ command_buffer::{
auto::{RenderPassStateType, Resource, ResourceUseRef2}, auto::{RenderPassStateType, Resource, ResourceUseRef2},
sys::RawRecordingCommandBuffer, sys::{RawCommandBuffer, RawRecordingCommandBuffer},
CommandBufferInheritanceRenderPassType, CommandBufferLevel, RecordingCommandBuffer, CommandBufferInheritanceRenderPassType, CommandBufferLevel, RecordingCommandBuffer,
ResourceInCommand, SecondaryAutoCommandBuffer, SecondaryCommandBufferBufferUsage, ResourceInCommand, SecondaryAutoCommandBuffer, SecondaryCommandBufferBufferUsage,
SecondaryCommandBufferImageUsage, SecondaryCommandBufferResourcesUsage, SubpassContents, SecondaryCommandBufferImageUsage, SecondaryCommandBufferResourcesUsage, SubpassContents,
@ -11,7 +11,7 @@ use crate::{
Requires, RequiresAllOf, RequiresOneOf, SafeDeref, ValidationError, VulkanObject, Requires, RequiresAllOf, RequiresOneOf, SafeDeref, ValidationError, VulkanObject,
}; };
use smallvec::{smallvec, SmallVec}; 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. /// # Commands to execute a secondary command buffer inside a primary command buffer.
/// ///
@ -58,7 +58,7 @@ impl<L> RecordingCommandBuffer<L> {
command_buffers: impl Iterator<Item = &'a SecondaryAutoCommandBuffer> + Clone, command_buffers: impl Iterator<Item = &'a SecondaryAutoCommandBuffer> + Clone,
) -> Result<(), Box<ValidationError>> { ) -> Result<(), Box<ValidationError>> {
self.inner 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 let Some(render_pass_state) = &self.builder_state.render_pass {
if render_pass_state.contents != SubpassContents::SecondaryCommandBuffers { if render_pass_state.contents != SubpassContents::SecondaryCommandBuffers {
@ -552,16 +552,16 @@ impl RawRecordingCommandBuffer {
#[inline] #[inline]
pub unsafe fn execute_commands( pub unsafe fn execute_commands(
&mut self, &mut self,
command_buffers: &[Arc<SecondaryAutoCommandBuffer>], command_buffers: &[&RawCommandBuffer],
) -> Result<&mut Self, Box<ValidationError>> { ) -> Result<&mut Self, Box<ValidationError>> {
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)) Ok(self.execute_commands_unchecked(command_buffers))
} }
fn validate_execute_commands<'a>( fn validate_execute_commands<'a>(
&self, &self,
command_buffers: impl Iterator<Item = &'a SecondaryAutoCommandBuffer>, command_buffers: impl Iterator<Item = &'a RawCommandBuffer>,
) -> Result<(), Box<ValidationError>> { ) -> Result<(), Box<ValidationError>> {
if self.level() != CommandBufferLevel::Primary { if self.level() != CommandBufferLevel::Primary {
return Err(Box::new(ValidationError { 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 // VUID-vkCmdExecuteCommands-commonparent
assert_eq!(self.device(), command_buffer.device()); 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: // TODO:
// VUID-vkCmdExecuteCommands-pCommandBuffers-00094 // VUID-vkCmdExecuteCommands-pCommandBuffers-00094
} }
@ -599,9 +608,8 @@ impl RawRecordingCommandBuffer {
// VUID-vkCmdExecuteCommands-pCommandBuffers-00093 // VUID-vkCmdExecuteCommands-pCommandBuffers-00093
// VUID-vkCmdExecuteCommands-pCommandBuffers-00105 // VUID-vkCmdExecuteCommands-pCommandBuffers-00105
// VUID-vkCmdExecuteCommands-pCommandBuffers-00088
// VUID-vkCmdExecuteCommands-pCommandBuffers-00089 // VUID-vkCmdExecuteCommands-pCommandBuffers-00089
// Ensured by the SecondaryCommandBuffer trait. // Partially ensured by the `RawCommandBuffer` type.
Ok(()) Ok(())
} }
@ -609,7 +617,7 @@ impl RawRecordingCommandBuffer {
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn execute_commands_unchecked( pub unsafe fn execute_commands_unchecked(
&mut self, &mut self,
command_buffers: &[Arc<SecondaryAutoCommandBuffer>], command_buffers: &[&RawCommandBuffer],
) -> &mut Self { ) -> &mut Self {
if command_buffers.is_empty() { if command_buffers.is_empty() {
return self; return self;