<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::error::Error;
use std::iter;
use std::sync::Arc;

use buffer::TrackedBuffer;
use command_buffer::RawCommandBufferPrototype;
use command_buffer::DynamicState;
use command_buffer::pool::CommandPool;
use command_buffer::StatesManager;
use command_buffer::SubmitInfo;
use command_buffer::SubmitBuilder;
use command_buffer::Submit;
use command_buffer::sys::PipelineBarrierBuilder;
use command_buffer::sys::UnsafeCommandBufferBuilder;
use descriptor::PipelineLayoutRef;
use descriptor::descriptor_set::collection::TrackedDescriptorSetsCollection;
use device::Device;
use device::Queue;
use framebuffer::traits::TrackedFramebuffer;
use framebuffer::RenderPass;
use framebuffer::RenderPassClearValues;
use image::Layout;
use image::TrackedImage;
use instance::QueueFamily;
use pipeline::ComputePipeline;
use pipeline::GraphicsPipeline;
use pipeline::vertex::Source;
use sync::Fence;
use vk;

pub use self::begin_render_pass::CmdBeginRenderPass;
pub use self::bind_index_buffer::CmdBindIndexBuffer;
pub use self::bind_descriptor_sets::{CmdBindDescriptorSets, CmdBindDescriptorSetsError};
pub use self::bind_pipeline::CmdBindPipeline;
pub use self::bind_vertex_buffers::CmdBindVertexBuffers;
pub use self::blit_image_unsynced::{BlitRegion, BlitRegionAspect};
pub use self::blit_image_unsynced::{CmdBlitImageUnsynced, CmdBlitImageUnsyncedError};
pub use self::copy_buffer::{CmdCopyBuffer, CmdCopyBufferError};
pub use self::dispatch::CmdDispatch;
pub use self::draw::CmdDraw;
pub use self::empty::{empty, EmptyCommandsList};
pub use self::end_render_pass::CmdEndRenderPass;
pub use self::fill_buffer::{CmdFillBuffer, CmdFillBufferError};
pub use self::next_subpass::CmdNextSubpass;
pub use self::push_constants::{CmdPushConstants, CmdPushConstantsError};
pub use self::set_state::{CmdSetState};
pub use self::update_buffer::{CmdUpdateBuffer, CmdUpdateBufferError};

mod begin_render_pass;
mod bind_descriptor_sets;
mod bind_index_buffer;
mod bind_pipeline;
mod bind_vertex_buffers;
mod blit_image_unsynced;
mod copy_buffer;
mod dispatch;
mod draw;
mod empty;
mod end_render_pass;
//pub mod execute;      // TODO: reenable when the concept of a command buffer is well defined
mod fill_buffer;
mod next_subpass;
mod push_constants;
mod set_state;
mod update_buffer;

/// A list of commands that can be turned into a command buffer.
///
/// This is just a naked list of commands. It stores buffers, images, etc. but the list of commands
/// itself is not a Vulkan object.
pub unsafe trait CommandsList {
    /// Adds a command that writes the content of a buffer.
    ///
    /// After this command is executed, the content of `buffer` will become `data`.
    #[inline]
    fn update_buffer<'a, B, D: ?Sized>(self, buffer: B, data: &'a D)
                                       -> Result<CmdUpdateBuffer<'a, Self, B, D>, CmdUpdateBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass, B: TrackedBuffer, D: Copy + 'static
    {
        CmdUpdateBuffer::new(self, buffer, data)
    }

    /// Adds a command that copies the content of a buffer to another.
    #[inline]
    fn copy_buffer<S, D>(self, source: S, destination: D)
                         -> Result<CmdCopyBuffer<Self, S, D>, CmdCopyBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass,
              S: TrackedBuffer, D: TrackedBuffer
    {
        CmdCopyBuffer::new(self, source, destination)
    }

    /// Adds a command that writes the content of a buffer.
    #[inline]
    fn fill_buffer<B>(self, buffer: B, data: u32)
                      -> Result<CmdFillBuffer<Self, B>, CmdFillBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass, B: TrackedBuffer
    {
        CmdFillBuffer::new(self, buffer, data)
    }

    // TODO: reenable
    /*/// Adds a command that executes a secondary command buffer.
    ///
    /// When you create a command buffer, you have the possibility to create either a primary
    /// command buffer or a secondary command buffer. Secondary command buffers can't be executed
    /// directly, but can be executed from a primary command buffer.
    ///
    /// A secondary command buffer can't execute another secondary command buffer. The only way
    /// you can use `execute` is to make a primary command buffer call a secondary command buffer.
    #[inline]
    fn execute<Cb>(self, command_buffer: Cb) -> execute::ExecuteCommand<Cb, Self>
        where Self: Sized, Cb: CommandsListOutput       /* FIXME: */
    {
        execute::ExecuteCommand::new(self, command_buffer)
    }*/

    /// Adds a command that executes a compute shader.
    ///
    /// The `dimensions` are the number of working groups to start. The GPU will execute the
    /// compute shader `dimensions[0] * dimensions[1] * dimensions[2]` times.
    ///
    /// The `pipeline` is the compute pipeline that will be executed, and the sets and push
    /// constants will be accessible to all the invocations.
    #[inline]
    fn dispatch<Pl, S, Pc>(self, pipeline: Arc<ComputePipeline<Pl>>, sets: S,
                           dimensions: [u32; 3], push_constants: Pc)
                           -> CmdDispatch<Self, Pl, S, Pc>
        where Self: Sized + CommandsList, Pl: PipelineLayoutRef,
              S: TrackedDescriptorSetsCollection
    {
        CmdDispatch::new(self, pipeline, sets, dimensions, push_constants)
    }

    /// Adds a command that starts a render pass.
    ///
    /// If `secondary` is true, then you will only be able to add secondary command buffers while
    /// you're inside the first subpass on the render pass. If `secondary` is false, you will only
    /// be able to add inline draw commands and not secondary command buffers.
    ///
    /// You must call this before you can add draw commands.
    #[inline]
    fn begin_render_pass<F, C>(self, framebuffer: F, secondary: bool, clear_values: C)
                               -> CmdBeginRenderPass<Self, F::RenderPass, F>
        where Self: Sized, F: TrackedFramebuffer,
              F::RenderPass: RenderPass + RenderPassClearValues<C>
    {
        CmdBeginRenderPass::new(self, framebuffer, secondary, clear_values)
    }

    /// Adds a command that jumps to the next subpass of the current render pass.
    #[inline]
    fn next_subpass(self, secondary: bool) -> CmdNextSubpass<Self>
        where Self: Sized
    {
        CmdNextSubpass::new(self, secondary)
    }

    /// Adds a command that ends the current render pass.
    ///
    /// This must be called after you went through all the subpasses and before you can build
    /// the command buffer or add further commands.
    #[inline]
    fn end_render_pass(self) -> CmdEndRenderPass<Self>
        where Self: Sized
    {
        CmdEndRenderPass::new(self)
    }

    /// Adds a command that draws.
    ///
    /// Can only be used from inside a render pass.
    #[inline]
    fn draw<Pv, Pl, Prp, S, Pc, V>(self, pipeline: Arc<GraphicsPipeline<Pv, Pl, Prp>>,
                                   dynamic: DynamicState, vertices: V, sets: S,
                                   push_constants: Pc)
                                   -> CmdDraw<Self, V, Pv, Pl, Prp, S, Pc>
        where Self: Sized + CommandsList + CommandsListPossibleInsideRenderPass, Pl: PipelineLayoutRef,
              S: TrackedDescriptorSetsCollection, Pv: Source<V>
    {
        CmdDraw::new(self, pipeline, dynamic, vertices, sets, push_constants)
    }

    /// Appends this list of commands at the end of a command buffer in construction.
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>);<commit_msg>Some comments for buffer copy commands<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::error::Error;
use std::iter;
use std::sync::Arc;

use buffer::TrackedBuffer;
use command_buffer::RawCommandBufferPrototype;
use command_buffer::DynamicState;
use command_buffer::pool::CommandPool;
use command_buffer::StatesManager;
use command_buffer::SubmitInfo;
use command_buffer::SubmitBuilder;
use command_buffer::Submit;
use command_buffer::sys::PipelineBarrierBuilder;
use command_buffer::sys::UnsafeCommandBufferBuilder;
use descriptor::PipelineLayoutRef;
use descriptor::descriptor_set::collection::TrackedDescriptorSetsCollection;
use device::Device;
use device::Queue;
use framebuffer::traits::TrackedFramebuffer;
use framebuffer::RenderPass;
use framebuffer::RenderPassClearValues;
use image::Layout;
use image::TrackedImage;
use instance::QueueFamily;
use pipeline::ComputePipeline;
use pipeline::GraphicsPipeline;
use pipeline::vertex::Source;
use sync::Fence;
use vk;

pub use self::begin_render_pass::CmdBeginRenderPass;
pub use self::bind_index_buffer::CmdBindIndexBuffer;
pub use self::bind_descriptor_sets::{CmdBindDescriptorSets, CmdBindDescriptorSetsError};
pub use self::bind_pipeline::CmdBindPipeline;
pub use self::bind_vertex_buffers::CmdBindVertexBuffers;
pub use self::blit_image_unsynced::{BlitRegion, BlitRegionAspect};
pub use self::blit_image_unsynced::{CmdBlitImageUnsynced, CmdBlitImageUnsyncedError};
pub use self::copy_buffer::{CmdCopyBuffer, CmdCopyBufferError};
pub use self::dispatch::CmdDispatch;
pub use self::draw::CmdDraw;
pub use self::empty::{empty, EmptyCommandsList};
pub use self::end_render_pass::CmdEndRenderPass;
pub use self::fill_buffer::{CmdFillBuffer, CmdFillBufferError};
pub use self::next_subpass::CmdNextSubpass;
pub use self::push_constants::{CmdPushConstants, CmdPushConstantsError};
pub use self::set_state::{CmdSetState};
pub use self::update_buffer::{CmdUpdateBuffer, CmdUpdateBufferError};

mod begin_render_pass;
mod bind_descriptor_sets;
mod bind_index_buffer;
mod bind_pipeline;
mod bind_vertex_buffers;
mod blit_image_unsynced;
mod copy_buffer;
mod dispatch;
mod draw;
mod empty;
mod end_render_pass;
//pub mod execute;      // TODO: reenable when the concept of a command buffer is well defined
mod fill_buffer;
mod next_subpass;
mod push_constants;
mod set_state;
mod update_buffer;

/// A list of commands that can be turned into a command buffer.
///
/// This is just a naked list of commands. It stores buffers, images, etc. but the list of commands
/// itself is not a Vulkan object.
pub unsafe trait CommandsList {
    /// Adds a command that writes the content of a buffer.
    ///
    /// After this command is executed, the content of `buffer` will become `data`. If `data` is
    /// smaller than `buffer`, then only the beginning of `buffer` will be modified and the rest
    /// will be left untouched. If `buffer` is smaller than `data`, `buffer` will be entirely
    /// written and no error is generated.
    ///
    /// This command is limited to 64kB (65536 bytes) of data and should only be used for small
    /// amounts of data. For large amounts of data, you are encouraged to write the data to a
    /// buffer and use `copy_buffer` instead.
    #[inline]
    fn update_buffer<'a, B, D: ?Sized>(self, buffer: B, data: &'a D)
                                       -> Result<CmdUpdateBuffer<'a, Self, B, D>, CmdUpdateBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass, B: TrackedBuffer, D: Copy + 'static
    {
        CmdUpdateBuffer::new(self, buffer, data)
    }

    /// Adds a command that copies the content of a buffer to another.
    ///
    /// If `source` is smaller than `destination`, only the beginning of `destination` will be
    /// modified.
    #[inline]
    fn copy_buffer<S, D>(self, source: S, destination: D)
                         -> Result<CmdCopyBuffer<Self, S, D>, CmdCopyBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass,
              S: TrackedBuffer, D: TrackedBuffer
    {
        CmdCopyBuffer::new(self, source, destination)
    }

    /// Adds a command that writes the content of a buffer.
    ///
    /// This function is similar to the `memset` function in C. The `data` parameter is a number
    /// that will be repeatidely written through the entire buffer.
    ///
    /// > **Note**: This function is technically safe because buffers can only contain integers or
    /// > floating point numbers, which are always valid whatever their memory representation is.
    /// > But unless your buffer actually contains only 32-bits integers, you are encouraged to use
    /// > this function only for zeroing the content of a buffer by passing `0` for the data.
    #[inline]
    fn fill_buffer<B>(self, buffer: B, data: u32)
                      -> Result<CmdFillBuffer<Self, B>, CmdFillBufferError>
        where Self: Sized + CommandsListPossibleOutsideRenderPass, B: TrackedBuffer
    {
        CmdFillBuffer::new(self, buffer, data)
    }

    // TODO: reenable
    /*/// Adds a command that executes a secondary command buffer.
    ///
    /// When you create a command buffer, you have the possibility to create either a primary
    /// command buffer or a secondary command buffer. Secondary command buffers can't be executed
    /// directly, but can be executed from a primary command buffer.
    ///
    /// A secondary command buffer can't execute another secondary command buffer. The only way
    /// you can use `execute` is to make a primary command buffer call a secondary command buffer.
    #[inline]
    fn execute<Cb>(self, command_buffer: Cb) -> execute::ExecuteCommand<Cb, Self>
        where Self: Sized, Cb: CommandsListOutput       /* FIXME: */
    {
        execute::ExecuteCommand::new(self, command_buffer)
    }*/

    /// Adds a command that executes a compute shader.
    ///
    /// The `dimensions` are the number of working groups to start. The GPU will execute the
    /// compute shader `dimensions[0] * dimensions[1] * dimensions[2]` times.
    ///
    /// The `pipeline` is the compute pipeline that will be executed, and the sets and push
    /// constants will be accessible to all the invocations.
    #[inline]
    fn dispatch<Pl, S, Pc>(self, pipeline: Arc<ComputePipeline<Pl>>, sets: S,
                           dimensions: [u32; 3], push_constants: Pc)
                           -> CmdDispatch<Self, Pl, S, Pc>
        where Self: Sized + CommandsList, Pl: PipelineLayoutRef,
              S: TrackedDescriptorSetsCollection
    {
        CmdDispatch::new(self, pipeline, sets, dimensions, push_constants)
    }

    /// Adds a command that starts a render pass.
    ///
    /// If `secondary` is true, then you will only be able to add secondary command buffers while
    /// you're inside the first subpass on the render pass. If `secondary` is false, you will only
    /// be able to add inline draw commands and not secondary command buffers.
    ///
    /// You must call this before you can add draw commands.
    #[inline]
    fn begin_render_pass<F, C>(self, framebuffer: F, secondary: bool, clear_values: C)
                               -> CmdBeginRenderPass<Self, F::RenderPass, F>
        where Self: Sized, F: TrackedFramebuffer,
              F::RenderPass: RenderPass + RenderPassClearValues<C>
    {
        CmdBeginRenderPass::new(self, framebuffer, secondary, clear_values)
    }

    /// Adds a command that jumps to the next subpass of the current render pass.
    #[inline]
    fn next_subpass(self, secondary: bool) -> CmdNextSubpass<Self>
        where Self: Sized
    {
        CmdNextSubpass::new(self, secondary)
    }

    /// Adds a command that ends the current render pass.
    ///
    /// This must be called after you went through all the subpasses and before you can build
    /// the command buffer or add further commands.
    #[inline]
    fn end_render_pass(self) -> CmdEndRenderPass<Self>
        where Self: Sized
    {
        CmdEndRenderPass::new(self)
    }

    /// Adds a command that draws.
    ///
    /// Can only be used from inside a render pass.
    #[inline]
    fn draw<Pv, Pl, Prp, S, Pc, V>(self, pipeline: Arc<GraphicsPipeline<Pv, Pl, Prp>>,
                                   dynamic: DynamicState, vertices: V, sets: S,
                                   push_constants: Pc)
                                   -> CmdDraw<Self, V, Pv, Pl, Prp, S, Pc>
        where Self: Sized + CommandsList + CommandsListPossibleInsideRenderPass,
              Pl: PipelineLayoutRef,
              S: TrackedDescriptorSetsCollection,
              Pv: Source<V>
    {
        CmdDraw::new(self, pipeline, dynamic, vertices, sets, push_constants)
    }

    /// Appends this list of commands at the end of a command buffer in construction.
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>);
{'fraction_non_alphanumeric': 0.10063294814470704, 'fraction_numerical': 0.0024388827594216365, 'mean_word_length': 3.230410218619504, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 83, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4876517', 'n_tokens_mistral': 4878, 'n_tokens_neox': 4842, 'n_words': 1713}