diff --git a/vulkano/src/command_buffer/synced.rs b/vulkano/src/command_buffer/synced.rs index 50c85dd8..ec21216b 100644 --- a/vulkano/src/command_buffer/synced.rs +++ b/vulkano/src/command_buffer/synced.rs @@ -10,6 +10,7 @@ use fnv::FnvHashMap; use smallvec::SmallVec; use std::any::Any; +use std::borrow::Cow; use std::collections::hash_map::Entry; use std::error; use std::fmt; @@ -36,6 +37,7 @@ use command_buffer::sys::UnsafeCommandBufferBuilderColorImageClear; use command_buffer::sys::UnsafeCommandBufferBuilderExecuteCommands; use command_buffer::sys::UnsafeCommandBufferBuilderImageBlit; use command_buffer::sys::UnsafeCommandBufferBuilderPipelineBarrier; +use descriptor::descriptor::DescriptorDescTy; use descriptor::descriptor::ShaderStages; use descriptor::descriptor_set::DescriptorSet; use descriptor::pipeline_layout::PipelineLayoutAbstract; @@ -92,6 +94,9 @@ pub struct SyncCommandBufferBuilder
{
// Stores all the commands that were submitted or are going to be submitted to the inner
// builder. A copy of this `Arc` is stored in each `BuilderKey`.
commands: Arc fmt::Debug for SyncCommandBufferBuilder {
@@ -105,15 +110,22 @@ impl fmt::Debug for SyncCommandBufferBuilder {
#[derive(Debug, Clone)]
pub enum SyncCommandBufferBuilderError {
/// Unsolvable conflict.
- // TODO: add details
- Conflict,
+ Conflict {
+ command1_name: &'static str,
+ command1_param: Cow<'static, str>,
+ command1_offset: usize,
+
+ command2_name: &'static str,
+ command2_param: Cow<'static, str>,
+ command2_offset: usize,
+ },
}
impl error::Error for SyncCommandBufferBuilderError {
#[inline]
fn description(&self) -> &str {
match *self {
- SyncCommandBufferBuilderError::Conflict => {
+ SyncCommandBufferBuilderError::Conflict { .. } => {
"unsolvable conflict"
},
}
@@ -133,12 +145,19 @@ struct Commands {
// `UnsafeCommandBufferBuilder`.
first_unflushed: usize,
+ // If we're currently inside a render pass, contains the index of the `CmdBeginRenderPass`
+ // command.
+ latest_render_pass_enter: Option {
+ // Returns a user-friendly name for the command for error reporting purposes.
+ fn name(&self) -> &'static str;
+
// Sends the command to the `UnsafeCommandBufferBuilder`. Calling this method twice on the same
// object may lead to a panic.
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder );
@@ -154,6 +173,17 @@ trait Command {
fn image(&self, num: usize) -> &ImageAccess {
panic!()
}
+
+ // Returns a user-friendly name for the `num`th buffer used by the command, for error
+ // reporting purposes.
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ panic!()
+ }
+ // Returns a user-friendly name for the `num`th image used by the command, for error
+ // reporting purposes.
+ fn image_name(&self, num: usize) -> Cow<'static, str> {
+ panic!()
+ }
}
// Key that identifies a resource. Implements `PartialEq`, `Eq` and `Hash` so that two resources
@@ -315,8 +345,13 @@ impl SyncCommandBufferBuilder {
R: RenderPassAbstract,
F: FramebufferAbstract
{
+ let (is_secondary, inside_render_pass) = match kind {
+ Kind::Primary => (false, false),
+ Kind::Secondary { ref render_pass, .. } => (true, render_pass.is_some()),
+ };
+
let cmd = UnsafeCommandBufferBuilder::new(pool, kind, flags)?;
- Ok(SyncCommandBufferBuilder::from_unsafe_cmd(cmd))
+ Ok(SyncCommandBufferBuilder::from_unsafe_cmd(cmd, is_secondary, inside_render_pass))
}
/// Builds a `SyncCommandBufferBuilder` from an existing `UnsafeCommandBufferBuilder`.
@@ -329,16 +364,24 @@ impl SyncCommandBufferBuilder {
/// you must take into account the fact that the `SyncCommandBufferBuilder` won't be aware of
/// any existing resource usage.
#[inline]
- pub unsafe fn from_unsafe_cmd(cmd: UnsafeCommandBufferBuilder )
- -> SyncCommandBufferBuilder {
+ pub unsafe fn from_unsafe_cmd(cmd: UnsafeCommandBufferBuilder , is_secondary: bool,
+ inside_render_pass: bool) -> SyncCommandBufferBuilder {
+ let latest_render_pass_enter = if inside_render_pass {
+ Some(0)
+ } else {
+ None
+ };
+
SyncCommandBufferBuilder {
inner: cmd,
resources: FnvHashMap::default(),
pending_barrier: UnsafeCommandBufferBuilderPipelineBarrier::new(),
commands: Arc::new(Mutex::new(Commands {
first_unflushed: 0,
+ latest_render_pass_enter,
commands: Vec::new(),
})),
+ is_secondary,
}
}
@@ -373,10 +416,9 @@ impl SyncCommandBufferBuilder {
Entry::Occupied(entry) => {
let collision_command_id = entry.key().command_id;
debug_assert!(collision_command_id <= latest_command_id);
- if collision_command_id == latest_command_id {
- return Err(SyncCommandBufferBuilderError::Conflict);
- }
+ let entry_key_resource_index = entry.key().resource_index;
+ let entry_key_resource_ty = entry.key().resource_ty;
let mut entry = entry.into_mut();
// Find out if we have a collision with the pending commands.
@@ -394,11 +436,33 @@ impl SyncCommandBufferBuilder {
self.pending_barrier = UnsafeCommandBufferBuilderPipelineBarrier::new();
{
let mut commands_lock = self.commands.lock().unwrap();
- let f = commands_lock.first_unflushed;
- for command in &mut commands_lock.commands[f .. latest_command_id] {
+ let start = commands_lock.first_unflushed;
+ let end = if let Some(rp_enter) = commands_lock.latest_render_pass_enter {
+ rp_enter
+ } else {
+ latest_command_id
+ };
+ if collision_command_id >= end {
+ return Err(SyncCommandBufferBuilderError::Conflict {
+ command1_name: commands_lock.commands[collision_command_id].name(),
+ command1_param: match entry_key_resource_ty {
+ KeyTy::Buffer => commands_lock.commands[collision_command_id].buffer_name(entry_key_resource_index),
+ KeyTy::Image => commands_lock.commands[collision_command_id].image_name(entry_key_resource_index),
+ },
+ command1_offset: collision_command_id,
+
+ command2_name: commands_lock.commands[latest_command_id].name(),
+ command2_param: match resource_ty {
+ KeyTy::Buffer => commands_lock.commands[latest_command_id].buffer_name(resource_index),
+ KeyTy::Image => commands_lock.commands[latest_command_id].image_name(resource_index),
+ },
+ command2_offset: latest_command_id,
+ });
+ }
+ for command in &mut commands_lock.commands[start .. end] {
command.send(&mut self.inner);
}
- commands_lock.first_unflushed = latest_command_id;
+ commands_lock.first_unflushed = end;
}
}
}
@@ -448,7 +512,7 @@ impl SyncCommandBufferBuilder {
entry.access = access;
entry.exclusive_any = true;
entry.exclusive = exclusive;
- if exclusive {
+ if exclusive || end_layout != ImageLayout::Undefined {
// Only modify the layout in case of a write, because buffer operations
// pass `Undefined` for the layout. While a buffer write *must* set the
// layout to `Undefined`, a buffer read must not touch it.
@@ -466,7 +530,8 @@ impl SyncCommandBufferBuilder {
// Handle the case when the initial layout requirement of the image is different
// from the first layout usage.
- if resource_ty == KeyTy::Image && start_layout != ImageLayout::Undefined &&
+ if !self.is_secondary && resource_ty == KeyTy::Image &&
+ start_layout != ImageLayout::Undefined &&
start_layout != ImageLayout::Preinitialized
{
let commands_lock = self.commands.lock().unwrap();
@@ -515,6 +580,8 @@ impl SyncCommandBufferBuilder {
where P: CommandPoolBuilderAlloc
{
let mut commands_lock = self.commands.lock().unwrap();
+ debug_assert!(commands_lock.latest_render_pass_enter.is_none() ||
+ self.pending_barrier.is_empty());
// Flush the commands that haven't been flushed yet.
unsafe {
@@ -526,37 +593,39 @@ impl SyncCommandBufferBuilder {
}
// Transition images to their desired final layout.
- unsafe {
- let mut barrier = UnsafeCommandBufferBuilderPipelineBarrier::new();
+ if !self.is_secondary {
+ unsafe {
+ let mut barrier = UnsafeCommandBufferBuilderPipelineBarrier::new();
- for (key, mut state) in &mut self.resources {
- if key.resource_ty != KeyTy::Image {
- continue;
+ for (key, mut state) in &mut self.resources {
+ if key.resource_ty != KeyTy::Image {
+ continue;
+ }
+
+ let img = commands_lock.commands[key.command_id].image(key.resource_index);
+ if img.final_layout_requirement() == state.current_layout {
+ continue;
+ }
+
+ state.exclusive_any = true;
+ barrier.add_image_memory_barrier(img,
+ 0 .. img.mipmap_levels(),
+ 0 .. img.dimensions().array_layers(),
+ state.stages,
+ state.access,
+ PipelineStages {
+ bottom_of_pipe: true,
+ ..PipelineStages::none()
+ }, // TODO:?
+ AccessFlagBits::none(),
+ true,
+ None, // TODO: access?
+ state.current_layout,
+ img.final_layout_requirement());
}
- let img = commands_lock.commands[key.command_id].image(key.resource_index);
- if img.final_layout_requirement() == state.current_layout {
- continue;
- }
-
- state.exclusive_any = true;
- barrier.add_image_memory_barrier(img,
- 0 .. img.mipmap_levels(),
- 0 .. img.dimensions().array_layers(),
- state.stages,
- state.access,
- PipelineStages {
- bottom_of_pipe: true,
- ..PipelineStages::none()
- }, // TODO:?
- AccessFlagBits::none(),
- true,
- None, // TODO: access?
- state.current_layout,
- img.final_layout_requirement());
+ self.inner.pipeline_barrier(&barrier);
}
-
- self.inner.pipeline_barrier(&barrier);
}
// Fill the `commands` list.
@@ -606,6 +675,10 @@ impl SyncCommandBufferBuilder {
where F: FramebufferAbstract + Send + Sync + 'static,
I: Iterator ) {
out.begin_render_pass(&self.framebuffer,
self.subpass_contents,
@@ -627,6 +700,10 @@ impl SyncCommandBufferBuilder {
fn image(&self, num: usize) -> &ImageAccess {
self.framebuffer.attached_image_view(num).unwrap().parent()
}
+
+ fn image_name(&self, num: usize) -> Cow<'static, str> {
+ format!("attachment {}", num).into()
+ }
}
let atch_desc = (0 .. framebuffer.num_attachments())
@@ -658,6 +735,11 @@ impl SyncCommandBufferBuilder {
desc.initial_layout, desc.final_layout)?;
}
+ {
+ let mut cmd_lock = self.commands.lock().unwrap();
+ cmd_lock.latest_render_pass_enter = Some(cmd_lock.commands.len() - 1);
+ }
+
Ok(())
}
@@ -675,6 +757,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd
where B: BufferAccess + Send + Sync + 'static
{
+ fn name(&self) -> &'static str {
+ "vkCmdBindIndexBuffer"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.bind_index_buffer(&self.buffer, self.index_ty);
}
@@ -696,6 +782,11 @@ impl SyncCommandBufferBuilder {
assert_eq!(num, 0);
&self.buffer
}
+
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "index buffer".into()
+ }
}
self.commands
@@ -731,6 +822,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd ) {
out.bind_pipeline_graphics(&self.pipeline);
}
@@ -764,6 +859,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd ) {
out.bind_pipeline_compute(&self.pipeline);
}
@@ -833,6 +932,10 @@ impl SyncCommandBufferBuilder {
D: ImageAccess + Send + Sync + 'static,
R: Iterator ) {
out.blit_image(self.source.as_ref().unwrap(), self.source_layout,
self.destination.as_ref().unwrap(), self.destination_layout,
@@ -871,6 +974,16 @@ impl SyncCommandBufferBuilder {
panic!()
}
}
+
+ fn image_name(&self, num: usize) -> Cow<'static, str> {
+ if num == 0 {
+ "source".into()
+ } else if num == 1 {
+ "destination".into()
+ } else {
+ panic!()
+ }
+ }
}
self.commands.lock().unwrap().commands.push(Box::new(Cmd {
@@ -931,6 +1044,10 @@ impl SyncCommandBufferBuilder {
where I: ImageAccess + Send + Sync + 'static,
R: Iterator ) {
out.clear_color_image(self.image.as_ref().unwrap(), self.layout, self.color,
self.regions.take().unwrap());
@@ -955,6 +1072,11 @@ impl SyncCommandBufferBuilder {
assert_eq!(num, 0);
self.image.as_ref().unwrap()
}
+
+ fn image_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "target".into()
+ }
}
self.commands.lock().unwrap().commands.push(Box::new(Cmd {
@@ -1001,6 +1123,10 @@ impl SyncCommandBufferBuilder {
D: BufferAccess + Send + Sync + 'static,
R: Iterator ) {
out.copy_buffer(self.source.as_ref().unwrap(),
self.destination.as_ref().unwrap(),
@@ -1034,6 +1160,14 @@ impl SyncCommandBufferBuilder {
_ => panic!(),
}
}
+
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ match num {
+ 0 => "source".into(),
+ 1 => "destination".into(),
+ _ => panic!(),
+ }
+ }
}
self.commands.lock().unwrap().commands.push(Box::new(Cmd {
@@ -1094,6 +1228,10 @@ impl SyncCommandBufferBuilder {
D: ImageAccess + Send + Sync + 'static,
R: Iterator ) {
out.copy_buffer_to_image(self.source.as_ref().unwrap(),
self.destination.as_ref().unwrap(),
@@ -1129,10 +1267,20 @@ impl SyncCommandBufferBuilder {
self.source.as_ref().unwrap()
}
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "source".into()
+ }
+
fn image(&self, num: usize) -> &ImageAccess {
assert_eq!(num, 0);
self.destination.as_ref().unwrap()
}
+
+ fn image_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "destination".into()
+ }
}
self.commands.lock().unwrap().commands.push(Box::new(Cmd {
@@ -1194,6 +1342,10 @@ impl SyncCommandBufferBuilder {
D: BufferAccess + Send + Sync + 'static,
R: Iterator ) {
out.copy_image_to_buffer(self.source.as_ref().unwrap(),
self.source_layout,
@@ -1229,10 +1381,20 @@ impl SyncCommandBufferBuilder {
self.destination.as_ref().unwrap()
}
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "destination".into()
+ }
+
fn image(&self, num: usize) -> &ImageAccess {
assert_eq!(num, 0);
self.source.as_ref().unwrap()
}
+
+ fn image_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "source".into()
+ }
}
self.commands.lock().unwrap().commands.push(Box::new(Cmd {
@@ -1278,6 +1440,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdDispatch"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.dispatch(self.dimensions);
}
@@ -1307,6 +1473,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd
where B: BufferAccess + Send + Sync + 'static
{
+ fn name(&self) -> &'static str {
+ "vkCmdDispatchIndirect"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.dispatch_indirect(&self.buffer);
}
@@ -1328,6 +1498,11 @@ impl SyncCommandBufferBuilder {
assert_eq!(num, 0);
&self.buffer
}
+
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "indirect buffer".into()
+ }
}
self.commands
@@ -1363,6 +1538,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdDraw"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.draw(self.vertex_count,
self.instance_count,
@@ -1397,6 +1576,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdDrawIndexed"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.draw_indexed(self.index_count,
self.instance_count,
@@ -1434,6 +1617,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd
where B: BufferAccess + Send + Sync + 'static
{
+ fn name(&self) -> &'static str {
+ "vkCmdDrawIndirect"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.draw_indirect(&self.buffer, self.draw_count, self.stride);
}
@@ -1455,6 +1642,11 @@ impl SyncCommandBufferBuilder {
assert_eq!(num, 0);
&self.buffer
}
+
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "indirect buffer".into()
+ }
}
self.commands.lock().unwrap().commands.push(Box::new(Cmd {
@@ -1493,6 +1685,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd
where B: BufferAccess + Send + Sync + 'static
{
+ fn name(&self) -> &'static str {
+ "vkCmdDrawIndexedIndirect"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.draw_indexed_indirect(&self.buffer, self.draw_count, self.stride);
}
@@ -1514,6 +1710,11 @@ impl SyncCommandBufferBuilder {
assert_eq!(num, 0);
&self.buffer
}
+
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ assert_eq!(num, 0);
+ "indirect buffer".into()
+ }
}
self.commands.lock().unwrap().commands.push(Box::new(Cmd {
@@ -1543,6 +1744,10 @@ impl SyncCommandBufferBuilder {
struct Cmd;
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdEndRenderPass"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.end_render_pass();
}
@@ -1552,7 +1757,10 @@ impl SyncCommandBufferBuilder {
}
}
- self.commands.lock().unwrap().commands.push(Box::new(Cmd));
+ let mut cmd_lock = self.commands.lock().unwrap();
+ cmd_lock.commands.push(Box::new(Cmd));
+ debug_assert!(cmd_lock.latest_render_pass_enter.is_some());
+ cmd_lock.latest_render_pass_enter = None;
}
/// Starts the process of executing secondary command buffers. Returns an intermediate struct
@@ -1579,6 +1787,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd
where B: BufferAccess + Send + Sync + 'static
{
+ fn name(&self) -> &'static str {
+ "vkCmdFillBuffer"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.fill_buffer(&self.buffer, self.data);
}
@@ -1600,6 +1812,10 @@ impl SyncCommandBufferBuilder {
assert_eq!(num, 0);
&self.buffer
}
+
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ "destination".into()
+ }
}
self.commands
@@ -1631,6 +1847,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdNextSubpass"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.next_subpass(self.subpass_contents);
}
@@ -1665,6 +1885,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd ) {
out.push_constants::<_, [u8]>(&self.pipeline_layout,
self.stages,
@@ -1709,6 +1933,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdResetEvent"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.reset_event(&self.event, self.stages);
}
@@ -1736,6 +1964,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdSetBlendConstants"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.set_blend_constants(self.constants);
}
@@ -1762,6 +1994,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdSetDepthBias"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.set_depth_bias(self.constant_factor, self.clamp, self.slope_factor);
}
@@ -1787,6 +2023,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdSetDepthBounds"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.set_depth_bounds(self.min, self.max);
}
@@ -1812,6 +2052,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdSetEvent"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.set_event(&self.event, self.stages);
}
@@ -1839,6 +2083,10 @@ impl SyncCommandBufferBuilder {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdSetLineWidth"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.set_line_width(self.line_width);
}
@@ -1872,6 +2120,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd
where I: Iterator ) {
out.set_scissor(self.first_scissor, self.scissors.take().unwrap());
}
@@ -1902,6 +2154,10 @@ impl SyncCommandBufferBuilder {
impl Command for Cmd
where I: Iterator ) {
out.set_viewport(self.first_viewport, self.viewports.take().unwrap());
}
@@ -1932,6 +2188,10 @@ impl SyncCommandBufferBuilder {
where B: BufferAccess + Send + Sync + 'static,
D: Send + Sync + 'static
{
+ fn name(&self) -> &'static str {
+ "vkCmdUpdateBuffer"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.update_buffer(&self.buffer, &self.data);
}
@@ -1953,6 +2213,10 @@ impl SyncCommandBufferBuilder {
assert_eq!(num, 0);
&self.buffer
}
+
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ "destination".into()
+ }
}
self.commands
@@ -2017,6 +2281,10 @@ impl<'b, P> SyncCommandBufferBuilderBindDescriptorSets<'b, P> {
where Pl: PipelineLayoutAbstract,
I: Iterator ) {
out.bind_descriptor_sets(self.graphics,
&self.pipeline_layout,
@@ -2028,12 +2296,119 @@ impl<'b, P> SyncCommandBufferBuilderBindDescriptorSets<'b, P> {
fn into_final_command(self: Box Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdBindVertexBuffers"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.bind_vertex_buffers(self.first_binding, self.inner.take().unwrap());
}
@@ -2096,6 +2490,10 @@ impl<'a, P> SyncCommandBufferBuilderBindVertexBuffer<'a, P> {
fn buffer(&self, num: usize) -> &BufferAccess {
&self.buffers[num]
}
+
+ fn buffer_name(&self, num: usize) -> Cow<'static, str> {
+ format!("Buffer #{}", num).into()
+ }
}
let num_buffers = self.buffers.len();
@@ -2158,6 +2556,10 @@ impl<'a, P> SyncCommandBufferBuilderExecuteCommands<'a, P> {
}
impl Command for Cmd {
+ fn name(&self) -> &'static str {
+ "vkCmdExecuteCommands"
+ }
+
unsafe fn send(&mut self, out: &mut UnsafeCommandBufferBuilder ) {
out.execute_commands(self.inner.take().unwrap());
}
diff --git a/vulkano/src/descriptor/descriptor.rs b/vulkano/src/descriptor/descriptor.rs
index a2fceae5..81db1bc7 100644
--- a/vulkano/src/descriptor/descriptor.rs
+++ b/vulkano/src/descriptor/descriptor.rs
@@ -43,6 +43,8 @@
use format::Format;
use image::Dimensions;
+use sync::AccessFlagBits;
+use sync::PipelineStages;
use std::cmp;
use std::ops::BitOr;
use vk;
@@ -100,6 +102,56 @@ impl DescriptorDesc {
readonly: self.readonly && other.readonly,
})
}
+
+ /// Returns the pipeline stages and access flags corresponding to the usage of this descriptor.
+ ///
+ /// # Panic
+ ///
+ /// Panicks if the type if `Sampler`.
+ ///
+ pub fn pipeline_stages_and_access(&self) -> (PipelineStages, AccessFlagBits) {
+ let stages: PipelineStages = self.stages.into();
+
+ let access = match self.ty {
+ DescriptorDescTy::Sampler => panic!(),
+ DescriptorDescTy::CombinedImageSampler(_) | DescriptorDescTy::Image(_) => {
+ AccessFlagBits {
+ shader_read: true,
+ shader_write: !self.readonly,
+ .. AccessFlagBits::none()
+ }
+ },
+ DescriptorDescTy::TexelBuffer { .. } => {
+ AccessFlagBits {
+ shader_read: true,
+ shader_write: !self.readonly,
+ .. AccessFlagBits::none()
+ }
+ },
+ DescriptorDescTy::InputAttachment { .. } => {
+ AccessFlagBits {
+ input_attachment_read: true,
+ .. AccessFlagBits::none()
+ }
+ },
+ DescriptorDescTy::Buffer(ref buf) => {
+ if buf.storage {
+ AccessFlagBits {
+ shader_read: true,
+ shader_write: !self.readonly,
+ .. AccessFlagBits::none()
+ }
+ } else {
+ AccessFlagBits {
+ uniform_read: true,
+ .. AccessFlagBits::none()
+ }
+ }
+ },
+ };
+
+ (stages, access)
+ }
}
/// Describes the content and layout of each array element of a descriptor.
@@ -472,6 +524,21 @@ impl BitOr for ShaderStages {
}
}
+impl From (self, pool: P)
- -> Result