mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-26 00:34:19 +00:00
Add basic synchronization tracking to CommandBufferBuilder
(#2099)
This commit is contained in:
parent
def369dced
commit
10d7349556
@ -23,6 +23,7 @@ crossbeam-queue = "0.3"
|
|||||||
half = "2"
|
half = "2"
|
||||||
libloading = "0.7"
|
libloading = "0.7"
|
||||||
nalgebra = { version = "0.31.0", optional = true }
|
nalgebra = { version = "0.31.0", optional = true }
|
||||||
|
once_cell = "1.16"
|
||||||
parking_lot = { version = "0.12", features = ["send_guard"] }
|
parking_lot = { version = "0.12", features = ["send_guard"] }
|
||||||
smallvec = "1.8"
|
smallvec = "1.8"
|
||||||
thread_local = "1.1"
|
thread_local = "1.1"
|
||||||
|
@ -597,6 +597,7 @@ pub enum ResourceInCommand {
|
|||||||
DescriptorSet { set: u32, binding: u32, index: u32 },
|
DescriptorSet { set: u32, binding: u32, index: u32 },
|
||||||
Destination,
|
Destination,
|
||||||
FramebufferAttachment { index: u32 },
|
FramebufferAttachment { index: u32 },
|
||||||
|
ImageMemoryBarrier { index: u32 },
|
||||||
IndexBuffer,
|
IndexBuffer,
|
||||||
IndirectBuffer,
|
IndirectBuffer,
|
||||||
SecondaryCommandBuffer { index: u32 },
|
SecondaryCommandBuffer { index: u32 },
|
||||||
|
@ -166,7 +166,7 @@ where
|
|||||||
dynamic_offsets.as_ptr(),
|
dynamic_offsets.as_ptr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let state = self.current_state.invalidate_descriptor_sets(
|
let state = self.builder_state.invalidate_descriptor_sets(
|
||||||
pipeline_bind_point,
|
pipeline_bind_point,
|
||||||
pipeline_layout.clone(),
|
pipeline_layout.clone(),
|
||||||
first_set,
|
first_set,
|
||||||
@ -189,6 +189,7 @@ where
|
|||||||
|
|
||||||
self.resources.push(Box::new(pipeline_layout));
|
self.resources.push(Box::new(pipeline_layout));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,9 +272,10 @@ where
|
|||||||
index_type.into(),
|
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.resources.push(Box::new(buffer));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,9 +323,10 @@ where
|
|||||||
pipeline.handle(),
|
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.resources.push(Box::new(pipeline));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,12 +360,12 @@ where
|
|||||||
assert_eq!(self.device(), pipeline.device());
|
assert_eq!(self.device(), pipeline.device());
|
||||||
|
|
||||||
if let Some(last_pipeline) =
|
if let Some(last_pipeline) =
|
||||||
self.current_state
|
self.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|render_pass_state| match &render_pass_state.render_pass {
|
.and_then(|render_pass_state| match &render_pass_state.render_pass {
|
||||||
RenderPassStateType::BeginRendering(state) if state.pipeline_used => {
|
RenderPassStateType::BeginRendering(state) if state.pipeline_used => {
|
||||||
self.current_state.pipeline_graphics.as_ref()
|
self.builder_state.pipeline_graphics.as_ref()
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
@ -416,15 +419,16 @@ where
|
|||||||
|
|
||||||
// Reset any states that are fixed in the new pipeline. The pipeline bind command will
|
// Reset any states that are fixed in the new pipeline. The pipeline bind command will
|
||||||
// overwrite these states.
|
// overwrite these states.
|
||||||
self.current_state.reset_dynamic_states(
|
self.builder_state.reset_dynamic_states(
|
||||||
pipeline
|
pipeline
|
||||||
.dynamic_states()
|
.dynamic_states()
|
||||||
.filter(|(_, d)| !d) // not dynamic
|
.filter(|(_, d)| !d) // not dynamic
|
||||||
.map(|(s, _)| s),
|
.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.resources.push(Box::new(pipeline));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,12 +536,13 @@ where
|
|||||||
self.resources.reserve(buffers.len());
|
self.resources.reserve(buffers.len());
|
||||||
|
|
||||||
for (i, buffer) in buffers.into_iter().enumerate() {
|
for (i, buffer) in buffers.into_iter().enumerate() {
|
||||||
self.current_state
|
self.builder_state
|
||||||
.vertex_buffers
|
.vertex_buffers
|
||||||
.insert(first_binding + i as u32, buffer.clone());
|
.insert(first_binding + i as u32, buffer.clone());
|
||||||
self.resources.push(Box::new(buffer));
|
self.resources.push(Box::new(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,13 +672,13 @@ where
|
|||||||
// push constants as set, and never unsets them. See:
|
// push constants as set, and never unsets them. See:
|
||||||
// https://github.com/KhronosGroup/Vulkan-Docs/issues/1485
|
// https://github.com/KhronosGroup/Vulkan-Docs/issues/1485
|
||||||
// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/2711
|
// https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/2711
|
||||||
self.current_state
|
self.builder_state
|
||||||
.push_constants
|
.push_constants
|
||||||
.insert(offset..offset + push_constants.len() as u32);
|
.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.resources.push(Box::new(pipeline_layout));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,7 +846,7 @@ where
|
|||||||
writes.as_ptr(),
|
writes.as_ptr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let state = self.current_state.invalidate_descriptor_sets(
|
let state = self.builder_state.invalidate_descriptor_sets(
|
||||||
pipeline_bind_point,
|
pipeline_bind_point,
|
||||||
pipeline_layout.clone(),
|
pipeline_layout.clone(),
|
||||||
set_num,
|
set_num,
|
||||||
@ -863,6 +868,7 @@ where
|
|||||||
|
|
||||||
self.resources.push(Box::new(pipeline_layout));
|
self.resources.push(Box::new(pipeline_layout));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,10 +13,11 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::{BufferAccess, BufferContents, BufferUsage, TypedBufferAccess},
|
buffer::{BufferAccess, BufferContents, BufferUsage, TypedBufferAccess},
|
||||||
command_buffer::allocator::CommandBufferAllocator,
|
command_buffer::{allocator::CommandBufferAllocator, ResourceInCommand, ResourceUseRef},
|
||||||
device::{DeviceOwned, QueueFlags},
|
device::{DeviceOwned, QueueFlags},
|
||||||
format::FormatFeatures,
|
format::FormatFeatures,
|
||||||
image::{ImageAccess, ImageAspects, ImageLayout, ImageUsage},
|
image::{ImageAccess, ImageAspects, ImageLayout, ImageUsage},
|
||||||
|
sync::PipelineStageAccess,
|
||||||
DeviceSize, RequiresOneOf, Version, VulkanObject,
|
DeviceSize, RequiresOneOf, Version, VulkanObject,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -50,7 +51,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdClearColorImage-renderpass
|
// VUID-vkCmdClearColorImage-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(ClearError::ForbiddenInsideRenderPass);
|
return Err(ClearError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +194,7 @@ where
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let image_inner = image.inner();
|
||||||
let clear_value = clear_value.into();
|
let clear_value = clear_value.into();
|
||||||
let ranges: SmallVec<[_; 8]> = regions
|
let ranges: SmallVec<[_; 8]> = regions
|
||||||
.iter()
|
.iter()
|
||||||
@ -203,17 +205,40 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.v1_0.cmd_clear_color_image)(
|
(fns.v1_0.cmd_clear_color_image)(
|
||||||
self.handle(),
|
self.handle(),
|
||||||
image.inner().image.handle(),
|
image_inner.image.handle(),
|
||||||
image_layout.into(),
|
image_layout.into(),
|
||||||
&clear_value,
|
&clear_value,
|
||||||
ranges.len() as u32,
|
ranges.len() as u32,
|
||||||
ranges.as_ptr(),
|
ranges.as_ptr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(image));
|
self.resources.push(Box::new(image));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +266,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdClearDepthStencilImage-renderpass
|
// VUID-vkCmdClearDepthStencilImage-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(ClearError::ForbiddenInsideRenderPass);
|
return Err(ClearError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,6 +427,7 @@ where
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let image_inner = image.inner();
|
||||||
let clear_value = clear_value.into();
|
let clear_value = clear_value.into();
|
||||||
let ranges: SmallVec<[_; 8]> = regions
|
let ranges: SmallVec<[_; 8]> = regions
|
||||||
.iter()
|
.iter()
|
||||||
@ -412,17 +438,40 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.v1_0.cmd_clear_depth_stencil_image)(
|
(fns.v1_0.cmd_clear_depth_stencil_image)(
|
||||||
self.handle(),
|
self.handle(),
|
||||||
image.inner().image.handle(),
|
image_inner.image.handle(),
|
||||||
image_layout.into(),
|
image_layout.into(),
|
||||||
&clear_value,
|
&clear_value,
|
||||||
ranges.len() as u32,
|
ranges.len() as u32,
|
||||||
ranges.as_ptr(),
|
ranges.as_ptr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(image));
|
self.resources.push(Box::new(image));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,7 +502,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdFillBuffer-renderpass
|
// VUID-vkCmdFillBuffer-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(ClearError::ForbiddenInsideRenderPass);
|
return Err(ClearError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,10 +603,28 @@ where
|
|||||||
data,
|
data,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
|
||||||
self.resources.push(Box::new(dst_buffer));
|
self.resources.push(Box::new(dst_buffer));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,7 +663,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdUpdateBuffer-renderpass
|
// VUID-vkCmdUpdateBuffer-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(ClearError::ForbiddenInsideRenderPass);
|
return Err(ClearError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,10 +751,28 @@ where
|
|||||||
data.as_bytes().as_ptr() as *const _,
|
data.as_bytes().as_ptr() as *const _,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
|
||||||
self.resources.push(Box::new(dst_buffer));
|
self.resources.push(Box::new(dst_buffer));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,14 +14,18 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::{BufferAccess, BufferUsage},
|
buffer::{BufferAccess, BufferUsage},
|
||||||
command_buffer::{allocator::CommandBufferAllocator, ImageBlit, ImageResolve},
|
command_buffer::{
|
||||||
|
allocator::CommandBufferAllocator, ImageBlit, ImageResolve, ResourceInCommand,
|
||||||
|
ResourceUseRef,
|
||||||
|
},
|
||||||
device::{DeviceOwned, QueueFlags},
|
device::{DeviceOwned, QueueFlags},
|
||||||
format::{Format, FormatFeatures, NumericType},
|
format::{Format, FormatFeatures, NumericType},
|
||||||
image::{
|
image::{
|
||||||
ImageAccess, ImageAspects, ImageDimensions, ImageLayout, ImageSubresourceLayers, ImageType,
|
ImageAccess, ImageAspects, ImageDimensions, ImageLayout, ImageSubresourceLayers,
|
||||||
ImageUsage, SampleCount, SampleCounts,
|
ImageSubresourceRange, ImageType, ImageUsage, SampleCount, SampleCounts,
|
||||||
},
|
},
|
||||||
sampler::Filter,
|
sampler::Filter,
|
||||||
|
sync::PipelineStageAccess,
|
||||||
DeviceSize, Version, VulkanObject,
|
DeviceSize, Version, VulkanObject,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -57,7 +61,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdCopyBuffer2-renderpass
|
// VUID-vkCmdCopyBuffer2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,11 +261,54 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "copy_buffer";
|
||||||
|
let src_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Source,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
let dst_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Destination,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for region in regions {
|
||||||
|
let BufferCopy {
|
||||||
|
src_offset,
|
||||||
|
dst_offset,
|
||||||
|
size,
|
||||||
|
_ne: _,
|
||||||
|
} = region;
|
||||||
|
|
||||||
|
let mut src_range = src_offset..src_offset + size;
|
||||||
|
src_range.start += src_buffer_inner.offset;
|
||||||
|
src_range.end += src_buffer_inner.offset;
|
||||||
|
self.resources_usage_state.record_buffer_access(
|
||||||
|
&src_use_ref,
|
||||||
|
src_buffer_inner.buffer,
|
||||||
|
src_range,
|
||||||
|
PipelineStageAccess::Copy_TransferRead,
|
||||||
|
);
|
||||||
|
|
||||||
|
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(
|
||||||
|
&dst_use_ref,
|
||||||
|
dst_buffer_inner.buffer,
|
||||||
|
dst_range,
|
||||||
|
PipelineStageAccess::Copy_TransferWrite,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(src_buffer));
|
self.resources.push(Box::new(src_buffer));
|
||||||
self.resources.push(Box::new(dst_buffer));
|
self.resources.push(Box::new(dst_buffer));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,7 +352,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdCopyImage2-renderpass
|
// VUID-vkCmdCopyImage2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,11 +1174,62 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "copy_image";
|
||||||
|
let src_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Source,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
let dst_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Destination,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for region in regions {
|
||||||
|
let ImageCopy {
|
||||||
|
src_subresource,
|
||||||
|
src_offset: _,
|
||||||
|
dst_subresource,
|
||||||
|
dst_offset: _,
|
||||||
|
extent: _,
|
||||||
|
_ne: _,
|
||||||
|
} = region;
|
||||||
|
|
||||||
|
let mut src_subresource_range = ImageSubresourceRange::from(src_subresource);
|
||||||
|
src_subresource_range.array_layers.start += src_image_inner.first_layer;
|
||||||
|
src_subresource_range.array_layers.end += src_image_inner.first_layer;
|
||||||
|
src_subresource_range.mip_levels.start += src_image_inner.first_mipmap_level;
|
||||||
|
src_subresource_range.mip_levels.end += src_image_inner.first_mipmap_level;
|
||||||
|
self.resources_usage_state.record_image_access(
|
||||||
|
&src_use_ref,
|
||||||
|
src_image_inner.image,
|
||||||
|
src_subresource_range,
|
||||||
|
PipelineStageAccess::Copy_TransferRead,
|
||||||
|
src_image_layout,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut dst_subresource_range = ImageSubresourceRange::from(dst_subresource);
|
||||||
|
dst_subresource_range.array_layers.start += dst_image_inner.first_layer;
|
||||||
|
dst_subresource_range.array_layers.end += dst_image_inner.first_layer;
|
||||||
|
dst_subresource_range.mip_levels.start += dst_image_inner.first_mipmap_level;
|
||||||
|
dst_subresource_range.mip_levels.end += dst_image_inner.first_mipmap_level;
|
||||||
|
self.resources_usage_state.record_image_access(
|
||||||
|
&dst_use_ref,
|
||||||
|
dst_image_inner.image,
|
||||||
|
dst_subresource_range,
|
||||||
|
PipelineStageAccess::Copy_TransferWrite,
|
||||||
|
dst_image_layout,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(src_image));
|
self.resources.push(Box::new(src_image));
|
||||||
self.resources.push(Box::new(dst_image));
|
self.resources.push(Box::new(dst_image));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1159,7 +1257,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdCopyBufferToImage2-renderpass
|
// VUID-vkCmdCopyBufferToImage2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1705,11 +1803,62 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "copy_buffer_to_image";
|
||||||
|
let src_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Source,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
let dst_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Destination,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for region in regions {
|
||||||
|
let buffer_copy_size = region.buffer_copy_size(dst_image.format());
|
||||||
|
|
||||||
|
let BufferImageCopy {
|
||||||
|
buffer_offset,
|
||||||
|
buffer_row_length: _,
|
||||||
|
buffer_image_height: _,
|
||||||
|
image_subresource,
|
||||||
|
image_offset: _,
|
||||||
|
image_extent: _,
|
||||||
|
_ne: _,
|
||||||
|
} = region;
|
||||||
|
|
||||||
|
let mut src_range = buffer_offset..buffer_offset + buffer_copy_size;
|
||||||
|
src_range.start += src_buffer_inner.offset;
|
||||||
|
src_range.end += src_buffer_inner.offset;
|
||||||
|
self.resources_usage_state.record_buffer_access(
|
||||||
|
&src_use_ref,
|
||||||
|
src_buffer_inner.buffer,
|
||||||
|
src_range,
|
||||||
|
PipelineStageAccess::Copy_TransferRead,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut dst_subresource_range = ImageSubresourceRange::from(image_subresource);
|
||||||
|
dst_subresource_range.array_layers.start += dst_image_inner.first_layer;
|
||||||
|
dst_subresource_range.array_layers.end += dst_image_inner.first_layer;
|
||||||
|
dst_subresource_range.mip_levels.start += dst_image_inner.first_mipmap_level;
|
||||||
|
dst_subresource_range.mip_levels.end += dst_image_inner.first_mipmap_level;
|
||||||
|
self.resources_usage_state.record_image_access(
|
||||||
|
&dst_use_ref,
|
||||||
|
dst_image_inner.image,
|
||||||
|
dst_subresource_range,
|
||||||
|
PipelineStageAccess::Copy_TransferWrite,
|
||||||
|
dst_image_layout,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(src_buffer));
|
self.resources.push(Box::new(src_buffer));
|
||||||
self.resources.push(Box::new(dst_image));
|
self.resources.push(Box::new(dst_image));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1737,7 +1886,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdCopyImageToBuffer2-renderpass
|
// VUID-vkCmdCopyImageToBuffer2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2273,11 +2422,62 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "copy_image_to_buffer";
|
||||||
|
let src_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Source,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
let dst_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Destination,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for region in regions {
|
||||||
|
let buffer_copy_size = region.buffer_copy_size(src_image.format());
|
||||||
|
|
||||||
|
let BufferImageCopy {
|
||||||
|
buffer_offset,
|
||||||
|
buffer_row_length: _,
|
||||||
|
buffer_image_height: _,
|
||||||
|
image_subresource,
|
||||||
|
image_offset: _,
|
||||||
|
image_extent: _,
|
||||||
|
_ne: _,
|
||||||
|
} = region;
|
||||||
|
|
||||||
|
let mut src_subresource_range = ImageSubresourceRange::from(image_subresource);
|
||||||
|
src_subresource_range.array_layers.start += src_image_inner.first_layer;
|
||||||
|
src_subresource_range.array_layers.end += src_image_inner.first_layer;
|
||||||
|
src_subresource_range.mip_levels.start += src_image_inner.first_mipmap_level;
|
||||||
|
src_subresource_range.mip_levels.end += src_image_inner.first_mipmap_level;
|
||||||
|
self.resources_usage_state.record_image_access(
|
||||||
|
&src_use_ref,
|
||||||
|
src_image_inner.image,
|
||||||
|
src_subresource_range,
|
||||||
|
PipelineStageAccess::Copy_TransferRead,
|
||||||
|
src_image_layout,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut dst_range = buffer_offset..buffer_offset + buffer_copy_size;
|
||||||
|
dst_range.start += dst_buffer_inner.offset;
|
||||||
|
dst_range.end += dst_buffer_inner.offset;
|
||||||
|
self.resources_usage_state.record_buffer_access(
|
||||||
|
&dst_use_ref,
|
||||||
|
dst_buffer_inner.buffer,
|
||||||
|
dst_range,
|
||||||
|
PipelineStageAccess::Copy_TransferWrite,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(src_image));
|
self.resources.push(Box::new(src_image));
|
||||||
self.resources.push(Box::new(dst_buffer));
|
self.resources.push(Box::new(dst_buffer));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2331,7 +2531,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdBlitImage2-renderpass
|
// VUID-vkCmdBlitImage2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2983,11 +3183,61 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "blit_image";
|
||||||
|
let src_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Source,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
let dst_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Destination,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for region in regions {
|
||||||
|
let ImageBlit {
|
||||||
|
src_subresource,
|
||||||
|
src_offsets: _,
|
||||||
|
dst_subresource,
|
||||||
|
dst_offsets: _,
|
||||||
|
_ne: _,
|
||||||
|
} = region;
|
||||||
|
|
||||||
|
let mut src_subresource_range = ImageSubresourceRange::from(src_subresource);
|
||||||
|
src_subresource_range.array_layers.start += src_image_inner.first_layer;
|
||||||
|
src_subresource_range.array_layers.end += src_image_inner.first_layer;
|
||||||
|
src_subresource_range.mip_levels.start += src_image_inner.first_mipmap_level;
|
||||||
|
src_subresource_range.mip_levels.end += src_image_inner.first_mipmap_level;
|
||||||
|
self.resources_usage_state.record_image_access(
|
||||||
|
&src_use_ref,
|
||||||
|
src_image_inner.image,
|
||||||
|
src_subresource_range,
|
||||||
|
PipelineStageAccess::Blit_TransferRead,
|
||||||
|
src_image_layout,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut dst_subresource_range = ImageSubresourceRange::from(dst_subresource);
|
||||||
|
dst_subresource_range.array_layers.start += dst_image_inner.first_layer;
|
||||||
|
dst_subresource_range.array_layers.end += dst_image_inner.first_layer;
|
||||||
|
dst_subresource_range.mip_levels.start += dst_image_inner.first_mipmap_level;
|
||||||
|
dst_subresource_range.mip_levels.end += dst_image_inner.first_mipmap_level;
|
||||||
|
self.resources_usage_state.record_image_access(
|
||||||
|
&dst_use_ref,
|
||||||
|
dst_image_inner.image,
|
||||||
|
dst_subresource_range,
|
||||||
|
PipelineStageAccess::Blit_TransferWrite,
|
||||||
|
dst_image_layout,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(src_image));
|
self.resources.push(Box::new(src_image));
|
||||||
self.resources.push(Box::new(dst_image));
|
self.resources.push(Box::new(dst_image));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3020,7 +3270,7 @@ where
|
|||||||
let device = self.device();
|
let device = self.device();
|
||||||
|
|
||||||
// VUID-vkCmdResolveImage2-renderpass
|
// VUID-vkCmdResolveImage2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3412,11 +3662,62 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "resolve_image";
|
||||||
|
let src_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Source,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
let dst_use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Destination,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
for region in regions {
|
||||||
|
let ImageResolve {
|
||||||
|
src_subresource,
|
||||||
|
src_offset: _,
|
||||||
|
dst_subresource,
|
||||||
|
dst_offset: _,
|
||||||
|
extent: _,
|
||||||
|
_ne: _,
|
||||||
|
} = region;
|
||||||
|
|
||||||
|
let mut src_subresource_range = ImageSubresourceRange::from(src_subresource);
|
||||||
|
src_subresource_range.array_layers.start += src_image_inner.first_layer;
|
||||||
|
src_subresource_range.array_layers.end += src_image_inner.first_layer;
|
||||||
|
src_subresource_range.mip_levels.start += src_image_inner.first_mipmap_level;
|
||||||
|
src_subresource_range.mip_levels.end += src_image_inner.first_mipmap_level;
|
||||||
|
self.resources_usage_state.record_image_access(
|
||||||
|
&src_use_ref,
|
||||||
|
src_image_inner.image,
|
||||||
|
src_subresource_range,
|
||||||
|
PipelineStageAccess::Resolve_TransferRead,
|
||||||
|
src_image_layout,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut dst_subresource_range = ImageSubresourceRange::from(dst_subresource);
|
||||||
|
dst_subresource_range.array_layers.start += dst_image_inner.first_layer;
|
||||||
|
dst_subresource_range.array_layers.end += dst_image_inner.first_layer;
|
||||||
|
dst_subresource_range.mip_levels.start += dst_image_inner.first_mipmap_level;
|
||||||
|
dst_subresource_range.mip_levels.end += dst_image_inner.first_mipmap_level;
|
||||||
|
self.resources_usage_state.record_image_access(
|
||||||
|
&dst_use_ref,
|
||||||
|
dst_image_inner.image,
|
||||||
|
dst_subresource_range,
|
||||||
|
PipelineStageAccess::Resolve_TransferWrite,
|
||||||
|
dst_image_layout,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(src_image));
|
self.resources.push(Box::new(src_image));
|
||||||
self.resources.push(Box::new(dst_image));
|
self.resources.push(Box::new(dst_image));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,7 @@ where
|
|||||||
let fns = self.device().instance().fns();
|
let fns = self.device().instance().fns();
|
||||||
(fns.ext_debug_utils.cmd_begin_debug_utils_label_ext)(self.handle(), &label_info);
|
(fns.ext_debug_utils.cmd_begin_debug_utils_label_ext)(self.handle(), &label_info);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +142,7 @@ where
|
|||||||
let fns = self.device().instance().fns();
|
let fns = self.device().instance().fns();
|
||||||
(fns.ext_debug_utils.cmd_end_debug_utils_label_ext)(self.handle());
|
(fns.ext_debug_utils.cmd_end_debug_utils_label_ext)(self.handle());
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,6 +210,7 @@ where
|
|||||||
let fns = self.device().instance().fns();
|
let fns = self.device().instance().fns();
|
||||||
(fns.ext_debug_utils.cmd_insert_debug_utils_label_ext)(self.handle(), &label_info);
|
(fns.ext_debug_utils.cmd_insert_debug_utils_label_ext)(self.handle(), &label_info);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ where
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
// VUID-vkCmdDispatch-None-02859
|
// VUID-vkCmdDispatch-None-02859
|
||||||
if self
|
if self
|
||||||
.current_state
|
.builder_state
|
||||||
.pipeline_graphics
|
.pipeline_graphics
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(false, |pipeline| {
|
.map_or(false, |pipeline| {
|
||||||
@ -90,8 +90,9 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.v1_0.cmd_set_blend_constants)(self.handle(), &constants);
|
(fns.v1_0.cmd_set_blend_constants)(self.handle(), &constants);
|
||||||
|
|
||||||
self.current_state.blend_constants = Some(constants);
|
self.builder_state.blend_constants = Some(constants);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +149,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(color_blend_state) = self
|
if let Some(color_blend_state) = self
|
||||||
.current_state
|
.builder_state
|
||||||
.pipeline_graphics
|
.pipeline_graphics
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|pipeline| pipeline.color_blend_state())
|
.and_then(|pipeline| pipeline.color_blend_state())
|
||||||
@ -193,8 +194,9 @@ where
|
|||||||
enables_vk.as_ptr(),
|
enables_vk.as_ptr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.current_state.color_write_enable = Some(enables);
|
self.builder_state.color_write_enable = Some(enables);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,8 +265,9 @@ where
|
|||||||
(fns.ext_extended_dynamic_state.cmd_set_cull_mode_ext)(self.handle(), cull_mode.into());
|
(fns.ext_extended_dynamic_state.cmd_set_cull_mode_ext)(self.handle(), cull_mode.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.cull_mode = Some(cull_mode);
|
self.builder_state.cull_mode = Some(cull_mode);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,12 +336,13 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.v1_0.cmd_set_depth_bias)(self.handle(), constant_factor, clamp, slope_factor);
|
(fns.v1_0.cmd_set_depth_bias)(self.handle(), constant_factor, clamp, slope_factor);
|
||||||
|
|
||||||
self.current_state.depth_bias = Some(DepthBias {
|
self.builder_state.depth_bias = Some(DepthBias {
|
||||||
constant_factor,
|
constant_factor,
|
||||||
clamp,
|
clamp,
|
||||||
slope_factor,
|
slope_factor,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,8 +409,9 @@ where
|
|||||||
.cmd_set_depth_bias_enable_ext)(self.handle(), enable.into());
|
.cmd_set_depth_bias_enable_ext)(self.handle(), enable.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.depth_bias_enable = Some(enable);
|
self.builder_state.depth_bias_enable = Some(enable);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,8 +472,9 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.v1_0.cmd_set_depth_bounds)(self.handle(), *bounds.start(), *bounds.end());
|
(fns.v1_0.cmd_set_depth_bounds)(self.handle(), *bounds.start(), *bounds.end());
|
||||||
|
|
||||||
self.current_state.depth_bounds = Some(bounds);
|
self.builder_state.depth_bounds = Some(bounds);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,8 +544,9 @@ where
|
|||||||
.cmd_set_depth_bounds_test_enable_ext)(self.handle(), enable.into());
|
.cmd_set_depth_bounds_test_enable_ext)(self.handle(), enable.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.depth_bounds_test_enable = Some(enable);
|
self.builder_state.depth_bounds_test_enable = Some(enable);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -613,8 +620,9 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.depth_compare_op = Some(compare_op);
|
self.builder_state.depth_compare_op = Some(compare_op);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,8 +690,9 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.depth_test_enable = Some(enable);
|
self.builder_state.depth_test_enable = Some(enable);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,8 +758,9 @@ where
|
|||||||
.cmd_set_depth_write_enable_ext)(self.handle(), enable.into());
|
.cmd_set_depth_write_enable_ext)(self.handle(), enable.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.depth_write_enable = Some(enable);
|
self.builder_state.depth_write_enable = Some(enable);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,11 +785,7 @@ where
|
|||||||
self.validate_set_discard_rectangle(first_rectangle, &rectangles)
|
self.validate_set_discard_rectangle(first_rectangle, &rectangles)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe { self.set_discard_rectangle_unchecked(first_rectangle, rectangles) }
|
||||||
self.set_discard_rectangle_unchecked(first_rectangle, rectangles);
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_set_discard_rectangle(
|
fn validate_set_discard_rectangle(
|
||||||
@ -872,9 +878,10 @@ where
|
|||||||
|
|
||||||
for (num, rectangle) in rectangles.iter().enumerate() {
|
for (num, rectangle) in rectangles.iter().enumerate() {
|
||||||
let num = num as u32 + first_rectangle;
|
let num = num as u32 + first_rectangle;
|
||||||
self.current_state.discard_rectangle.insert(num, *rectangle);
|
self.builder_state.discard_rectangle.insert(num, *rectangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,8 +949,9 @@ where
|
|||||||
(fns.ext_extended_dynamic_state.cmd_set_front_face_ext)(self.handle(), face.into());
|
(fns.ext_extended_dynamic_state.cmd_set_front_face_ext)(self.handle(), face.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.front_face = Some(face);
|
self.builder_state.front_face = Some(face);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1004,8 +1012,9 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.ext_line_rasterization.cmd_set_line_stipple_ext)(self.handle(), factor, pattern);
|
(fns.ext_line_rasterization.cmd_set_line_stipple_ext)(self.handle(), factor, pattern);
|
||||||
|
|
||||||
self.current_state.line_stipple = Some(LineStipple { factor, pattern });
|
self.builder_state.line_stipple = Some(LineStipple { factor, pattern });
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1055,8 +1064,9 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.v1_0.cmd_set_line_width)(self.handle(), line_width);
|
(fns.v1_0.cmd_set_line_width)(self.handle(), line_width);
|
||||||
|
|
||||||
self.current_state.line_width = Some(line_width);
|
self.builder_state.line_width = Some(line_width);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1125,8 +1135,9 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.ext_extended_dynamic_state2.cmd_set_logic_op_ext)(self.handle(), logic_op.into());
|
(fns.ext_extended_dynamic_state2.cmd_set_logic_op_ext)(self.handle(), logic_op.into());
|
||||||
|
|
||||||
self.current_state.logic_op = Some(logic_op);
|
self.builder_state.logic_op = Some(logic_op);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1213,8 +1224,9 @@ where
|
|||||||
(fns.ext_extended_dynamic_state2
|
(fns.ext_extended_dynamic_state2
|
||||||
.cmd_set_patch_control_points_ext)(self.handle(), num);
|
.cmd_set_patch_control_points_ext)(self.handle(), num);
|
||||||
|
|
||||||
self.current_state.patch_control_points = Some(num);
|
self.builder_state.patch_control_points = Some(num);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1283,8 +1295,9 @@ where
|
|||||||
.cmd_set_primitive_restart_enable_ext)(self.handle(), enable.into());
|
.cmd_set_primitive_restart_enable_ext)(self.handle(), enable.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.primitive_restart_enable = Some(enable);
|
self.builder_state.primitive_restart_enable = Some(enable);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1409,8 +1422,9 @@ where
|
|||||||
.cmd_set_primitive_topology_ext)(self.handle(), topology.into());
|
.cmd_set_primitive_topology_ext)(self.handle(), topology.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.primitive_topology = Some(topology);
|
self.builder_state.primitive_topology = Some(topology);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1479,8 +1493,9 @@ where
|
|||||||
.cmd_set_rasterizer_discard_enable_ext)(self.handle(), enable.into());
|
.cmd_set_rasterizer_discard_enable_ext)(self.handle(), enable.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.rasterizer_discard_enable = Some(enable);
|
self.builder_state.rasterizer_discard_enable = Some(enable);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1588,9 +1603,10 @@ where
|
|||||||
|
|
||||||
for (num, scissor) in scissors.iter().enumerate() {
|
for (num, scissor) in scissors.iter().enumerate() {
|
||||||
let num = num as u32 + first_scissor;
|
let num = num as u32 + first_scissor;
|
||||||
self.current_state.scissor.insert(num, *scissor);
|
self.builder_state.scissor.insert(num, *scissor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1709,8 +1725,9 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.scissor_with_count = Some(scissors);
|
self.builder_state.scissor_with_count = Some(scissors);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1766,13 +1783,14 @@ where
|
|||||||
let faces = ash::vk::StencilFaceFlags::from(faces);
|
let faces = ash::vk::StencilFaceFlags::from(faces);
|
||||||
|
|
||||||
if faces.intersects(ash::vk::StencilFaceFlags::FRONT) {
|
if faces.intersects(ash::vk::StencilFaceFlags::FRONT) {
|
||||||
self.current_state.stencil_compare_mask.front = Some(compare_mask);
|
self.builder_state.stencil_compare_mask.front = Some(compare_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
if faces.intersects(ash::vk::StencilFaceFlags::BACK) {
|
if faces.intersects(ash::vk::StencilFaceFlags::BACK) {
|
||||||
self.current_state.stencil_compare_mask.back = Some(compare_mask);
|
self.builder_state.stencil_compare_mask.back = Some(compare_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1891,7 +1909,7 @@ where
|
|||||||
let faces = ash::vk::StencilFaceFlags::from(faces);
|
let faces = ash::vk::StencilFaceFlags::from(faces);
|
||||||
|
|
||||||
if faces.intersects(ash::vk::StencilFaceFlags::FRONT) {
|
if faces.intersects(ash::vk::StencilFaceFlags::FRONT) {
|
||||||
self.current_state.stencil_op.front = Some(StencilOps {
|
self.builder_state.stencil_op.front = Some(StencilOps {
|
||||||
fail_op,
|
fail_op,
|
||||||
pass_op,
|
pass_op,
|
||||||
depth_fail_op,
|
depth_fail_op,
|
||||||
@ -1900,7 +1918,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if faces.intersects(ash::vk::StencilFaceFlags::BACK) {
|
if faces.intersects(ash::vk::StencilFaceFlags::BACK) {
|
||||||
self.current_state.stencil_op.back = Some(StencilOps {
|
self.builder_state.stencil_op.back = Some(StencilOps {
|
||||||
fail_op,
|
fail_op,
|
||||||
pass_op,
|
pass_op,
|
||||||
depth_fail_op,
|
depth_fail_op,
|
||||||
@ -1908,6 +1926,7 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1959,13 +1978,14 @@ where
|
|||||||
let faces = ash::vk::StencilFaceFlags::from(faces);
|
let faces = ash::vk::StencilFaceFlags::from(faces);
|
||||||
|
|
||||||
if faces.intersects(ash::vk::StencilFaceFlags::FRONT) {
|
if faces.intersects(ash::vk::StencilFaceFlags::FRONT) {
|
||||||
self.current_state.stencil_reference.front = Some(reference);
|
self.builder_state.stencil_reference.front = Some(reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
if faces.intersects(ash::vk::StencilFaceFlags::BACK) {
|
if faces.intersects(ash::vk::StencilFaceFlags::BACK) {
|
||||||
self.current_state.stencil_reference.back = Some(reference);
|
self.builder_state.stencil_reference.back = Some(reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2031,8 +2051,9 @@ where
|
|||||||
.cmd_set_stencil_test_enable_ext)(self.handle(), enable.into());
|
.cmd_set_stencil_test_enable_ext)(self.handle(), enable.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.stencil_test_enable = Some(enable);
|
self.builder_state.stencil_test_enable = Some(enable);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2084,13 +2105,14 @@ where
|
|||||||
let faces = ash::vk::StencilFaceFlags::from(faces);
|
let faces = ash::vk::StencilFaceFlags::from(faces);
|
||||||
|
|
||||||
if faces.intersects(ash::vk::StencilFaceFlags::FRONT) {
|
if faces.intersects(ash::vk::StencilFaceFlags::FRONT) {
|
||||||
self.current_state.stencil_write_mask.front = Some(write_mask);
|
self.builder_state.stencil_write_mask.front = Some(write_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
if faces.intersects(ash::vk::StencilFaceFlags::BACK) {
|
if faces.intersects(ash::vk::StencilFaceFlags::BACK) {
|
||||||
self.current_state.stencil_write_mask.back = Some(write_mask);
|
self.builder_state.stencil_write_mask.back = Some(write_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2198,9 +2220,10 @@ where
|
|||||||
|
|
||||||
for (num, viewport) in viewports.iter().enumerate() {
|
for (num, viewport) in viewports.iter().enumerate() {
|
||||||
let num = num as u32 + first_viewport;
|
let num = num as u32 + first_viewport;
|
||||||
self.current_state.viewport.insert(num, viewport.clone());
|
self.builder_state.viewport.insert(num, viewport.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2319,8 +2342,9 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.viewport_with_count = Some(viewports);
|
self.builder_state.viewport_with_count = Some(viewports);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ pub use crate::command_buffer::{
|
|||||||
RenderingAttachmentInfo, RenderingAttachmentResolveInfo, RenderingInfo, ResolveImageInfo,
|
RenderingAttachmentInfo, RenderingAttachmentResolveInfo, RenderingInfo, ResolveImageInfo,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::BufferAccess,
|
buffer::{sys::Buffer, BufferAccess},
|
||||||
command_buffer::{
|
command_buffer::{
|
||||||
allocator::{
|
allocator::{
|
||||||
CommandBufferAllocator, CommandBufferBuilderAlloc, StandardCommandBufferAllocator,
|
CommandBufferAllocator, CommandBufferBuilderAlloc, StandardCommandBufferAllocator,
|
||||||
@ -30,12 +30,12 @@ use crate::{
|
|||||||
BuildError, CommandBufferBeginError, CommandBufferInheritanceInfo,
|
BuildError, CommandBufferBeginError, CommandBufferInheritanceInfo,
|
||||||
CommandBufferInheritanceRenderPassInfo, CommandBufferInheritanceRenderPassType,
|
CommandBufferInheritanceRenderPassInfo, CommandBufferInheritanceRenderPassType,
|
||||||
CommandBufferInheritanceRenderingInfo, CommandBufferLevel, CommandBufferUsage,
|
CommandBufferInheritanceRenderingInfo, CommandBufferLevel, CommandBufferUsage,
|
||||||
SubpassContents,
|
ResourceInCommand, ResourceUseRef, SubpassContents,
|
||||||
},
|
},
|
||||||
descriptor_set::{DescriptorSetResources, DescriptorSetWithOffsets},
|
descriptor_set::{DescriptorSetResources, DescriptorSetWithOffsets},
|
||||||
device::{Device, DeviceOwned, QueueFamilyProperties},
|
device::{Device, DeviceOwned, QueueFamilyProperties, QueueFlags},
|
||||||
format::{Format, FormatFeatures},
|
format::{Format, FormatFeatures},
|
||||||
image::ImageAspects,
|
image::{sys::Image, ImageAspects, ImageLayout, ImageSubresourceRange},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
graphics::{
|
graphics::{
|
||||||
color_blend::LogicOp,
|
color_blend::LogicOp,
|
||||||
@ -47,17 +47,23 @@ use crate::{
|
|||||||
ComputePipeline, DynamicState, GraphicsPipeline, PipelineBindPoint, PipelineLayout,
|
ComputePipeline, DynamicState, GraphicsPipeline, PipelineBindPoint, PipelineLayout,
|
||||||
},
|
},
|
||||||
query::{QueryControlFlags, QueryType},
|
query::{QueryControlFlags, QueryType},
|
||||||
|
range_map::RangeMap,
|
||||||
range_set::RangeSet,
|
range_set::RangeSet,
|
||||||
render_pass::{Framebuffer, Subpass},
|
render_pass::{Framebuffer, Subpass},
|
||||||
OomError, RequiresOneOf, VulkanError, VulkanObject,
|
sync::{
|
||||||
|
BufferMemoryBarrier, DependencyInfo, ImageMemoryBarrier, PipelineStage,
|
||||||
|
PipelineStageAccess, PipelineStageAccessSet, PipelineStages,
|
||||||
|
},
|
||||||
|
DeviceSize, OomError, RequiresOneOf, VulkanError, VulkanObject,
|
||||||
};
|
};
|
||||||
|
use ahash::HashMap;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
collections::{hash_map::Entry, HashMap},
|
collections::hash_map::Entry,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ops::RangeInclusive,
|
ops::{Range, RangeInclusive},
|
||||||
ptr,
|
ptr,
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::{atomic::AtomicBool, Arc},
|
||||||
};
|
};
|
||||||
@ -83,8 +89,10 @@ where
|
|||||||
queue_family_index: u32,
|
queue_family_index: u32,
|
||||||
usage: CommandBufferUsage,
|
usage: CommandBufferUsage,
|
||||||
|
|
||||||
|
next_command_index: usize,
|
||||||
resources: Vec<Box<dyn Any + Send + Sync>>,
|
resources: Vec<Box<dyn Any + Send + Sync>>,
|
||||||
current_state: CurrentState,
|
builder_state: CommandBufferBuilderState,
|
||||||
|
resources_usage_state: ResourcesState,
|
||||||
|
|
||||||
_data: PhantomData<L>,
|
_data: PhantomData<L>,
|
||||||
}
|
}
|
||||||
@ -542,7 +550,7 @@ where
|
|||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut current_state: CurrentState = Default::default();
|
let mut builder_state: CommandBufferBuilderState = Default::default();
|
||||||
|
|
||||||
if let Some(inheritance_info) = &inheritance_info {
|
if let Some(inheritance_info) = &inheritance_info {
|
||||||
let &CommandBufferInheritanceInfo {
|
let &CommandBufferInheritanceInfo {
|
||||||
@ -553,7 +561,7 @@ where
|
|||||||
} = inheritance_info;
|
} = inheritance_info;
|
||||||
|
|
||||||
if let Some(render_pass) = render_pass {
|
if let Some(render_pass) = render_pass {
|
||||||
current_state.render_pass = Some(RenderPassState::from_inheritance(render_pass));
|
builder_state.render_pass = Some(RenderPassState::from_inheritance(render_pass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,8 +571,10 @@ where
|
|||||||
queue_family_index,
|
queue_family_index,
|
||||||
usage,
|
usage,
|
||||||
|
|
||||||
|
next_command_index: 0,
|
||||||
resources: Vec::new(),
|
resources: Vec::new(),
|
||||||
current_state,
|
builder_state,
|
||||||
|
resources_usage_state: Default::default(),
|
||||||
|
|
||||||
_data: PhantomData,
|
_data: PhantomData,
|
||||||
})
|
})
|
||||||
@ -581,11 +591,11 @@ where
|
|||||||
{
|
{
|
||||||
/// Builds the command buffer.
|
/// Builds the command buffer.
|
||||||
pub fn build(self) -> Result<PrimaryCommandBuffer<A::Alloc>, BuildError> {
|
pub fn build(self) -> Result<PrimaryCommandBuffer<A::Alloc>, BuildError> {
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(BuildError::RenderPassActive);
|
return Err(BuildError::RenderPassActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.current_state.queries.is_empty() {
|
if !self.builder_state.queries.is_empty() {
|
||||||
return Err(BuildError::QueryActive);
|
return Err(BuildError::QueryActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,7 +625,7 @@ where
|
|||||||
{
|
{
|
||||||
/// Builds the command buffer.
|
/// Builds the command buffer.
|
||||||
pub fn build(self) -> Result<SecondaryCommandBuffer<A::Alloc>, BuildError> {
|
pub fn build(self) -> Result<SecondaryCommandBuffer<A::Alloc>, BuildError> {
|
||||||
if !self.current_state.queries.is_empty() {
|
if !self.builder_state.queries.is_empty() {
|
||||||
return Err(BuildError::QueryActive);
|
return Err(BuildError::QueryActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +663,7 @@ where
|
|||||||
|
|
||||||
/// Holds the current binding and setting state.
|
/// Holds the current binding and setting state.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct CurrentState {
|
struct CommandBufferBuilderState {
|
||||||
// Render pass
|
// Render pass
|
||||||
render_pass: Option<RenderPassState>,
|
render_pass: Option<RenderPassState>,
|
||||||
|
|
||||||
@ -700,7 +710,7 @@ struct CurrentState {
|
|||||||
queries: HashMap<ash::vk::QueryType, QueryState>,
|
queries: HashMap<ash::vk::QueryType, QueryState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CurrentState {
|
impl CommandBufferBuilderState {
|
||||||
fn reset_dynamic_states(&mut self, states: impl IntoIterator<Item = DynamicState>) {
|
fn reset_dynamic_states(&mut self, states: impl IntoIterator<Item = DynamicState>) {
|
||||||
for state in states {
|
for state in states {
|
||||||
match state {
|
match state {
|
||||||
@ -962,3 +972,433 @@ struct QueryState {
|
|||||||
flags: QueryControlFlags,
|
flags: QueryControlFlags,
|
||||||
in_subpass: bool,
|
in_subpass: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct ResourcesState {
|
||||||
|
buffers: HashMap<Arc<Buffer>, RangeMap<DeviceSize, BufferRangeState>>,
|
||||||
|
images: HashMap<Arc<Image>, RangeMap<DeviceSize, ImageRangeState>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||||
|
struct BufferRangeState {
|
||||||
|
resource_uses: Vec<ResourceUseRef>,
|
||||||
|
memory_access: MemoryAccessState,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||||
|
struct ImageRangeState {
|
||||||
|
resource_uses: Vec<ResourceUseRef>,
|
||||||
|
memory_access: MemoryAccessState,
|
||||||
|
expected_layout: ImageLayout,
|
||||||
|
current_layout: ImageLayout,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResourcesState {
|
||||||
|
fn record_buffer_access(
|
||||||
|
&mut self,
|
||||||
|
use_ref: &ResourceUseRef,
|
||||||
|
buffer: &Arc<Buffer>,
|
||||||
|
range: Range<DeviceSize>,
|
||||||
|
stage_access: PipelineStageAccess,
|
||||||
|
) {
|
||||||
|
let range_map = self.buffers.entry(buffer.clone()).or_insert_with(|| {
|
||||||
|
[(0..buffer.size(), Default::default())]
|
||||||
|
.into_iter()
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
range_map.split_at(&range.start);
|
||||||
|
range_map.split_at(&range.end);
|
||||||
|
|
||||||
|
for (_range, state) in range_map.range_mut(&range) {
|
||||||
|
state.resource_uses.push(*use_ref);
|
||||||
|
state.memory_access.record_access(use_ref, stage_access);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn record_image_access(
|
||||||
|
&mut self,
|
||||||
|
use_ref: &ResourceUseRef,
|
||||||
|
image: &Arc<Image>,
|
||||||
|
subresource_range: ImageSubresourceRange,
|
||||||
|
stage_access: PipelineStageAccess,
|
||||||
|
image_layout: ImageLayout,
|
||||||
|
) {
|
||||||
|
let range_map = self.images.entry(image.clone()).or_insert_with(|| {
|
||||||
|
[(0..image.range_size(), Default::default())]
|
||||||
|
.into_iter()
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
|
||||||
|
for range in image.iter_ranges(subresource_range) {
|
||||||
|
range_map.split_at(&range.start);
|
||||||
|
range_map.split_at(&range.end);
|
||||||
|
|
||||||
|
for (_range, state) in range_map.range_mut(&range) {
|
||||||
|
if state.resource_uses.is_empty() {
|
||||||
|
state.expected_layout = image_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.resource_uses.push(*use_ref);
|
||||||
|
state.memory_access.record_access(use_ref, stage_access);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn record_pipeline_barrier(
|
||||||
|
&mut self,
|
||||||
|
command_index: usize,
|
||||||
|
command_name: &'static str,
|
||||||
|
dependency_info: &DependencyInfo,
|
||||||
|
queue_flags: QueueFlags,
|
||||||
|
) {
|
||||||
|
for barrier in &dependency_info.buffer_memory_barriers {
|
||||||
|
let barrier_scopes = BarrierScopes::from_buffer_memory_barrier(barrier, queue_flags);
|
||||||
|
let &BufferMemoryBarrier {
|
||||||
|
src_stages: _,
|
||||||
|
src_access: _,
|
||||||
|
dst_stages: _,
|
||||||
|
dst_access: _,
|
||||||
|
queue_family_ownership_transfer: _,
|
||||||
|
ref buffer,
|
||||||
|
ref range,
|
||||||
|
_ne: _,
|
||||||
|
} = barrier;
|
||||||
|
|
||||||
|
let range_map = self.buffers.entry(buffer.clone()).or_insert_with(|| {
|
||||||
|
[(0..buffer.size(), Default::default())]
|
||||||
|
.into_iter()
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
range_map.split_at(&range.start);
|
||||||
|
range_map.split_at(&range.end);
|
||||||
|
|
||||||
|
for (_range, state) in range_map.range_mut(range) {
|
||||||
|
state.memory_access.record_barrier(&barrier_scopes, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index, barrier) in dependency_info.image_memory_barriers.iter().enumerate() {
|
||||||
|
let index = index as u32;
|
||||||
|
let barrier_scopes = BarrierScopes::from_image_memory_barrier(barrier, queue_flags);
|
||||||
|
let &ImageMemoryBarrier {
|
||||||
|
src_stages: _,
|
||||||
|
src_access: _,
|
||||||
|
dst_stages: _,
|
||||||
|
dst_access: _,
|
||||||
|
old_layout,
|
||||||
|
new_layout,
|
||||||
|
queue_family_ownership_transfer: _,
|
||||||
|
ref image,
|
||||||
|
ref subresource_range,
|
||||||
|
_ne,
|
||||||
|
} = barrier;
|
||||||
|
|
||||||
|
// This is only used if there is a layout transition.
|
||||||
|
let use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::ImageMemoryBarrier { index },
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
let layout_transition = (old_layout != new_layout).then_some(&use_ref);
|
||||||
|
|
||||||
|
let range_map = self.images.entry(image.clone()).or_insert_with(|| {
|
||||||
|
[(0..image.range_size(), Default::default())]
|
||||||
|
.into_iter()
|
||||||
|
.collect()
|
||||||
|
});
|
||||||
|
|
||||||
|
for range in image.iter_ranges(subresource_range.clone()) {
|
||||||
|
range_map.split_at(&range.start);
|
||||||
|
range_map.split_at(&range.end);
|
||||||
|
|
||||||
|
for (_range, state) in range_map.range_mut(&range) {
|
||||||
|
if old_layout != new_layout {
|
||||||
|
if state.resource_uses.is_empty() {
|
||||||
|
state.expected_layout = old_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.resource_uses.push(ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::ImageMemoryBarrier { index },
|
||||||
|
secondary_use_ref: None,
|
||||||
|
});
|
||||||
|
state.current_layout = new_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
state
|
||||||
|
.memory_access
|
||||||
|
.record_barrier(&barrier_scopes, layout_transition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for barrier in &dependency_info.buffer_memory_barriers {
|
||||||
|
let &BufferMemoryBarrier {
|
||||||
|
ref buffer,
|
||||||
|
ref range,
|
||||||
|
..
|
||||||
|
} = barrier;
|
||||||
|
|
||||||
|
let range_map = self.buffers.get_mut(buffer).unwrap();
|
||||||
|
for (_range, state) in range_map.range_mut(range) {
|
||||||
|
state.memory_access.apply_pending();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for barrier in &dependency_info.image_memory_barriers {
|
||||||
|
let &ImageMemoryBarrier {
|
||||||
|
ref image,
|
||||||
|
ref subresource_range,
|
||||||
|
..
|
||||||
|
} = barrier;
|
||||||
|
|
||||||
|
let range_map = self.images.get_mut(image).unwrap();
|
||||||
|
for range in image.iter_ranges(subresource_range.clone()) {
|
||||||
|
for (_range, state) in range_map.range_mut(&range) {
|
||||||
|
state.memory_access.apply_pending();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||||
|
struct MemoryAccessState {
|
||||||
|
mutable: bool,
|
||||||
|
last_write: Option<WriteState>,
|
||||||
|
reads_since_last_write: HashMap<PipelineStage, ReadState>,
|
||||||
|
|
||||||
|
/// Pending changes that have not yet been applied. This is used during barrier recording.
|
||||||
|
pending: Option<PendingWriteState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
struct WriteState {
|
||||||
|
use_ref: ResourceUseRef,
|
||||||
|
access: PipelineStageAccess,
|
||||||
|
|
||||||
|
/// The `dst_stages` and `dst_access` of all barriers that protect against this write.
|
||||||
|
barriers_since: PipelineStageAccessSet,
|
||||||
|
|
||||||
|
/// The `dst_stages` of all barriers that form a dependency chain with this write.
|
||||||
|
dependency_chain: PipelineStages,
|
||||||
|
|
||||||
|
/// The union of all `barriers_since` of all `reads_since_last_write`.
|
||||||
|
read_barriers_since: PipelineStages,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||||
|
struct PendingWriteState {
|
||||||
|
/// If this is `Some`, then the barrier is treated as a new write,
|
||||||
|
/// and the previous `last_write` is discarded.
|
||||||
|
/// Otherwise, the values below are added to the existing `last_write`.
|
||||||
|
layout_transition: Option<ResourceUseRef>,
|
||||||
|
|
||||||
|
barriers_since: PipelineStageAccessSet,
|
||||||
|
dependency_chain: PipelineStages,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
struct ReadState {
|
||||||
|
use_ref: ResourceUseRef,
|
||||||
|
access: PipelineStageAccess,
|
||||||
|
|
||||||
|
/// The `dst_stages` of all barriers that protect against this read.
|
||||||
|
/// This always includes the stage of `self`.
|
||||||
|
barriers_since: PipelineStages,
|
||||||
|
|
||||||
|
/// Stages of reads recorded after this read,
|
||||||
|
/// that were in scope of `barriers_since` at the time of recording.
|
||||||
|
/// This always includes the stage of `self`.
|
||||||
|
barriered_reads_since: PipelineStages,
|
||||||
|
|
||||||
|
/// Pending changes that have not yet been applied. This is used during barrier recording.
|
||||||
|
pending: Option<PendingReadState>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||||
|
struct PendingReadState {
|
||||||
|
barriers_since: PipelineStages,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryAccessState {
|
||||||
|
fn record_access(&mut self, use_ref: &ResourceUseRef, access: PipelineStageAccess) {
|
||||||
|
if access.is_write() {
|
||||||
|
self.mutable = true;
|
||||||
|
self.last_write = Some(WriteState {
|
||||||
|
use_ref: *use_ref,
|
||||||
|
access,
|
||||||
|
barriers_since: Default::default(),
|
||||||
|
dependency_chain: Default::default(),
|
||||||
|
read_barriers_since: Default::default(),
|
||||||
|
});
|
||||||
|
self.reads_since_last_write.clear();
|
||||||
|
} else {
|
||||||
|
let pipeline_stage = PipelineStage::try_from(access).unwrap();
|
||||||
|
let pipeline_stages = PipelineStages::from(pipeline_stage);
|
||||||
|
|
||||||
|
for read_state in self.reads_since_last_write.values_mut() {
|
||||||
|
if read_state.barriers_since.intersects(pipeline_stages) {
|
||||||
|
read_state.barriered_reads_since |= pipeline_stages;
|
||||||
|
} else {
|
||||||
|
read_state.barriered_reads_since -= pipeline_stages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.reads_since_last_write.insert(
|
||||||
|
pipeline_stage,
|
||||||
|
ReadState {
|
||||||
|
use_ref: *use_ref,
|
||||||
|
access,
|
||||||
|
barriers_since: pipeline_stages,
|
||||||
|
barriered_reads_since: pipeline_stages,
|
||||||
|
pending: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn record_barrier(
|
||||||
|
&mut self,
|
||||||
|
barrier_scopes: &BarrierScopes,
|
||||||
|
layout_transition: Option<&ResourceUseRef>,
|
||||||
|
) {
|
||||||
|
let skip_reads = if let Some(use_ref) = layout_transition {
|
||||||
|
let pending = self.pending.get_or_insert_with(Default::default);
|
||||||
|
pending.layout_transition = Some(*use_ref);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
self.pending
|
||||||
|
.map_or(false, |pending| pending.layout_transition.is_some())
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the last write is in the src scope of the barrier, then add the dst scopes.
|
||||||
|
// If the barrier includes a layout transition, then that layout transition is
|
||||||
|
// considered the last write, and it is always in the src scope of the barrier.
|
||||||
|
if layout_transition.is_some()
|
||||||
|
|| self.last_write.as_ref().map_or(false, |write_state| {
|
||||||
|
barrier_scopes
|
||||||
|
.src_access_scope
|
||||||
|
.contains_enum(write_state.access)
|
||||||
|
|| barrier_scopes
|
||||||
|
.src_exec_scope
|
||||||
|
.intersects(write_state.dependency_chain)
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let pending = self.pending.get_or_insert_with(Default::default);
|
||||||
|
pending.barriers_since |= barrier_scopes.dst_access_scope;
|
||||||
|
pending.dependency_chain |= barrier_scopes.dst_exec_scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A layout transition counts as a write, which means that `reads_since_last_write` will
|
||||||
|
// be cleared when applying pending operations.
|
||||||
|
// Therefore, there is no need to update the reads.
|
||||||
|
if !skip_reads {
|
||||||
|
// Gather all reads for which `barriers_since` is in the barrier's `src_exec_scope`.
|
||||||
|
let reads_in_src_exec_scope = self.reads_since_last_write.iter().fold(
|
||||||
|
PipelineStages::empty(),
|
||||||
|
|total, (&stage, read_state)| {
|
||||||
|
if barrier_scopes
|
||||||
|
.src_exec_scope
|
||||||
|
.intersects(read_state.barriers_since)
|
||||||
|
{
|
||||||
|
total.union(stage.into())
|
||||||
|
} else {
|
||||||
|
total
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
for read_state in self.reads_since_last_write.values_mut() {
|
||||||
|
if reads_in_src_exec_scope.intersects(read_state.barriered_reads_since) {
|
||||||
|
let pending = read_state.pending.get_or_insert_with(Default::default);
|
||||||
|
pending.barriers_since |= barrier_scopes.dst_exec_scope;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_pending(&mut self) {
|
||||||
|
if let Some(PendingWriteState {
|
||||||
|
layout_transition,
|
||||||
|
barriers_since,
|
||||||
|
dependency_chain,
|
||||||
|
}) = self.pending.take()
|
||||||
|
{
|
||||||
|
// If there is a pending layout transition, it is treated as the new `last_write`.
|
||||||
|
if let Some(use_ref) = layout_transition {
|
||||||
|
self.mutable = true;
|
||||||
|
self.last_write = Some(WriteState {
|
||||||
|
use_ref,
|
||||||
|
access: PipelineStageAccess::ImageLayoutTransition,
|
||||||
|
barriers_since,
|
||||||
|
dependency_chain,
|
||||||
|
read_barriers_since: Default::default(),
|
||||||
|
});
|
||||||
|
self.reads_since_last_write.clear();
|
||||||
|
} else if let Some(write_state) = &mut self.last_write {
|
||||||
|
write_state.barriers_since |= barriers_since;
|
||||||
|
write_state.dependency_chain |= dependency_chain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for read_state in self.reads_since_last_write.values_mut() {
|
||||||
|
if let Some(PendingReadState { barriers_since }) = read_state.pending.take() {
|
||||||
|
read_state.barriers_since |= barriers_since;
|
||||||
|
|
||||||
|
if let Some(write_state) = &mut self.last_write {
|
||||||
|
write_state.read_barriers_since |= read_state.barriers_since;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BarrierScopes {
|
||||||
|
src_exec_scope: PipelineStages,
|
||||||
|
src_access_scope: PipelineStageAccessSet,
|
||||||
|
dst_exec_scope: PipelineStages,
|
||||||
|
dst_access_scope: PipelineStageAccessSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BarrierScopes {
|
||||||
|
fn from_buffer_memory_barrier(barrier: &BufferMemoryBarrier, queue_flags: QueueFlags) -> Self {
|
||||||
|
let src_stages_expanded = barrier.src_stages.expand(queue_flags);
|
||||||
|
let src_exec_scope = src_stages_expanded.with_earlier();
|
||||||
|
let src_access_scope = PipelineStageAccessSet::from(barrier.src_access)
|
||||||
|
& PipelineStageAccessSet::from(src_stages_expanded);
|
||||||
|
|
||||||
|
let dst_stages_expanded = barrier.dst_stages.expand(queue_flags);
|
||||||
|
let dst_exec_scope = dst_stages_expanded.with_later();
|
||||||
|
let dst_access_scope = PipelineStageAccessSet::from(barrier.dst_access)
|
||||||
|
& PipelineStageAccessSet::from(dst_stages_expanded);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
src_exec_scope,
|
||||||
|
src_access_scope,
|
||||||
|
dst_exec_scope,
|
||||||
|
dst_access_scope,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_image_memory_barrier(barrier: &ImageMemoryBarrier, queue_flags: QueueFlags) -> Self {
|
||||||
|
let src_stages_expanded = barrier.src_stages.expand(queue_flags);
|
||||||
|
let src_exec_scope = src_stages_expanded.with_earlier();
|
||||||
|
let src_access_scope = PipelineStageAccessSet::from(barrier.src_access)
|
||||||
|
& PipelineStageAccessSet::from(src_stages_expanded);
|
||||||
|
|
||||||
|
let dst_stages_expanded = barrier.dst_stages.expand(queue_flags);
|
||||||
|
let dst_exec_scope = dst_stages_expanded.with_later();
|
||||||
|
let dst_access_scope = PipelineStageAccessSet::from(barrier.dst_access)
|
||||||
|
& PipelineStageAccessSet::from(dst_stages_expanded);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
src_exec_scope,
|
||||||
|
src_access_scope,
|
||||||
|
dst_exec_scope,
|
||||||
|
dst_access_scope,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,28 +7,36 @@
|
|||||||
// notice may not be copied, modified, or distributed except
|
// notice may not be copied, modified, or distributed except
|
||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
use super::{CommandBufferBuilder, PipelineExecutionError, RenderPassState, RenderPassStateType};
|
use super::{
|
||||||
|
CommandBufferBuilder, DescriptorSetState, PipelineExecutionError, RenderPassState,
|
||||||
|
RenderPassStateType, ResourcesState,
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::{view::BufferViewAbstract, BufferAccess, BufferUsage, TypedBufferAccess},
|
buffer::{view::BufferViewAbstract, BufferAccess, BufferUsage, TypedBufferAccess},
|
||||||
command_buffer::{
|
command_buffer::{
|
||||||
allocator::CommandBufferAllocator, commands::pipeline::DescriptorResourceInvalidError,
|
allocator::CommandBufferAllocator, commands::pipeline::DescriptorResourceInvalidError,
|
||||||
DispatchIndirectCommand, DrawIndexedIndirectCommand, DrawIndirectCommand, SubpassContents,
|
DispatchIndirectCommand, DrawIndexedIndirectCommand, DrawIndirectCommand,
|
||||||
|
ResourceInCommand, ResourceUseRef, SubpassContents,
|
||||||
},
|
},
|
||||||
descriptor_set::{layout::DescriptorType, DescriptorBindingResources},
|
descriptor_set::{layout::DescriptorType, DescriptorBindingResources},
|
||||||
device::{DeviceOwned, QueueFlags},
|
device::{DeviceOwned, QueueFlags},
|
||||||
format::FormatFeatures,
|
format::FormatFeatures,
|
||||||
image::{ImageAspects, ImageViewAbstract, SampleCount},
|
image::{ImageAccess, ImageAspects, ImageViewAbstract, SampleCount},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
graphics::{
|
graphics::{
|
||||||
input_assembly::PrimitiveTopology, render_pass::PipelineRenderPassType,
|
input_assembly::{IndexType, PrimitiveTopology},
|
||||||
|
render_pass::PipelineRenderPassType,
|
||||||
vertex_input::VertexInputRate,
|
vertex_input::VertexInputRate,
|
||||||
},
|
},
|
||||||
DynamicState, GraphicsPipeline, PartialStateMode, Pipeline, PipelineLayout,
|
DynamicState, GraphicsPipeline, PartialStateMode, Pipeline, PipelineBindPoint,
|
||||||
|
PipelineLayout,
|
||||||
},
|
},
|
||||||
sampler::Sampler,
|
sampler::Sampler,
|
||||||
shader::{DescriptorBindingRequirements, ShaderScalarType, ShaderStage},
|
shader::{DescriptorBindingRequirements, ShaderScalarType, ShaderStage, ShaderStages},
|
||||||
|
sync::PipelineStageAccess,
|
||||||
RequiresOneOf, VulkanObject,
|
RequiresOneOf, VulkanObject,
|
||||||
};
|
};
|
||||||
|
use ahash::HashMap;
|
||||||
use std::{cmp::min, mem::size_of, sync::Arc};
|
use std::{cmp::min, mem::size_of, sync::Arc};
|
||||||
|
|
||||||
impl<L, A> CommandBufferBuilder<L, A>
|
impl<L, A> CommandBufferBuilder<L, A>
|
||||||
@ -69,13 +77,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdDispatch-renderpass
|
// VUID-vkCmdDispatch-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(PipelineExecutionError::ForbiddenInsideRenderPass);
|
return Err(PipelineExecutionError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdDispatch-None-02700
|
// VUID-vkCmdDispatch-None-02700
|
||||||
let pipeline = self
|
let pipeline = self
|
||||||
.current_state
|
.builder_state
|
||||||
.pipeline_compute
|
.pipeline_compute
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
||||||
@ -115,8 +123,23 @@ where
|
|||||||
group_counts[2],
|
group_counts[2],
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: sync state update
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "dispatch";
|
||||||
|
let pipeline = self
|
||||||
|
.builder_state
|
||||||
|
.pipeline_compute
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref();
|
||||||
|
record_descriptor_sets_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.descriptor_sets,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,13 +181,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdDispatchIndirect-renderpass
|
// VUID-vkCmdDispatchIndirect-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(PipelineExecutionError::ForbiddenInsideRenderPass);
|
return Err(PipelineExecutionError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdDispatchIndirect-None-02700
|
// VUID-vkCmdDispatchIndirect-None-02700
|
||||||
let pipeline = self
|
let pipeline = self
|
||||||
.current_state
|
.builder_state
|
||||||
.pipeline_compute
|
.pipeline_compute
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
||||||
@ -193,10 +216,31 @@ where
|
|||||||
indirect_buffer_inner.offset,
|
indirect_buffer_inner.offset,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "dispatch_indirect";
|
||||||
|
let pipeline = self
|
||||||
|
.builder_state
|
||||||
|
.pipeline_compute
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref();
|
||||||
|
record_descriptor_sets_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.descriptor_sets,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
record_indirect_buffer_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&indirect_buffer,
|
||||||
|
);
|
||||||
|
|
||||||
self.resources.push(Box::new(indirect_buffer));
|
self.resources.push(Box::new(indirect_buffer));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,14 +286,14 @@ where
|
|||||||
) -> Result<(), PipelineExecutionError> {
|
) -> Result<(), PipelineExecutionError> {
|
||||||
// VUID-vkCmdDraw-renderpass
|
// VUID-vkCmdDraw-renderpass
|
||||||
let render_pass_state = self
|
let render_pass_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::ForbiddenOutsideRenderPass)?;
|
.ok_or(PipelineExecutionError::ForbiddenOutsideRenderPass)?;
|
||||||
|
|
||||||
// VUID-vkCmdDraw-None-02700
|
// VUID-vkCmdDraw-None-02700
|
||||||
let pipeline = self
|
let pipeline = self
|
||||||
.current_state
|
.builder_state
|
||||||
.pipeline_graphics
|
.pipeline_graphics
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
||||||
@ -287,14 +331,36 @@ where
|
|||||||
first_instance,
|
first_instance,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "draw";
|
||||||
|
let pipeline = self
|
||||||
|
.builder_state
|
||||||
|
.pipeline_graphics
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref();
|
||||||
|
record_descriptor_sets_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.descriptor_sets,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
record_vertex_buffers_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.vertex_buffers,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
|
||||||
if let RenderPassStateType::BeginRendering(state) =
|
if let RenderPassStateType::BeginRendering(state) =
|
||||||
&mut self.current_state.render_pass.as_mut().unwrap().render_pass
|
&mut self.builder_state.render_pass.as_mut().unwrap().render_pass
|
||||||
{
|
{
|
||||||
state.pipeline_used = true;
|
state.pipeline_used = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,14 +406,14 @@ where
|
|||||||
) -> Result<(), PipelineExecutionError> {
|
) -> Result<(), PipelineExecutionError> {
|
||||||
// VUID-vkCmdDrawIndirect-renderpass
|
// VUID-vkCmdDrawIndirect-renderpass
|
||||||
let render_pass_state = self
|
let render_pass_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::ForbiddenOutsideRenderPass)?;
|
.ok_or(PipelineExecutionError::ForbiddenOutsideRenderPass)?;
|
||||||
|
|
||||||
// VUID-vkCmdDrawIndirect-None-02700
|
// VUID-vkCmdDrawIndirect-None-02700
|
||||||
let pipeline = self
|
let pipeline = self
|
||||||
.current_state
|
.builder_state
|
||||||
.pipeline_graphics
|
.pipeline_graphics
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
||||||
@ -409,16 +475,44 @@ where
|
|||||||
stride,
|
stride,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "draw_indirect";
|
||||||
|
let pipeline = self
|
||||||
|
.builder_state
|
||||||
|
.pipeline_graphics
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref();
|
||||||
|
record_descriptor_sets_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.descriptor_sets,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
record_vertex_buffers_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.vertex_buffers,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
record_indirect_buffer_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&indirect_buffer,
|
||||||
|
);
|
||||||
|
|
||||||
if let RenderPassStateType::BeginRendering(state) =
|
if let RenderPassStateType::BeginRendering(state) =
|
||||||
&mut self.current_state.render_pass.as_mut().unwrap().render_pass
|
&mut self.builder_state.render_pass.as_mut().unwrap().render_pass
|
||||||
{
|
{
|
||||||
state.pipeline_used = true;
|
state.pipeline_used = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(indirect_buffer));
|
self.resources.push(Box::new(indirect_buffer));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -487,14 +581,14 @@ where
|
|||||||
|
|
||||||
// VUID-vkCmdDrawIndexed-renderpass
|
// VUID-vkCmdDrawIndexed-renderpass
|
||||||
let render_pass_state = self
|
let render_pass_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::ForbiddenOutsideRenderPass)?;
|
.ok_or(PipelineExecutionError::ForbiddenOutsideRenderPass)?;
|
||||||
|
|
||||||
// VUID-vkCmdDrawIndexed-None-02700
|
// VUID-vkCmdDrawIndexed-None-02700
|
||||||
let pipeline = self
|
let pipeline = self
|
||||||
.current_state
|
.builder_state
|
||||||
.pipeline_graphics
|
.pipeline_graphics
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
||||||
@ -536,14 +630,42 @@ where
|
|||||||
first_instance,
|
first_instance,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "draw_indexed";
|
||||||
|
let pipeline = self
|
||||||
|
.builder_state
|
||||||
|
.pipeline_graphics
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref();
|
||||||
|
record_descriptor_sets_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.descriptor_sets,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
record_vertex_buffers_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.vertex_buffers,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
record_index_buffer_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.index_buffer,
|
||||||
|
);
|
||||||
|
|
||||||
if let RenderPassStateType::BeginRendering(state) =
|
if let RenderPassStateType::BeginRendering(state) =
|
||||||
&mut self.current_state.render_pass.as_mut().unwrap().render_pass
|
&mut self.builder_state.render_pass.as_mut().unwrap().render_pass
|
||||||
{
|
{
|
||||||
state.pipeline_used = true;
|
state.pipeline_used = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,14 +718,14 @@ where
|
|||||||
) -> Result<(), PipelineExecutionError> {
|
) -> Result<(), PipelineExecutionError> {
|
||||||
// VUID-vkCmdDrawIndexedIndirect-renderpass
|
// VUID-vkCmdDrawIndexedIndirect-renderpass
|
||||||
let render_pass_state = self
|
let render_pass_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::ForbiddenOutsideRenderPass)?;
|
.ok_or(PipelineExecutionError::ForbiddenOutsideRenderPass)?;
|
||||||
|
|
||||||
// VUID-vkCmdDrawIndexedIndirect-None-02700
|
// VUID-vkCmdDrawIndexedIndirect-None-02700
|
||||||
let pipeline = self
|
let pipeline = self
|
||||||
.current_state
|
.builder_state
|
||||||
.pipeline_graphics
|
.pipeline_graphics
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
.ok_or(PipelineExecutionError::PipelineNotBound)?
|
||||||
@ -666,16 +788,50 @@ where
|
|||||||
stride,
|
stride,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "draw_indexed_indirect";
|
||||||
|
let pipeline = self
|
||||||
|
.builder_state
|
||||||
|
.pipeline_graphics
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.as_ref();
|
||||||
|
record_descriptor_sets_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.descriptor_sets,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
record_vertex_buffers_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.vertex_buffers,
|
||||||
|
pipeline,
|
||||||
|
);
|
||||||
|
record_index_buffer_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&self.builder_state.index_buffer,
|
||||||
|
);
|
||||||
|
record_indirect_buffer_access(
|
||||||
|
&mut self.resources_usage_state,
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&indirect_buffer,
|
||||||
|
);
|
||||||
|
|
||||||
if let RenderPassStateType::BeginRendering(state) =
|
if let RenderPassStateType::BeginRendering(state) =
|
||||||
&mut self.current_state.render_pass.as_mut().unwrap().render_pass
|
&mut self.builder_state.render_pass.as_mut().unwrap().render_pass
|
||||||
{
|
{
|
||||||
state.pipeline_used = true;
|
state.pipeline_used = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.resources.push(Box::new(indirect_buffer));
|
self.resources.push(Box::new(indirect_buffer));
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,7 +841,7 @@ where
|
|||||||
) -> Result<(), PipelineExecutionError> {
|
) -> Result<(), PipelineExecutionError> {
|
||||||
// VUID?
|
// VUID?
|
||||||
let (index_buffer, index_type) = self
|
let (index_buffer, index_type) = self
|
||||||
.current_state
|
.builder_state
|
||||||
.index_buffer
|
.index_buffer
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::IndexBufferNotBound)?;
|
.ok_or(PipelineExecutionError::IndexBufferNotBound)?;
|
||||||
@ -787,7 +943,7 @@ where
|
|||||||
|
|
||||||
// VUID-vkCmdDispatch-None-02697
|
// VUID-vkCmdDispatch-None-02697
|
||||||
let descriptor_set_state = self
|
let descriptor_set_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.descriptor_sets
|
.descriptor_sets
|
||||||
.get(&pipeline.bind_point())
|
.get(&pipeline.bind_point())
|
||||||
.ok_or(PipelineExecutionError::PipelineLayoutNotCompatible)?;
|
.ok_or(PipelineExecutionError::PipelineLayoutNotCompatible)?;
|
||||||
@ -1137,7 +1293,7 @@ where
|
|||||||
|
|
||||||
// VUID-vkCmdDispatch-maintenance4-06425
|
// VUID-vkCmdDispatch-maintenance4-06425
|
||||||
let constants_pipeline_layout = self
|
let constants_pipeline_layout = self
|
||||||
.current_state
|
.builder_state
|
||||||
.push_constants_pipeline_layout
|
.push_constants_pipeline_layout
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(PipelineExecutionError::PushConstantsMissing)?;
|
.ok_or(PipelineExecutionError::PushConstantsMissing)?;
|
||||||
@ -1150,7 +1306,7 @@ where
|
|||||||
return Err(PipelineExecutionError::PushConstantsNotCompatible);
|
return Err(PipelineExecutionError::PushConstantsNotCompatible);
|
||||||
}
|
}
|
||||||
|
|
||||||
let set_bytes = &self.current_state.push_constants;
|
let set_bytes = &self.builder_state.push_constants;
|
||||||
|
|
||||||
// VUID-vkCmdDispatch-maintenance4-06425
|
// VUID-vkCmdDispatch-maintenance4-06425
|
||||||
if !pipeline_layout
|
if !pipeline_layout
|
||||||
@ -1179,13 +1335,13 @@ where
|
|||||||
match dynamic_state {
|
match dynamic_state {
|
||||||
DynamicState::BlendConstants => {
|
DynamicState::BlendConstants => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.blend_constants.is_none() {
|
if self.builder_state.blend_constants.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::ColorWriteEnable => {
|
DynamicState::ColorWriteEnable => {
|
||||||
// VUID-vkCmdDraw-attachmentCount-06667
|
// VUID-vkCmdDraw-attachmentCount-06667
|
||||||
let enables = self.current_state.color_write_enable.as_ref().ok_or(PipelineExecutionError::DynamicStateNotSet { dynamic_state })?;
|
let enables = self.builder_state.color_write_enable.as_ref().ok_or(PipelineExecutionError::DynamicStateNotSet { dynamic_state })?;
|
||||||
|
|
||||||
// VUID-vkCmdDraw-attachmentCount-06667
|
// VUID-vkCmdDraw-attachmentCount-06667
|
||||||
if enables.len() < pipeline.color_blend_state().unwrap().attachments.len() {
|
if enables.len() < pipeline.color_blend_state().unwrap().attachments.len() {
|
||||||
@ -1203,49 +1359,49 @@ where
|
|||||||
}
|
}
|
||||||
DynamicState::CullMode => {
|
DynamicState::CullMode => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.cull_mode.is_none() {
|
if self.builder_state.cull_mode.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::DepthBias => {
|
DynamicState::DepthBias => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.depth_bias.is_none() {
|
if self.builder_state.depth_bias.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::DepthBiasEnable => {
|
DynamicState::DepthBiasEnable => {
|
||||||
// VUID-vkCmdDraw-None-04877
|
// VUID-vkCmdDraw-None-04877
|
||||||
if self.current_state.depth_bias_enable.is_none() {
|
if self.builder_state.depth_bias_enable.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::DepthBounds => {
|
DynamicState::DepthBounds => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.depth_bounds.is_none() {
|
if self.builder_state.depth_bounds.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::DepthBoundsTestEnable => {
|
DynamicState::DepthBoundsTestEnable => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.depth_bounds_test_enable.is_none() {
|
if self.builder_state.depth_bounds_test_enable.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::DepthCompareOp => {
|
DynamicState::DepthCompareOp => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.depth_compare_op.is_none() {
|
if self.builder_state.depth_compare_op.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::DepthTestEnable => {
|
DynamicState::DepthTestEnable => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.depth_test_enable.is_none() {
|
if self.builder_state.depth_test_enable.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::DepthWriteEnable => {
|
DynamicState::DepthWriteEnable => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.depth_write_enable.is_none() {
|
if self.builder_state.depth_write_enable.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1260,7 +1416,7 @@ where
|
|||||||
|
|
||||||
for num in 0..discard_rectangle_count {
|
for num in 0..discard_rectangle_count {
|
||||||
// VUID?
|
// VUID?
|
||||||
if !self.current_state.discard_rectangle.contains_key(&num) {
|
if !self.builder_state.discard_rectangle.contains_key(&num) {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1269,38 +1425,38 @@ where
|
|||||||
DynamicState::FragmentShadingRate => todo!(),
|
DynamicState::FragmentShadingRate => todo!(),
|
||||||
DynamicState::FrontFace => {
|
DynamicState::FrontFace => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.front_face.is_none() {
|
if self.builder_state.front_face.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::LineStipple => {
|
DynamicState::LineStipple => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.line_stipple.is_none() {
|
if self.builder_state.line_stipple.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::LineWidth => {
|
DynamicState::LineWidth => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.line_width.is_none() {
|
if self.builder_state.line_width.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::LogicOp => {
|
DynamicState::LogicOp => {
|
||||||
// VUID-vkCmdDraw-logicOp-04878
|
// VUID-vkCmdDraw-logicOp-04878
|
||||||
if self.current_state.logic_op.is_none() {
|
if self.builder_state.logic_op.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::PatchControlPoints => {
|
DynamicState::PatchControlPoints => {
|
||||||
// VUID-vkCmdDraw-None-04875
|
// VUID-vkCmdDraw-None-04875
|
||||||
if self.current_state.patch_control_points.is_none() {
|
if self.builder_state.patch_control_points.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::PrimitiveRestartEnable => {
|
DynamicState::PrimitiveRestartEnable => {
|
||||||
// VUID-vkCmdDraw-None-04879
|
// VUID-vkCmdDraw-None-04879
|
||||||
let primitive_restart_enable =
|
let primitive_restart_enable =
|
||||||
if let Some(enable) = self.current_state.primitive_restart_enable {
|
if let Some(enable) = self.builder_state.primitive_restart_enable {
|
||||||
enable
|
enable
|
||||||
} else {
|
} else {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
@ -1310,7 +1466,7 @@ where
|
|||||||
let topology = match pipeline.input_assembly_state().topology {
|
let topology = match pipeline.input_assembly_state().topology {
|
||||||
PartialStateMode::Fixed(topology) => topology,
|
PartialStateMode::Fixed(topology) => topology,
|
||||||
PartialStateMode::Dynamic(_) => {
|
PartialStateMode::Dynamic(_) => {
|
||||||
if let Some(topology) = self.current_state.primitive_topology {
|
if let Some(topology) = self.builder_state.primitive_topology {
|
||||||
topology
|
topology
|
||||||
} else {
|
} else {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet {
|
return Err(PipelineExecutionError::DynamicStateNotSet {
|
||||||
@ -1364,7 +1520,7 @@ where
|
|||||||
}
|
}
|
||||||
DynamicState::PrimitiveTopology => {
|
DynamicState::PrimitiveTopology => {
|
||||||
// VUID-vkCmdDraw-primitiveTopology-03420
|
// VUID-vkCmdDraw-primitiveTopology-03420
|
||||||
let topology = if let Some(topology) = self.current_state.primitive_topology {
|
let topology = if let Some(topology) = self.builder_state.primitive_topology {
|
||||||
topology
|
topology
|
||||||
} else {
|
} else {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
@ -1405,7 +1561,7 @@ where
|
|||||||
}
|
}
|
||||||
DynamicState::RasterizerDiscardEnable => {
|
DynamicState::RasterizerDiscardEnable => {
|
||||||
// VUID-vkCmdDraw-None-04876
|
// VUID-vkCmdDraw-None-04876
|
||||||
if self.current_state.rasterizer_discard_enable.is_none() {
|
if self.builder_state.rasterizer_discard_enable.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1416,7 +1572,7 @@ where
|
|||||||
DynamicState::Scissor => {
|
DynamicState::Scissor => {
|
||||||
for num in 0..pipeline.viewport_state().unwrap().count().unwrap() {
|
for num in 0..pipeline.viewport_state().unwrap().count().unwrap() {
|
||||||
// VUID?
|
// VUID?
|
||||||
if !self.current_state.scissor.contains_key(&num) {
|
if !self.builder_state.scissor.contains_key(&num) {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1424,7 +1580,7 @@ where
|
|||||||
DynamicState::ScissorWithCount => {
|
DynamicState::ScissorWithCount => {
|
||||||
// VUID-vkCmdDraw-scissorCount-03418
|
// VUID-vkCmdDraw-scissorCount-03418
|
||||||
// VUID-vkCmdDraw-viewportCount-03419
|
// VUID-vkCmdDraw-viewportCount-03419
|
||||||
let scissor_count = self.current_state.scissor_with_count.as_ref().ok_or(PipelineExecutionError::DynamicStateNotSet { dynamic_state })?.len() as u32;
|
let scissor_count = self.builder_state.scissor_with_count.as_ref().ok_or(PipelineExecutionError::DynamicStateNotSet { dynamic_state })?.len() as u32;
|
||||||
|
|
||||||
// Check if the counts match, but only if the viewport count is fixed.
|
// Check if the counts match, but only if the viewport count is fixed.
|
||||||
// If the viewport count is also dynamic, then the
|
// If the viewport count is also dynamic, then the
|
||||||
@ -1442,7 +1598,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::StencilCompareMask => {
|
DynamicState::StencilCompareMask => {
|
||||||
let state = self.current_state.stencil_compare_mask;
|
let state = self.builder_state.stencil_compare_mask;
|
||||||
|
|
||||||
// VUID?
|
// VUID?
|
||||||
if state.front.is_none() || state.back.is_none() {
|
if state.front.is_none() || state.back.is_none() {
|
||||||
@ -1450,7 +1606,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::StencilOp => {
|
DynamicState::StencilOp => {
|
||||||
let state = self.current_state.stencil_op;
|
let state = self.builder_state.stencil_op;
|
||||||
|
|
||||||
// VUID?
|
// VUID?
|
||||||
if state.front.is_none() || state.back.is_none() {
|
if state.front.is_none() || state.back.is_none() {
|
||||||
@ -1458,7 +1614,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DynamicState::StencilReference => {
|
DynamicState::StencilReference => {
|
||||||
let state = self.current_state.stencil_reference;
|
let state = self.builder_state.stencil_reference;
|
||||||
|
|
||||||
// VUID?
|
// VUID?
|
||||||
if state.front.is_none() || state.back.is_none() {
|
if state.front.is_none() || state.back.is_none() {
|
||||||
@ -1467,14 +1623,14 @@ where
|
|||||||
}
|
}
|
||||||
DynamicState::StencilTestEnable => {
|
DynamicState::StencilTestEnable => {
|
||||||
// VUID?
|
// VUID?
|
||||||
if self.current_state.stencil_test_enable.is_none() {
|
if self.builder_state.stencil_test_enable.is_none() {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check if the stencil buffer is writable
|
// TODO: Check if the stencil buffer is writable
|
||||||
}
|
}
|
||||||
DynamicState::StencilWriteMask => {
|
DynamicState::StencilWriteMask => {
|
||||||
let state = self.current_state.stencil_write_mask;
|
let state = self.builder_state.stencil_write_mask;
|
||||||
|
|
||||||
// VUID?
|
// VUID?
|
||||||
if state.front.is_none() || state.back.is_none() {
|
if state.front.is_none() || state.back.is_none() {
|
||||||
@ -1486,7 +1642,7 @@ where
|
|||||||
DynamicState::Viewport => {
|
DynamicState::Viewport => {
|
||||||
for num in 0..pipeline.viewport_state().unwrap().count().unwrap() {
|
for num in 0..pipeline.viewport_state().unwrap().count().unwrap() {
|
||||||
// VUID?
|
// VUID?
|
||||||
if !self.current_state.viewport.contains_key(&num) {
|
if !self.builder_state.viewport.contains_key(&num) {
|
||||||
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
return Err(PipelineExecutionError::DynamicStateNotSet { dynamic_state });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1495,7 +1651,7 @@ where
|
|||||||
DynamicState::ViewportShadingRatePalette => todo!(),
|
DynamicState::ViewportShadingRatePalette => todo!(),
|
||||||
DynamicState::ViewportWithCount => {
|
DynamicState::ViewportWithCount => {
|
||||||
// VUID-vkCmdDraw-viewportCount-03417
|
// VUID-vkCmdDraw-viewportCount-03417
|
||||||
let viewport_count = self.current_state.viewport_with_count.as_ref().ok_or(PipelineExecutionError::DynamicStateNotSet { dynamic_state })?.len() as u32;
|
let viewport_count = self.builder_state.viewport_with_count.as_ref().ok_or(PipelineExecutionError::DynamicStateNotSet { dynamic_state })?.len() as u32;
|
||||||
|
|
||||||
let scissor_count = if let Some(scissor_count) =
|
let scissor_count = if let Some(scissor_count) =
|
||||||
pipeline.viewport_state().unwrap().count()
|
pipeline.viewport_state().unwrap().count()
|
||||||
@ -1505,7 +1661,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
// VUID-vkCmdDraw-viewportCount-03419
|
// VUID-vkCmdDraw-viewportCount-03419
|
||||||
// The scissor count is also dynamic.
|
// The scissor count is also dynamic.
|
||||||
self.current_state.scissor_with_count.as_ref().ok_or(PipelineExecutionError::DynamicStateNotSet { dynamic_state })?.len() as u32
|
self.builder_state.scissor_with_count.as_ref().ok_or(PipelineExecutionError::DynamicStateNotSet { dynamic_state })?.len() as u32
|
||||||
};
|
};
|
||||||
|
|
||||||
// VUID-vkCmdDraw-viewportCount-03417
|
// VUID-vkCmdDraw-viewportCount-03417
|
||||||
@ -1710,7 +1866,7 @@ where
|
|||||||
|
|
||||||
for (&binding_num, binding_desc) in &vertex_input.bindings {
|
for (&binding_num, binding_desc) in &vertex_input.bindings {
|
||||||
// VUID-vkCmdDraw-None-04007
|
// VUID-vkCmdDraw-None-04007
|
||||||
let vertex_buffer = match self.current_state.vertex_buffers.get(&binding_num) {
|
let vertex_buffer = match self.builder_state.vertex_buffers.get(&binding_num) {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => return Err(PipelineExecutionError::VertexBufferNotBound { binding_num }),
|
None => return Err(PipelineExecutionError::VertexBufferNotBound { binding_num }),
|
||||||
};
|
};
|
||||||
@ -1807,3 +1963,252 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn record_descriptor_sets_access(
|
||||||
|
resources_usage_state: &mut ResourcesState,
|
||||||
|
command_index: usize,
|
||||||
|
command_name: &'static str,
|
||||||
|
descriptor_sets_state: &HashMap<PipelineBindPoint, DescriptorSetState>,
|
||||||
|
pipeline: &impl Pipeline,
|
||||||
|
) {
|
||||||
|
let descriptor_sets_state = match descriptor_sets_state.get(&pipeline.bind_point()) {
|
||||||
|
Some(x) => x,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (&(set, binding), binding_reqs) in pipeline.descriptor_binding_requirements() {
|
||||||
|
let descriptor_type = descriptor_sets_state.pipeline_layout.set_layouts()[set as usize]
|
||||||
|
.bindings()[&binding]
|
||||||
|
.descriptor_type;
|
||||||
|
|
||||||
|
// TODO: Should input attachments be handled here or in attachment access?
|
||||||
|
if descriptor_type == DescriptorType::InputAttachment {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let use_iter = move |index: u32| {
|
||||||
|
let (stages_read, stages_write) = [Some(index), None]
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|index| binding_reqs.descriptors.get(&index))
|
||||||
|
.fold(
|
||||||
|
(ShaderStages::empty(), ShaderStages::empty()),
|
||||||
|
|(stages_read, stages_write), desc_reqs| {
|
||||||
|
(
|
||||||
|
stages_read | desc_reqs.memory_read,
|
||||||
|
stages_write | desc_reqs.memory_write,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::DescriptorSet {
|
||||||
|
set,
|
||||||
|
binding,
|
||||||
|
index,
|
||||||
|
},
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
let stage_access_iter = PipelineStageAccess::iter_descriptor_stages(
|
||||||
|
descriptor_type,
|
||||||
|
stages_read,
|
||||||
|
stages_write,
|
||||||
|
);
|
||||||
|
(use_ref, stage_access_iter)
|
||||||
|
};
|
||||||
|
|
||||||
|
match descriptor_sets_state.descriptor_sets[&set]
|
||||||
|
.resources()
|
||||||
|
.binding(binding)
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
DescriptorBindingResources::None(_) => continue,
|
||||||
|
DescriptorBindingResources::Buffer(elements) => {
|
||||||
|
for (index, element) in elements.iter().enumerate() {
|
||||||
|
if let Some(buffer) = element {
|
||||||
|
let buffer_inner = buffer.inner();
|
||||||
|
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||||
|
|
||||||
|
let mut range = 0..buffer.size(); // TODO:
|
||||||
|
range.start += buffer_inner.offset;
|
||||||
|
range.end += buffer_inner.offset;
|
||||||
|
|
||||||
|
for stage_access in stage_access_iter {
|
||||||
|
resources_usage_state.record_buffer_access(
|
||||||
|
&use_ref,
|
||||||
|
buffer_inner.buffer,
|
||||||
|
range.clone(),
|
||||||
|
stage_access,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DescriptorBindingResources::BufferView(elements) => {
|
||||||
|
for (index, element) in elements.iter().enumerate() {
|
||||||
|
if let Some(buffer_view) = element {
|
||||||
|
let buffer = buffer_view.buffer();
|
||||||
|
let buffer_inner = buffer.inner();
|
||||||
|
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||||
|
|
||||||
|
let mut range = buffer_view.range();
|
||||||
|
range.start += buffer_inner.offset;
|
||||||
|
range.end += buffer_inner.offset;
|
||||||
|
|
||||||
|
for stage_access in stage_access_iter {
|
||||||
|
resources_usage_state.record_buffer_access(
|
||||||
|
&use_ref,
|
||||||
|
buffer_inner.buffer,
|
||||||
|
range.clone(),
|
||||||
|
stage_access,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DescriptorBindingResources::ImageView(elements) => {
|
||||||
|
for (index, element) in elements.iter().enumerate() {
|
||||||
|
if let Some(image_view) = element {
|
||||||
|
let image = image_view.image();
|
||||||
|
let image_inner = image.inner();
|
||||||
|
let layout = image
|
||||||
|
.descriptor_layouts()
|
||||||
|
.expect(
|
||||||
|
"descriptor_layouts must return Some when used in an image view",
|
||||||
|
)
|
||||||
|
.layout_for(descriptor_type);
|
||||||
|
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||||
|
|
||||||
|
let mut subresource_range = image_view.subresource_range().clone();
|
||||||
|
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;
|
||||||
|
|
||||||
|
for stage_access in stage_access_iter {
|
||||||
|
resources_usage_state.record_image_access(
|
||||||
|
&use_ref,
|
||||||
|
image_inner.image,
|
||||||
|
subresource_range.clone(),
|
||||||
|
stage_access,
|
||||||
|
layout,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DescriptorBindingResources::ImageViewSampler(elements) => {
|
||||||
|
for (index, element) in elements.iter().enumerate() {
|
||||||
|
if let Some((image_view, _)) = element {
|
||||||
|
let image = image_view.image();
|
||||||
|
let image_inner = image.inner();
|
||||||
|
let layout = image
|
||||||
|
.descriptor_layouts()
|
||||||
|
.expect(
|
||||||
|
"descriptor_layouts must return Some when used in an image view",
|
||||||
|
)
|
||||||
|
.layout_for(descriptor_type);
|
||||||
|
let (use_ref, stage_access_iter) = use_iter(index as u32);
|
||||||
|
|
||||||
|
let mut subresource_range = image_view.subresource_range().clone();
|
||||||
|
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;
|
||||||
|
|
||||||
|
for stage_access in stage_access_iter {
|
||||||
|
resources_usage_state.record_image_access(
|
||||||
|
&use_ref,
|
||||||
|
image_inner.image,
|
||||||
|
subresource_range.clone(),
|
||||||
|
stage_access,
|
||||||
|
layout,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DescriptorBindingResources::Sampler(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn record_vertex_buffers_access(
|
||||||
|
resources_usage_state: &mut ResourcesState,
|
||||||
|
command_index: usize,
|
||||||
|
command_name: &'static str,
|
||||||
|
vertex_buffers_state: &HashMap<u32, Arc<dyn BufferAccess>>,
|
||||||
|
pipeline: &GraphicsPipeline,
|
||||||
|
) {
|
||||||
|
for &binding in pipeline.vertex_input_state().bindings.keys() {
|
||||||
|
let buffer = &vertex_buffers_state[&binding];
|
||||||
|
let buffer_inner = buffer.inner();
|
||||||
|
let use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::VertexBuffer { binding },
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut range = 0..buffer.size(); // TODO: take range from draw command
|
||||||
|
range.start += buffer_inner.offset;
|
||||||
|
range.end += buffer_inner.offset;
|
||||||
|
resources_usage_state.record_buffer_access(
|
||||||
|
&use_ref,
|
||||||
|
buffer_inner.buffer,
|
||||||
|
range,
|
||||||
|
PipelineStageAccess::VertexAttributeInput_VertexAttributeRead,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn record_index_buffer_access(
|
||||||
|
resources_usage_state: &mut ResourcesState,
|
||||||
|
command_index: usize,
|
||||||
|
command_name: &'static str,
|
||||||
|
index_buffer_state: &Option<(Arc<dyn BufferAccess>, IndexType)>,
|
||||||
|
) {
|
||||||
|
let buffer = &index_buffer_state.as_ref().unwrap().0;
|
||||||
|
let buffer_inner = buffer.inner();
|
||||||
|
let use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::IndexBuffer,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut range = 0..buffer.size(); // TODO: take range from draw command
|
||||||
|
range.start += buffer_inner.offset;
|
||||||
|
range.end += buffer_inner.offset;
|
||||||
|
resources_usage_state.record_buffer_access(
|
||||||
|
&use_ref,
|
||||||
|
buffer_inner.buffer,
|
||||||
|
range,
|
||||||
|
PipelineStageAccess::IndexInput_IndexRead,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn record_indirect_buffer_access(
|
||||||
|
resources_usage_state: &mut ResourcesState,
|
||||||
|
command_index: usize,
|
||||||
|
command_name: &'static str,
|
||||||
|
buffer: &Arc<dyn BufferAccess>,
|
||||||
|
) {
|
||||||
|
let buffer_inner = buffer.inner();
|
||||||
|
let use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::IndirectBuffer,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut range = 0..buffer.size(); // TODO: take range from draw command
|
||||||
|
range.start += buffer_inner.offset;
|
||||||
|
range.end += buffer_inner.offset;
|
||||||
|
resources_usage_state.record_buffer_access(
|
||||||
|
&use_ref,
|
||||||
|
buffer_inner.buffer,
|
||||||
|
range,
|
||||||
|
PipelineStageAccess::DrawIndirect_IndirectCommandRead,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
|
|
||||||
use super::{CommandBufferBuilder, QueryError, QueryState};
|
use super::{CommandBufferBuilder, QueryError, QueryState};
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::{BufferUsage, TypedBufferAccess},
|
buffer::{BufferAccess, BufferUsage, TypedBufferAccess},
|
||||||
command_buffer::allocator::CommandBufferAllocator,
|
command_buffer::{allocator::CommandBufferAllocator, ResourceInCommand, ResourceUseRef},
|
||||||
device::{DeviceOwned, QueueFlags},
|
device::{DeviceOwned, QueueFlags},
|
||||||
query::{QueryControlFlags, QueryPool, QueryResultElement, QueryResultFlags, QueryType},
|
query::{QueryControlFlags, QueryPool, QueryResultElement, QueryResultFlags, QueryType},
|
||||||
sync::{PipelineStage, PipelineStages},
|
sync::{PipelineStage, PipelineStageAccess, PipelineStages},
|
||||||
DeviceSize, RequiresOneOf, Version, VulkanObject,
|
DeviceSize, RequiresOneOf, Version, VulkanObject,
|
||||||
};
|
};
|
||||||
use std::{ops::Range, sync::Arc};
|
use std::{ops::Range, sync::Arc};
|
||||||
@ -122,14 +122,14 @@ where
|
|||||||
|
|
||||||
// VUID-vkCmdBeginQuery-queryPool-01922
|
// VUID-vkCmdBeginQuery-queryPool-01922
|
||||||
if self
|
if self
|
||||||
.current_state
|
.builder_state
|
||||||
.queries
|
.queries
|
||||||
.contains_key(&query_pool.query_type().into())
|
.contains_key(&query_pool.query_type().into())
|
||||||
{
|
{
|
||||||
return Err(QueryError::QueryIsActive);
|
return Err(QueryError::QueryIsActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(render_pass_state) = &self.current_state.render_pass {
|
if let Some(render_pass_state) = &self.builder_state.render_pass {
|
||||||
// VUID-vkCmdBeginQuery-query-00808
|
// VUID-vkCmdBeginQuery-query-00808
|
||||||
if query + render_pass_state.view_mask.count_ones() > query_pool.query_count() {
|
if query + render_pass_state.view_mask.count_ones() > query_pool.query_count() {
|
||||||
return Err(QueryError::OutOfRangeMultiview);
|
return Err(QueryError::OutOfRangeMultiview);
|
||||||
@ -154,19 +154,20 @@ where
|
|||||||
(fns.v1_0.cmd_begin_query)(self.handle(), query_pool.handle(), query, flags.into());
|
(fns.v1_0.cmd_begin_query)(self.handle(), query_pool.handle(), query, flags.into());
|
||||||
|
|
||||||
let ty = query_pool.query_type();
|
let ty = query_pool.query_type();
|
||||||
self.current_state.queries.insert(
|
self.builder_state.queries.insert(
|
||||||
ty.into(),
|
ty.into(),
|
||||||
QueryState {
|
QueryState {
|
||||||
query_pool: query_pool.handle(),
|
query_pool: query_pool.handle(),
|
||||||
query,
|
query,
|
||||||
ty,
|
ty,
|
||||||
flags,
|
flags,
|
||||||
in_subpass: self.current_state.render_pass.is_some(),
|
in_subpass: self.builder_state.render_pass.is_some(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
self.resources.push(Box::new(query_pool));
|
self.resources.push(Box::new(query_pool));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,7 +201,7 @@ where
|
|||||||
|
|
||||||
// VUID-vkCmdEndQuery-None-01923
|
// VUID-vkCmdEndQuery-None-01923
|
||||||
if !self
|
if !self
|
||||||
.current_state
|
.builder_state
|
||||||
.queries
|
.queries
|
||||||
.get(&query_pool.query_type().into())
|
.get(&query_pool.query_type().into())
|
||||||
.map_or(false, |state| {
|
.map_or(false, |state| {
|
||||||
@ -213,7 +214,7 @@ where
|
|||||||
// VUID-vkCmdEndQuery-query-00810
|
// VUID-vkCmdEndQuery-query-00810
|
||||||
query_pool.query(query).ok_or(QueryError::OutOfRange)?;
|
query_pool.query(query).ok_or(QueryError::OutOfRange)?;
|
||||||
|
|
||||||
if let Some(render_pass_state) = &self.current_state.render_pass {
|
if let Some(render_pass_state) = &self.builder_state.render_pass {
|
||||||
// VUID-vkCmdEndQuery-query-00812
|
// VUID-vkCmdEndQuery-query-00812
|
||||||
if query + render_pass_state.view_mask.count_ones() > query_pool.query_count() {
|
if query + render_pass_state.view_mask.count_ones() > query_pool.query_count() {
|
||||||
return Err(QueryError::OutOfRangeMultiview);
|
return Err(QueryError::OutOfRangeMultiview);
|
||||||
@ -232,12 +233,13 @@ where
|
|||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.v1_0.cmd_end_query)(self.handle(), query_pool.handle(), query);
|
(fns.v1_0.cmd_end_query)(self.handle(), query_pool.handle(), query);
|
||||||
|
|
||||||
self.current_state
|
self.builder_state
|
||||||
.queries
|
.queries
|
||||||
.remove(&query_pool.query_type().into());
|
.remove(&query_pool.query_type().into());
|
||||||
|
|
||||||
self.resources.push(Box::new(query_pool));
|
self.resources.push(Box::new(query_pool));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,7 +446,7 @@ where
|
|||||||
// VUID-vkCmdWriteTimestamp2-query-04903
|
// VUID-vkCmdWriteTimestamp2-query-04903
|
||||||
query_pool.query(query).ok_or(QueryError::OutOfRange)?;
|
query_pool.query(query).ok_or(QueryError::OutOfRange)?;
|
||||||
|
|
||||||
if let Some(render_pass_state) = &self.current_state.render_pass {
|
if let Some(render_pass_state) = &self.builder_state.render_pass {
|
||||||
// VUID-vkCmdWriteTimestamp2-query-03865
|
// VUID-vkCmdWriteTimestamp2-query-03865
|
||||||
if query + render_pass_state.view_mask.count_ones() > query_pool.query_count() {
|
if query + render_pass_state.view_mask.count_ones() > query_pool.query_count() {
|
||||||
return Err(QueryError::OutOfRangeMultiview);
|
return Err(QueryError::OutOfRangeMultiview);
|
||||||
@ -491,6 +493,7 @@ where
|
|||||||
|
|
||||||
self.resources.push(Box::new(query_pool));
|
self.resources.push(Box::new(query_pool));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,7 +517,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
query_pool: Arc<QueryPool>,
|
query_pool: Arc<QueryPool>,
|
||||||
queries: Range<u32>,
|
queries: Range<u32>,
|
||||||
destination: Arc<D>,
|
dst_buffer: Arc<D>,
|
||||||
flags: QueryResultFlags,
|
flags: QueryResultFlags,
|
||||||
) -> Result<&mut Self, QueryError>
|
) -> Result<&mut Self, QueryError>
|
||||||
where
|
where
|
||||||
@ -524,7 +527,7 @@ where
|
|||||||
self.validate_copy_query_pool_results(
|
self.validate_copy_query_pool_results(
|
||||||
&query_pool,
|
&query_pool,
|
||||||
queries.clone(),
|
queries.clone(),
|
||||||
destination.as_ref(),
|
dst_buffer.as_ref(),
|
||||||
flags,
|
flags,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -532,13 +535,8 @@ where
|
|||||||
let per_query_len = query_pool.query_type().result_len()
|
let per_query_len = query_pool.query_type().result_len()
|
||||||
+ flags.intersects(QueryResultFlags::WITH_AVAILABILITY) as DeviceSize;
|
+ flags.intersects(QueryResultFlags::WITH_AVAILABILITY) as DeviceSize;
|
||||||
let stride = per_query_len * std::mem::size_of::<T>() as DeviceSize;
|
let stride = per_query_len * std::mem::size_of::<T>() as DeviceSize;
|
||||||
Ok(self.copy_query_pool_results_unchecked(
|
Ok(self
|
||||||
query_pool,
|
.copy_query_pool_results_unchecked(query_pool, queries, dst_buffer, stride, flags))
|
||||||
queries,
|
|
||||||
destination,
|
|
||||||
stride,
|
|
||||||
flags,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,7 +544,7 @@ where
|
|||||||
&self,
|
&self,
|
||||||
query_pool: &QueryPool,
|
query_pool: &QueryPool,
|
||||||
queries: Range<u32>,
|
queries: Range<u32>,
|
||||||
destination: &D,
|
dst_buffer: &D,
|
||||||
flags: QueryResultFlags,
|
flags: QueryResultFlags,
|
||||||
) -> Result<(), QueryError>
|
) -> Result<(), QueryError>
|
||||||
where
|
where
|
||||||
@ -564,18 +562,18 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdCopyQueryPoolResults-renderpass
|
// VUID-vkCmdCopyQueryPoolResults-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(QueryError::ForbiddenInsideRenderPass);
|
return Err(QueryError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
let device = self.device();
|
let device = self.device();
|
||||||
let buffer_inner = destination.inner();
|
let buffer_inner = dst_buffer.inner();
|
||||||
|
|
||||||
// VUID-vkCmdCopyQueryPoolResults-commonparent
|
// VUID-vkCmdCopyQueryPoolResults-commonparent
|
||||||
assert_eq!(device, buffer_inner.buffer.device());
|
assert_eq!(device, buffer_inner.buffer.device());
|
||||||
assert_eq!(device, query_pool.device());
|
assert_eq!(device, query_pool.device());
|
||||||
|
|
||||||
assert!(destination.len() > 0);
|
assert!(dst_buffer.len() > 0);
|
||||||
|
|
||||||
// VUID-vkCmdCopyQueryPoolResults-flags-00822
|
// VUID-vkCmdCopyQueryPoolResults-flags-00822
|
||||||
// VUID-vkCmdCopyQueryPoolResults-flags-00823
|
// VUID-vkCmdCopyQueryPoolResults-flags-00823
|
||||||
@ -593,10 +591,10 @@ where
|
|||||||
let required_len = per_query_len * count as DeviceSize;
|
let required_len = per_query_len * count as DeviceSize;
|
||||||
|
|
||||||
// VUID-vkCmdCopyQueryPoolResults-dstBuffer-00824
|
// VUID-vkCmdCopyQueryPoolResults-dstBuffer-00824
|
||||||
if destination.len() < required_len {
|
if dst_buffer.len() < required_len {
|
||||||
return Err(QueryError::BufferTooSmall {
|
return Err(QueryError::BufferTooSmall {
|
||||||
required_len,
|
required_len,
|
||||||
actual_len: destination.len(),
|
actual_len: dst_buffer.len(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +624,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
query_pool: Arc<QueryPool>,
|
query_pool: Arc<QueryPool>,
|
||||||
queries: Range<u32>,
|
queries: Range<u32>,
|
||||||
destination: Arc<D>,
|
dst_buffer: Arc<D>,
|
||||||
stride: DeviceSize,
|
stride: DeviceSize,
|
||||||
flags: QueryResultFlags,
|
flags: QueryResultFlags,
|
||||||
) -> &mut Self
|
) -> &mut Self
|
||||||
@ -634,7 +632,7 @@ where
|
|||||||
D: TypedBufferAccess<Content = [T]> + 'static,
|
D: TypedBufferAccess<Content = [T]> + 'static,
|
||||||
T: QueryResultElement,
|
T: QueryResultElement,
|
||||||
{
|
{
|
||||||
let destination_inner = destination.inner();
|
let dst_buffer_inner = dst_buffer.inner();
|
||||||
|
|
||||||
let fns = self.device().fns();
|
let fns = self.device().fns();
|
||||||
(fns.v1_0.cmd_copy_query_pool_results)(
|
(fns.v1_0.cmd_copy_query_pool_results)(
|
||||||
@ -642,17 +640,35 @@ where
|
|||||||
query_pool.handle(),
|
query_pool.handle(),
|
||||||
queries.start,
|
queries.start,
|
||||||
queries.end - queries.start,
|
queries.end - queries.start,
|
||||||
destination_inner.buffer.handle(),
|
dst_buffer_inner.buffer.handle(),
|
||||||
destination_inner.offset,
|
dst_buffer_inner.offset,
|
||||||
stride,
|
stride,
|
||||||
ash::vk::QueryResultFlags::from(flags) | T::FLAG,
|
ash::vk::QueryResultFlags::from(flags) | T::FLAG,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "copy_query_pool_results";
|
||||||
|
let use_ref = ResourceUseRef {
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
resource_in_command: ResourceInCommand::Destination,
|
||||||
|
secondary_use_ref: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut dst_range = 0..dst_buffer.size(); // TODO:
|
||||||
|
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::Copy_TransferWrite,
|
||||||
|
);
|
||||||
|
|
||||||
self.resources.push(Box::new(query_pool));
|
self.resources.push(Box::new(query_pool));
|
||||||
self.resources.push(Box::new(destination));
|
self.resources.push(Box::new(dst_buffer));
|
||||||
|
|
||||||
// TODO: sync state update
|
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,7 +696,7 @@ where
|
|||||||
queries: Range<u32>,
|
queries: Range<u32>,
|
||||||
) -> Result<(), QueryError> {
|
) -> Result<(), QueryError> {
|
||||||
// VUID-vkCmdResetQueryPool-renderpass
|
// VUID-vkCmdResetQueryPool-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(QueryError::ForbiddenInsideRenderPass);
|
return Err(QueryError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -707,7 +723,7 @@ where
|
|||||||
|
|
||||||
// VUID-vkCmdResetQueryPool-None-02841
|
// VUID-vkCmdResetQueryPool-None-02841
|
||||||
if self
|
if self
|
||||||
.current_state
|
.builder_state
|
||||||
.queries
|
.queries
|
||||||
.values()
|
.values()
|
||||||
.any(|state| state.query_pool == query_pool.handle() && queries.contains(&state.query))
|
.any(|state| state.query_pool == query_pool.handle() && queries.contains(&state.query))
|
||||||
@ -734,6 +750,7 @@ where
|
|||||||
|
|
||||||
self.resources.push(Box::new(query_pool));
|
self.resources.push(Box::new(query_pool));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdBeginRenderPass2-renderpass
|
// VUID-vkCmdBeginRenderPass2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(RenderPassError::ForbiddenInsideRenderPass);
|
return Err(RenderPassError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +446,7 @@ where
|
|||||||
let subpass = render_pass.clone().first_subpass();
|
let subpass = render_pass.clone().first_subpass();
|
||||||
let view_mask = subpass.subpass_desc().view_mask;
|
let view_mask = subpass.subpass_desc().view_mask;
|
||||||
|
|
||||||
self.current_state.render_pass = Some(RenderPassState {
|
self.builder_state.render_pass = Some(RenderPassState {
|
||||||
contents,
|
contents,
|
||||||
render_area_offset,
|
render_area_offset,
|
||||||
render_area_extent,
|
render_area_extent,
|
||||||
@ -463,6 +463,7 @@ where
|
|||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -491,7 +492,7 @@ where
|
|||||||
|
|
||||||
// VUID-vkCmdNextSubpass2-renderpass
|
// VUID-vkCmdNextSubpass2-renderpass
|
||||||
let render_pass_state = self
|
let render_pass_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(RenderPassError::ForbiddenOutsideRenderPass)?;
|
.ok_or(RenderPassError::ForbiddenOutsideRenderPass)?;
|
||||||
@ -512,7 +513,7 @@ where
|
|||||||
|
|
||||||
// VUID?
|
// VUID?
|
||||||
if self
|
if self
|
||||||
.current_state
|
.builder_state
|
||||||
.queries
|
.queries
|
||||||
.values()
|
.values()
|
||||||
.any(|state| state.in_subpass)
|
.any(|state| state.in_subpass)
|
||||||
@ -561,7 +562,7 @@ where
|
|||||||
(fns.v1_0.cmd_next_subpass)(self.handle(), subpass_begin_info.contents);
|
(fns.v1_0.cmd_next_subpass)(self.handle(), subpass_begin_info.contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
let render_pass_state = self.current_state.render_pass.as_mut().unwrap();
|
let render_pass_state = self.builder_state.render_pass.as_mut().unwrap();
|
||||||
let begin_render_pass_state = match &mut render_pass_state.render_pass {
|
let begin_render_pass_state = match &mut render_pass_state.render_pass {
|
||||||
RenderPassStateType::BeginRenderPass(x) => x,
|
RenderPassStateType::BeginRenderPass(x) => x,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -574,11 +575,12 @@ where
|
|||||||
if render_pass_state.view_mask != 0 {
|
if render_pass_state.view_mask != 0 {
|
||||||
// When multiview is enabled, at the beginning of each subpass, all
|
// When multiview is enabled, at the beginning of each subpass, all
|
||||||
// non-render pass state is undefined.
|
// non-render pass state is undefined.
|
||||||
self.current_state = Default::default();
|
self.builder_state = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,7 +603,7 @@ where
|
|||||||
fn validate_end_render_pass(&self) -> Result<(), RenderPassError> {
|
fn validate_end_render_pass(&self) -> Result<(), RenderPassError> {
|
||||||
// VUID-vkCmdEndRenderPass2-renderpass
|
// VUID-vkCmdEndRenderPass2-renderpass
|
||||||
let render_pass_state = self
|
let render_pass_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(RenderPassError::ForbiddenOutsideRenderPass)?;
|
.ok_or(RenderPassError::ForbiddenOutsideRenderPass)?;
|
||||||
@ -628,7 +630,7 @@ where
|
|||||||
|
|
||||||
// VUID?
|
// VUID?
|
||||||
if self
|
if self
|
||||||
.current_state
|
.builder_state
|
||||||
.queries
|
.queries
|
||||||
.values()
|
.values()
|
||||||
.any(|state| state.in_subpass)
|
.any(|state| state.in_subpass)
|
||||||
@ -671,10 +673,11 @@ where
|
|||||||
(fns.v1_0.cmd_end_render_pass)(self.handle());
|
(fns.v1_0.cmd_end_render_pass)(self.handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.render_pass = None;
|
self.builder_state.render_pass = None;
|
||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -732,7 +735,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdBeginRendering-renderpass
|
// VUID-vkCmdBeginRendering-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(RenderPassError::ForbiddenInsideRenderPass);
|
return Err(RenderPassError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1360,7 +1363,7 @@ where
|
|||||||
(fns.khr_dynamic_rendering.cmd_begin_rendering_khr)(self.handle(), &rendering_info);
|
(fns.khr_dynamic_rendering.cmd_begin_rendering_khr)(self.handle(), &rendering_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.render_pass = Some(RenderPassState {
|
self.builder_state.render_pass = Some(RenderPassState {
|
||||||
contents,
|
contents,
|
||||||
render_area_offset,
|
render_area_offset,
|
||||||
render_area_extent,
|
render_area_extent,
|
||||||
@ -1460,6 +1463,7 @@ where
|
|||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1480,7 +1484,7 @@ where
|
|||||||
fn validate_end_rendering(&self) -> Result<(), RenderPassError> {
|
fn validate_end_rendering(&self) -> Result<(), RenderPassError> {
|
||||||
// VUID-vkCmdEndRendering-renderpass
|
// VUID-vkCmdEndRendering-renderpass
|
||||||
let render_pass_state = self
|
let render_pass_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(RenderPassError::ForbiddenOutsideRenderPass)?;
|
.ok_or(RenderPassError::ForbiddenOutsideRenderPass)?;
|
||||||
@ -1521,10 +1525,11 @@ where
|
|||||||
(fns.khr_dynamic_rendering.cmd_end_rendering_khr)(self.handle());
|
(fns.khr_dynamic_rendering.cmd_end_rendering_khr)(self.handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.current_state.render_pass = None;
|
self.builder_state.render_pass = None;
|
||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1569,7 +1574,7 @@ where
|
|||||||
) -> Result<(), RenderPassError> {
|
) -> Result<(), RenderPassError> {
|
||||||
// VUID-vkCmdClearAttachments-renderpass
|
// VUID-vkCmdClearAttachments-renderpass
|
||||||
let render_pass_state = self
|
let render_pass_state = self
|
||||||
.current_state
|
.builder_state
|
||||||
.render_pass
|
.render_pass
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(RenderPassError::ForbiddenOutsideRenderPass)?;
|
.ok_or(RenderPassError::ForbiddenOutsideRenderPass)?;
|
||||||
@ -1829,6 +1834,7 @@ where
|
|||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ where
|
|||||||
// TODO:
|
// TODO:
|
||||||
// VUID-vkCmdExecuteCommands-pCommandBuffers-00094
|
// VUID-vkCmdExecuteCommands-pCommandBuffers-00094
|
||||||
|
|
||||||
if let Some(render_pass_state) = &self.current_state.render_pass {
|
if let Some(render_pass_state) = &self.builder_state.render_pass {
|
||||||
// VUID-vkCmdExecuteCommands-contents-06018
|
// VUID-vkCmdExecuteCommands-contents-06018
|
||||||
// VUID-vkCmdExecuteCommands-flags-06024
|
// VUID-vkCmdExecuteCommands-flags-06024
|
||||||
if render_pass_state.contents != SubpassContents::SecondaryCommandBuffers {
|
if render_pass_state.contents != SubpassContents::SecondaryCommandBuffers {
|
||||||
@ -261,7 +261,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdExecuteCommands-commandBuffer-00101
|
// VUID-vkCmdExecuteCommands-commandBuffer-00101
|
||||||
if !self.current_state.queries.is_empty()
|
if !self.builder_state.queries.is_empty()
|
||||||
&& !self.device().enabled_features().inherited_queries
|
&& !self.device().enabled_features().inherited_queries
|
||||||
{
|
{
|
||||||
return Err(ExecuteCommandsError::RequirementNotMet {
|
return Err(ExecuteCommandsError::RequirementNotMet {
|
||||||
@ -273,7 +273,7 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for state in self.current_state.queries.values() {
|
for state in self.builder_state.queries.values() {
|
||||||
match state.ty {
|
match state.ty {
|
||||||
QueryType::Occlusion => {
|
QueryType::Occlusion => {
|
||||||
// VUID-vkCmdExecuteCommands-commandBuffer-00102
|
// VUID-vkCmdExecuteCommands-commandBuffer-00102
|
||||||
@ -375,15 +375,19 @@ where
|
|||||||
(fns.v1_0.cmd_execute_commands)(self.handle(), 1, &command_buffer.handle());
|
(fns.v1_0.cmd_execute_commands)(self.handle(), 1, &command_buffer.handle());
|
||||||
|
|
||||||
// The secondary command buffer could leave the primary in any state.
|
// The secondary command buffer could leave the primary in any state.
|
||||||
self.current_state = Default::default();
|
self.builder_state = Default::default();
|
||||||
|
|
||||||
// If the secondary is non-concurrent or one-time use, that restricts the primary as well.
|
// If the secondary is non-concurrent or one-time use, that restricts the primary as well.
|
||||||
self.usage = std::cmp::min(self.usage, command_buffer.usage);
|
self.usage = std::cmp::min(self.usage, command_buffer.usage);
|
||||||
|
|
||||||
self.resources.push(Box::new(command_buffer));
|
let _command_index = self.next_command_index;
|
||||||
|
let _command_name = "execute_commands";
|
||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.resources.push(Box::new(command_buffer));
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -999,7 +999,7 @@ where
|
|||||||
Checks for current render pass
|
Checks for current render pass
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if let Some(render_pass_state) = self.current_state.render_pass.as_ref() {
|
if let Some(render_pass_state) = self.builder_state.render_pass.as_ref() {
|
||||||
// VUID-vkCmdPipelineBarrier2-None-06191
|
// VUID-vkCmdPipelineBarrier2-None-06191
|
||||||
let begin_render_pass_state = match &render_pass_state.render_pass {
|
let begin_render_pass_state = match &render_pass_state.render_pass {
|
||||||
RenderPassStateType::BeginRenderPass(x) => x,
|
RenderPassStateType::BeginRenderPass(x) => x,
|
||||||
@ -1088,13 +1088,13 @@ where
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
let DependencyInfo {
|
let &DependencyInfo {
|
||||||
dependency_flags,
|
dependency_flags,
|
||||||
memory_barriers,
|
ref memory_barriers,
|
||||||
buffer_memory_barriers,
|
ref buffer_memory_barriers,
|
||||||
image_memory_barriers,
|
ref image_memory_barriers,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = dependency_info;
|
} = &dependency_info;
|
||||||
|
|
||||||
if self.device().enabled_features().synchronization2 {
|
if self.device().enabled_features().synchronization2 {
|
||||||
let memory_barriers_vk: SmallVec<[_; 2]> = memory_barriers
|
let memory_barriers_vk: SmallVec<[_; 2]> = memory_barriers
|
||||||
@ -1341,43 +1341,27 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let command_index = self.next_command_index;
|
||||||
|
let command_name = "pipeline_barrier";
|
||||||
|
self.resources_usage_state.record_pipeline_barrier(
|
||||||
|
command_index,
|
||||||
|
command_name,
|
||||||
|
&dependency_info,
|
||||||
|
self.queue_family_properties().queue_flags,
|
||||||
|
);
|
||||||
|
|
||||||
self.resources
|
self.resources
|
||||||
.reserve(buffer_memory_barriers.len() + image_memory_barriers.len());
|
.reserve(buffer_memory_barriers.len() + image_memory_barriers.len());
|
||||||
|
|
||||||
for barrier in buffer_memory_barriers {
|
for barrier in dependency_info.buffer_memory_barriers {
|
||||||
let BufferMemoryBarrier {
|
self.resources.push(Box::new(barrier.buffer));
|
||||||
src_stages: _,
|
|
||||||
src_access: _,
|
|
||||||
dst_stages: _,
|
|
||||||
dst_access: _,
|
|
||||||
queue_family_ownership_transfer: _, // TODO:
|
|
||||||
buffer,
|
|
||||||
range: _,
|
|
||||||
_ne: _,
|
|
||||||
} = barrier;
|
|
||||||
|
|
||||||
self.resources.push(Box::new(buffer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for barrier in image_memory_barriers {
|
for barrier in dependency_info.image_memory_barriers {
|
||||||
let ImageMemoryBarrier {
|
self.resources.push(Box::new(barrier.image));
|
||||||
src_stages: _,
|
|
||||||
src_access: _,
|
|
||||||
dst_stages: _,
|
|
||||||
dst_access: _,
|
|
||||||
old_layout: _, // TODO:
|
|
||||||
new_layout: _, // TODO:
|
|
||||||
queue_family_ownership_transfer: _, // TODO:
|
|
||||||
image,
|
|
||||||
subresource_range: _,
|
|
||||||
_ne: _,
|
|
||||||
} = barrier;
|
|
||||||
|
|
||||||
self.resources.push(Box::new(image));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: sync state update
|
self.next_command_index += 1;
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1406,7 +1390,7 @@ where
|
|||||||
dependency_info: &DependencyInfo,
|
dependency_info: &DependencyInfo,
|
||||||
) -> Result<(), SynchronizationError> {
|
) -> Result<(), SynchronizationError> {
|
||||||
// VUID-vkCmdSetEvent2-renderpass
|
// VUID-vkCmdSetEvent2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(SynchronizationError::ForbiddenInsideRenderPass);
|
return Err(SynchronizationError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2508,6 +2492,7 @@ where
|
|||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2981,7 +2966,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdWaitEvents2-dependencyFlags-03844
|
// VUID-vkCmdWaitEvents2-dependencyFlags-03844
|
||||||
if self.current_state.render_pass.is_some()
|
if self.builder_state.render_pass.is_some()
|
||||||
&& src_stages.intersects(PipelineStages::HOST)
|
&& src_stages.intersects(PipelineStages::HOST)
|
||||||
{
|
{
|
||||||
todo!()
|
todo!()
|
||||||
@ -3830,6 +3815,7 @@ where
|
|||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3859,7 +3845,7 @@ where
|
|||||||
stages: PipelineStages,
|
stages: PipelineStages,
|
||||||
) -> Result<(), SynchronizationError> {
|
) -> Result<(), SynchronizationError> {
|
||||||
// VUID-vkCmdResetEvent2-renderpass
|
// VUID-vkCmdResetEvent2-renderpass
|
||||||
if self.current_state.render_pass.is_some() {
|
if self.builder_state.render_pass.is_some() {
|
||||||
return Err(SynchronizationError::ForbiddenInsideRenderPass);
|
return Err(SynchronizationError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4081,6 +4067,7 @@ where
|
|||||||
|
|
||||||
// TODO: sync state update
|
// TODO: sync state update
|
||||||
|
|
||||||
|
self.next_command_index += 1;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,6 +199,13 @@ vulkan_enum! {
|
|||||||
},*/
|
},*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ImageLayout {
|
||||||
|
#[inline]
|
||||||
|
fn default() -> Self {
|
||||||
|
ImageLayout::Undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The set of layouts to use for an image when used in descriptor of various kinds.
|
/// The set of layouts to use for an image when used in descriptor of various kinds.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub struct ImageDescriptorLayouts {
|
pub struct ImageDescriptorLayouts {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
//! This safety is enforced at runtime by vulkano but it is not magic and you will require some
|
//! This safety is enforced at runtime by vulkano but it is not magic and you will require some
|
||||||
//! knowledge if you want to avoid errors.
|
//! knowledge if you want to avoid errors.
|
||||||
|
|
||||||
|
pub(crate) use self::pipeline::{PipelineStageAccess, PipelineStageAccessSet};
|
||||||
pub use self::{
|
pub use self::{
|
||||||
future::{now, FlushError, GpuFuture},
|
future::{now, FlushError, GpuFuture},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user