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 {
/// 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 {

View File

@ -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<L> RecordingCommandBuffer<L> {
command_buffers: impl Iterator<Item = &'a SecondaryAutoCommandBuffer> + Clone,
) -> Result<(), Box<ValidationError>> {
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<SecondaryAutoCommandBuffer>],
command_buffers: &[&RawCommandBuffer],
) -> 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))
}
fn validate_execute_commands<'a>(
&self,
command_buffers: impl Iterator<Item = &'a SecondaryAutoCommandBuffer>,
command_buffers: impl Iterator<Item = &'a RawCommandBuffer>,
) -> Result<(), Box<ValidationError>> {
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<SecondaryAutoCommandBuffer>],
command_buffers: &[&RawCommandBuffer],
) -> &mut Self {
if command_buffers.is_empty() {
return self;