Skip to content

Commit

Permalink
Add basic synchronization tracking to CommandBufferBuilder (#2099)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rua authored Dec 7, 2022
1 parent def369d commit 10d7349
Show file tree
Hide file tree
Showing 16 changed files with 2,898 additions and 267 deletions.
1 change: 1 addition & 0 deletions vulkano/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ crossbeam-queue = "0.3"
half = "2"
libloading = "0.7"
nalgebra = { version = "0.31.0", optional = true }
once_cell = "1.16"
parking_lot = { version = "0.12", features = ["send_guard"] }
smallvec = "1.8"
thread_local = "1.1"
Expand Down
1 change: 1 addition & 0 deletions vulkano/src/command_buffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ pub enum ResourceInCommand {
DescriptorSet { set: u32, binding: u32, index: u32 },
Destination,
FramebufferAttachment { index: u32 },
ImageMemoryBarrier { index: u32 },
IndexBuffer,
IndirectBuffer,
SecondaryCommandBuffer { index: u32 },
Expand Down
30 changes: 18 additions & 12 deletions vulkano/src/command_buffer/standard/builder/bind_push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ where
dynamic_offsets.as_ptr(),
);

let state = self.current_state.invalidate_descriptor_sets(
let state = self.builder_state.invalidate_descriptor_sets(
pipeline_bind_point,
pipeline_layout.clone(),
first_set,
Expand All @@ -189,6 +189,7 @@ where

self.resources.push(Box::new(pipeline_layout));

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -271,9 +272,10 @@ where
index_type.into(),
);

self.current_state.index_buffer = Some((buffer.clone(), index_type));
self.builder_state.index_buffer = Some((buffer.clone(), index_type));
self.resources.push(Box::new(buffer));

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -321,9 +323,10 @@ where
pipeline.handle(),
);

self.current_state.pipeline_compute = Some(pipeline.clone());
self.builder_state.pipeline_compute = Some(pipeline.clone());
self.resources.push(Box::new(pipeline));

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -357,12 +360,12 @@ where
assert_eq!(self.device(), pipeline.device());

if let Some(last_pipeline) =
self.current_state
self.builder_state
.render_pass
.as_ref()
.and_then(|render_pass_state| match &render_pass_state.render_pass {
RenderPassStateType::BeginRendering(state) if state.pipeline_used => {
self.current_state.pipeline_graphics.as_ref()
self.builder_state.pipeline_graphics.as_ref()
}
_ => None,
})
Expand Down Expand Up @@ -416,15 +419,16 @@ where

// Reset any states that are fixed in the new pipeline. The pipeline bind command will
// overwrite these states.
self.current_state.reset_dynamic_states(
self.builder_state.reset_dynamic_states(
pipeline
.dynamic_states()
.filter(|(_, d)| !d) // not dynamic
.map(|(s, _)| s),
);
self.current_state.pipeline_graphics = Some(pipeline.clone());
self.builder_state.pipeline_graphics = Some(pipeline.clone());
self.resources.push(Box::new(pipeline));

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -532,12 +536,13 @@ where
self.resources.reserve(buffers.len());

for (i, buffer) in buffers.into_iter().enumerate() {
self.current_state
self.builder_state
.vertex_buffers
.insert(first_binding + i as u32, buffer.clone());
self.resources.push(Box::new(buffer));
}

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -667,13 +672,13 @@ where
// push constants as set, and never unsets them. See:
// https://github.com/KhronosGroup/Vulkan-Docs/issues/1485
// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/2711
self.current_state
self.builder_state
.push_constants
.insert(offset..offset + push_constants.len() as u32);
self.current_state.push_constants_pipeline_layout = Some(pipeline_layout.clone());

self.builder_state.push_constants_pipeline_layout = Some(pipeline_layout.clone());
self.resources.push(Box::new(pipeline_layout));

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -841,7 +846,7 @@ where
writes.as_ptr(),
);

let state = self.current_state.invalidate_descriptor_sets(
let state = self.builder_state.invalidate_descriptor_sets(
pipeline_bind_point,
pipeline_layout.clone(),
set_num,
Expand All @@ -863,6 +868,7 @@ where

self.resources.push(Box::new(pipeline_layout));

self.next_command_index += 1;
self
}
}
115 changes: 100 additions & 15 deletions vulkano/src/command_buffer/standard/builder/clear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ use super::{
};
use crate::{
buffer::{BufferAccess, BufferContents, BufferUsage, TypedBufferAccess},
command_buffer::allocator::CommandBufferAllocator,
command_buffer::{allocator::CommandBufferAllocator, ResourceInCommand, ResourceUseRef},
device::{DeviceOwned, QueueFlags},
format::FormatFeatures,
image::{ImageAccess, ImageAspects, ImageLayout, ImageUsage},
sync::PipelineStageAccess,
DeviceSize, RequiresOneOf, Version, VulkanObject,
};
use smallvec::SmallVec;
Expand Down Expand Up @@ -50,7 +51,7 @@ where
let device = self.device();

// VUID-vkCmdClearColorImage-renderpass
if self.current_state.render_pass.is_some() {
if self.builder_state.render_pass.is_some() {
return Err(ClearError::ForbiddenInsideRenderPass);
}

Expand Down Expand Up @@ -193,6 +194,7 @@ where
return self;
}

let image_inner = image.inner();
let clear_value = clear_value.into();
let ranges: SmallVec<[_; 8]> = regions
.iter()
Expand All @@ -203,17 +205,40 @@ where
let fns = self.device().fns();
(fns.v1_0.cmd_clear_color_image)(
self.handle(),
image.inner().image.handle(),
image_inner.image.handle(),
image_layout.into(),
&clear_value,
ranges.len() as u32,
ranges.as_ptr(),
);

self.resources.push(Box::new(image));
let command_index = self.next_command_index;
let command_name = "clear_color_image";
let use_ref = ResourceUseRef {
command_index,
command_name,
resource_in_command: ResourceInCommand::Destination,
secondary_use_ref: None,
};

for mut subresource_range in regions {
subresource_range.array_layers.start += image_inner.first_layer;
subresource_range.array_layers.end += image_inner.first_layer;
subresource_range.mip_levels.start += image_inner.first_mipmap_level;
subresource_range.mip_levels.end += image_inner.first_mipmap_level;

self.resources_usage_state.record_image_access(
&use_ref,
image_inner.image,
subresource_range,
PipelineStageAccess::Clear_TransferWrite,
image_layout,
);
}

// TODO: sync state update
self.resources.push(Box::new(image));

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -241,7 +266,7 @@ where
let device = self.device();

// VUID-vkCmdClearDepthStencilImage-renderpass
if self.current_state.render_pass.is_some() {
if self.builder_state.render_pass.is_some() {
return Err(ClearError::ForbiddenInsideRenderPass);
}

Expand Down Expand Up @@ -402,6 +427,7 @@ where
return self;
}

let image_inner = image.inner();
let clear_value = clear_value.into();
let ranges: SmallVec<[_; 8]> = regions
.iter()
Expand All @@ -412,17 +438,40 @@ where
let fns = self.device().fns();
(fns.v1_0.cmd_clear_depth_stencil_image)(
self.handle(),
image.inner().image.handle(),
image_inner.image.handle(),
image_layout.into(),
&clear_value,
ranges.len() as u32,
ranges.as_ptr(),
);

self.resources.push(Box::new(image));
let command_index = self.next_command_index;
let command_name = "clear_depth_stencil_image";
let use_ref = ResourceUseRef {
command_index,
command_name,
resource_in_command: ResourceInCommand::Destination,
secondary_use_ref: None,
};

for mut subresource_range in regions {
subresource_range.array_layers.start += image_inner.first_layer;
subresource_range.array_layers.end += image_inner.first_layer;
subresource_range.mip_levels.start += image_inner.first_mipmap_level;
subresource_range.mip_levels.end += image_inner.first_mipmap_level;

self.resources_usage_state.record_image_access(
&use_ref,
image_inner.image,
subresource_range,
PipelineStageAccess::Clear_TransferWrite,
image_layout,
);
}

// TODO: sync state update
self.resources.push(Box::new(image));

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -453,7 +502,7 @@ where
let device = self.device();

// VUID-vkCmdFillBuffer-renderpass
if self.current_state.render_pass.is_some() {
if self.builder_state.render_pass.is_some() {
return Err(ClearError::ForbiddenInsideRenderPass);
}

Expand Down Expand Up @@ -554,10 +603,28 @@ where
data,
);

self.resources.push(Box::new(dst_buffer));
let command_index = self.next_command_index;
let command_name = "fill_buffer";
let use_ref = ResourceUseRef {
command_index,
command_name,
resource_in_command: ResourceInCommand::Destination,
secondary_use_ref: None,
};

let mut dst_range = dst_offset..dst_offset + size;
dst_range.start += dst_buffer_inner.offset;
dst_range.end += dst_buffer_inner.offset;
self.resources_usage_state.record_buffer_access(
&use_ref,
dst_buffer_inner.buffer,
dst_range,
PipelineStageAccess::Clear_TransferWrite,
);

// TODO: sync state update
self.resources.push(Box::new(dst_buffer));

self.next_command_index += 1;
self
}

Expand Down Expand Up @@ -596,7 +663,7 @@ where
let device = self.device();

// VUID-vkCmdUpdateBuffer-renderpass
if self.current_state.render_pass.is_some() {
if self.builder_state.render_pass.is_some() {
return Err(ClearError::ForbiddenInsideRenderPass);
}

Expand Down Expand Up @@ -684,10 +751,28 @@ where
data.as_bytes().as_ptr() as *const _,
);

self.resources.push(Box::new(dst_buffer));
let command_index = self.next_command_index;
let command_name = "update_buffer";
let use_ref = ResourceUseRef {
command_index,
command_name,
resource_in_command: ResourceInCommand::Destination,
secondary_use_ref: None,
};

let mut dst_range = dst_offset..dst_offset + size_of_val(data) as DeviceSize;
dst_range.start += dst_buffer_inner.offset;
dst_range.end += dst_buffer_inner.offset;
self.resources_usage_state.record_buffer_access(
&use_ref,
dst_buffer_inner.buffer,
dst_range,
PipelineStageAccess::Clear_TransferWrite,
);

// TODO: sync state update
self.resources.push(Box::new(dst_buffer));

self.next_command_index += 1;
self
}
}
Loading

0 comments on commit 10d7349

Please sign in to comment.