Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic synchronization tracking to CommandBufferBuilder #2099

Merged
merged 1 commit into from
Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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