<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::sync::Arc;
use std::ops::Range;
use std::ptr;
use smallvec::SmallVec;

use command_buffer::RawCommandBufferPrototype;
use command_buffer::CommandsList;
use command_buffer::CommandsListSink;
use device::Device;
use format::ClearValue;
use framebuffer::traits::TrackedFramebuffer;
use framebuffer::RenderPass;
use framebuffer::RenderPassClearValues;
use VulkanObject;
use VulkanPointers;
use vk;

/// Wraps around a commands list and adds to the end of it a command that enters a render pass.
pub struct CmdBeginRenderPass<L, Rp, F> where L: CommandsList {
    // Parent commands list.
    previous: L,
    // True if only secondary command buffers can be added.
    secondary: bool,
    // The draw area.
    rect: [Range<u32>; 2],
    // The clear values for the clear attachments.
    clear_values: SmallVec<[vk::ClearValue; 6]>,
    // The raw render pass handle to bind.
    raw_render_pass: vk::RenderPass,
    // The raw framebuffer handle to bind.
    raw_framebuffer: vk::Framebuffer,
    // The device.
    device: Arc<Device>,
    // The render pass. Can be `None` if same as framebuffer.
    render_pass: Option<Rp>,
    // The framebuffer.
    framebuffer: F,
}

impl<L, F> CmdBeginRenderPass<L, F::RenderPass, F>
    where L: CommandsList, F: TrackedFramebuffer
{
    /// See the documentation of the `begin_render_pass` method.
    // TODO: allow setting more parameters
    pub fn new<C>(previous: L, framebuffer: F, secondary: bool, clear_values: C)
                  -> CmdBeginRenderPass<L, F::RenderPass, F>
        where F::RenderPass: RenderPassClearValues<C>
    {
        let raw_render_pass = framebuffer.render_pass().inner().internal_object();
        let device = framebuffer.render_pass().inner().device().clone();
        let raw_framebuffer = framebuffer.internal_object();

        let clear_values = framebuffer.render_pass().convert_clear_values(clear_values)
                                      .map(|clear_value|
        {
            match clear_value {
                ClearValue::None => {
                    vk::ClearValue::color(vk::ClearColorValue::float32([0.0; 4]))
                },
                ClearValue::Float(val) => {
                    vk::ClearValue::color(vk::ClearColorValue::float32(val))
                },
                ClearValue::Int(val) => {
                    vk::ClearValue::color(vk::ClearColorValue::int32(val))
                },
                ClearValue::Uint(val) => {
                    vk::ClearValue::color(vk::ClearColorValue::uint32(val))
                },
                ClearValue::Depth(val) => {
                    vk::ClearValue::depth_stencil(vk::ClearDepthStencilValue {
                        depth: val, stencil: 0
                    })
                },
                ClearValue::Stencil(val) => {
                    vk::ClearValue::depth_stencil(vk::ClearDepthStencilValue {
                        depth: 0.0, stencil: val
                    })
                },
                ClearValue::DepthStencil((depth, stencil)) => {
                    vk::ClearValue::depth_stencil(vk::ClearDepthStencilValue {
                        depth: depth, stencil: stencil,
                    })
                },
            }
        }).collect();

        let rect = [0 .. framebuffer.dimensions()[0], 0 .. framebuffer.dimensions()[1]];

        CmdBeginRenderPass {
            previous: previous,
            secondary: secondary,
            rect: rect,
            clear_values: clear_values,
            raw_render_pass: raw_render_pass,
            raw_framebuffer: raw_framebuffer,
            device: device,
            render_pass: None,
            framebuffer: framebuffer,
        }
    }
}

unsafe impl<L, Rp, F> CommandsList for CmdBeginRenderPass<L, Rp, F> where L: CommandsList {
    #[inline]
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>) {
        self.previous.append(builder);

        assert_eq!(self.device.internal_object(), builder.device().internal_object());

        debug_assert!(self.rect[0].start <= self.rect[0].end);
        debug_assert!(self.rect[1].start <= self.rect[1].end);

        builder.add_command(Box::new(move |raw: &mut RawCommandBufferPrototype| {
            unsafe {
                let vk = raw.device.pointers();
                let cmd = raw.command_buffer.clone().take().unwrap();

                let begin = vk::RenderPassBeginInfo {
                    sType: vk::STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
                    pNext: ptr::null(),
                    renderPass: self.raw_render_pass,
                    framebuffer: self.raw_framebuffer,
                    renderArea: vk::Rect2D {<commit_msg>Perform transitions in begin render pass<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::sync::Arc;
use std::ops::Range;
use std::ptr;
use smallvec::SmallVec;

use command_buffer::RawCommandBufferPrototype;
use command_buffer::CommandsList;
use command_buffer::CommandsListSink;
use device::Device;
use format::ClearValue;
use framebuffer::traits::TrackedFramebuffer;
use framebuffer::RenderPass;
use framebuffer::RenderPassClearValues;
use VulkanObject;
use VulkanPointers;
use vk;

/// Wraps around a commands list and adds to the end of it a command that enters a render pass.
pub struct CmdBeginRenderPass<L, Rp, F> where L: CommandsList {
    // Parent commands list.
    previous: L,
    // True if only secondary command buffers can be added.
    secondary: bool,
    // The draw area.
    rect: [Range<u32>; 2],
    // The clear values for the clear attachments.
    clear_values: SmallVec<[vk::ClearValue; 6]>,
    // The raw render pass handle to bind.
    raw_render_pass: vk::RenderPass,
    // The raw framebuffer handle to bind.
    raw_framebuffer: vk::Framebuffer,
    // The device.
    device: Arc<Device>,
    // The render pass. Can be `None` if same as framebuffer.
    render_pass: Option<Rp>,
    // The framebuffer.
    framebuffer: F,
}

impl<L, F> CmdBeginRenderPass<L, F::RenderPass, F>
    where L: CommandsList, F: TrackedFramebuffer
{
    /// See the documentation of the `begin_render_pass` method.
    // TODO: allow setting more parameters
    pub fn new<C>(previous: L, framebuffer: F, secondary: bool, clear_values: C)
                  -> CmdBeginRenderPass<L, F::RenderPass, F>
        where F::RenderPass: RenderPassClearValues<C>
    {
        let raw_render_pass = framebuffer.render_pass().inner().internal_object();
        let device = framebuffer.render_pass().inner().device().clone();
        let raw_framebuffer = framebuffer.internal_object();

        let clear_values = framebuffer.render_pass().convert_clear_values(clear_values)
                                      .map(|clear_value|
        {
            match clear_value {
                ClearValue::None => {
                    vk::ClearValue::color(vk::ClearColorValue::float32([0.0; 4]))
                },
                ClearValue::Float(val) => {
                    vk::ClearValue::color(vk::ClearColorValue::float32(val))
                },
                ClearValue::Int(val) => {
                    vk::ClearValue::color(vk::ClearColorValue::int32(val))
                },
                ClearValue::Uint(val) => {
                    vk::ClearValue::color(vk::ClearColorValue::uint32(val))
                },
                ClearValue::Depth(val) => {
                    vk::ClearValue::depth_stencil(vk::ClearDepthStencilValue {
                        depth: val, stencil: 0
                    })
                },
                ClearValue::Stencil(val) => {
                    vk::ClearValue::depth_stencil(vk::ClearDepthStencilValue {
                        depth: 0.0, stencil: val
                    })
                },
                ClearValue::DepthStencil((depth, stencil)) => {
                    vk::ClearValue::depth_stencil(vk::ClearDepthStencilValue {
                        depth: depth, stencil: stencil,
                    })
                },
            }
        }).collect();

        let rect = [0 .. framebuffer.dimensions()[0], 0 .. framebuffer.dimensions()[1]];

        CmdBeginRenderPass {
            previous: previous,
            secondary: secondary,
            rect: rect,
            clear_values: clear_values,
            raw_render_pass: raw_render_pass,
            raw_framebuffer: raw_framebuffer,
            device: device,
            render_pass: None,
            framebuffer: framebuffer,
        }
    }
}

unsafe impl<L, Rp, F> CommandsList for CmdBeginRenderPass<L, Rp, F>
    where L: CommandsList, F: TrackedFramebuffer
{
    #[inline]
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>) {
        self.previous.append(builder);

        assert_eq!(self.device.internal_object(), builder.device().internal_object());

        debug_assert!(self.rect[0].start <= self.rect[0].end);
        debug_assert!(self.rect[1].start <= self.rect[1].end);

        self.framebuffer.add_transition(builder);

        builder.add_command(Box::new(move |raw: &mut RawCommandBufferPrototype| {
            unsafe {
                let vk = raw.device.pointers();
                let cmd = raw.command_buffer.clone().take().unwrap();

                let begin = vk::RenderPassBeginInfo {
                    sType: vk::STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
                    pNext: ptr::null(),
                    renderPass: self.raw_render_pass,
                    framebuffer: self.raw_framebuffer,
                    renderArea: vk::Rect2D {
{'fraction_non_alphanumeric': 0.11641906981260317, 'fraction_numerical': 0.006796776386056899, 'mean_word_length': 2.1928084314941105, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6608729', 'n_tokens_mistral': 2985, 'n_tokens_neox': 2841, 'n_words': 668}