<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 buffer::TrackedBuffer;
use buffer::TypedBuffer;
use command_buffer::RawCommandBufferPrototype;
use command_buffer::CommandsList;
use command_buffer::CommandsListSink;
use device::Device;
use pipeline::input_assembly::Index;
use VulkanObject;
use VulkanPointers;
use vk;

/// Wraps around a commands list and adds a command that binds an index buffer at the end of it.
pub struct CmdBindIndexBuffer<L, B> where L: CommandsList {
    // Parent commands list.
    previous: L,
    // Raw handle of the buffer to bind.
    raw_buffer: vk::Buffer,
    // Raw offset of the buffer to bind.
    offset: vk::DeviceSize,
    // Type of index.
    index_type: vk::IndexType,
    // The device of the buffer, so that we can compare it with the command buffer's device.
    device: Arc<Device>,
    // The buffer to bind. Unused, but we need to keep it alive.
    buffer: B,
}

impl<L, B, I> CmdBindIndexBuffer<L, B>
    where L: CommandsList,
          B: TrackedBuffer + TypedBuffer<Content = [I]>,
          I: Index + 'static
{
    /// Builds the command.
    #[inline]
    pub fn new(previous: L, buffer: B) -> CmdBindIndexBuffer<L, B> {
        let device;
        let raw_buffer;
        let offset;

        {
            let inner = buffer.inner();
            device = inner.buffer.device().clone();
            raw_buffer = inner.buffer.internal_object();
            offset = inner.offset as vk::DeviceSize;
        }

        CmdBindIndexBuffer {
            previous: previous,
            raw_buffer: raw_buffer,
            offset: offset,
            index_type: I::ty() as vk::IndexType,
            device: device,
            buffer: buffer,
        }
    }
}

impl<L, B> CmdBindIndexBuffer<L, B> where L: CommandsList, B: TrackedBuffer {
    #[inline]
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>) {
        self.previous.append(builder);

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

        builder.add_buffer_transition(&self.buffer, 0, self.buffer.size(), false);

        builder.add_command(Box::new(move |raw: &mut RawCommandBufferPrototype| {
            let params = (self.raw_buffer, self.offset, self.index_type);
            if raw.bound_index_buffer == params {
                return;
            }

            raw.bound_index_buffer = params;

            unsafe {
                let vk = raw.device.pointers();
                let cmd = raw.command_buffer.clone().take().unwrap();
                vk.CmdBindIndexBuffer(cmd, self.raw_buffer, self.offset, self.index_type);
            }
        }));
    }
}
<commit_msg>Check usage when binding index buffer<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 buffer::TrackedBuffer;
use buffer::TypedBuffer;
use command_buffer::RawCommandBufferPrototype;
use command_buffer::CommandsList;
use command_buffer::CommandsListSink;
use device::Device;
use pipeline::input_assembly::Index;
use VulkanObject;
use VulkanPointers;
use vk;

/// Wraps around a commands list and adds a command that binds an index buffer at the end of it.
pub struct CmdBindIndexBuffer<L, B> where L: CommandsList {
    // Parent commands list.
    previous: L,
    // Raw handle of the buffer to bind.
    raw_buffer: vk::Buffer,
    // Raw offset of the buffer to bind.
    offset: vk::DeviceSize,
    // Type of index.
    index_type: vk::IndexType,
    // The device of the buffer, so that we can compare it with the command buffer's device.
    device: Arc<Device>,
    // The buffer to bind. Unused, but we need to keep it alive.
    buffer: B,
}

impl<L, B, I> CmdBindIndexBuffer<L, B>
    where L: CommandsList,
          B: TrackedBuffer + TypedBuffer<Content = [I]>,
          I: Index + 'static
{
    /// Builds the command.
    #[inline]
    pub fn new(previous: L, buffer: B) -> CmdBindIndexBuffer<L, B> {
        let device;
        let raw_buffer;
        let offset;

        {
            let inner = buffer.inner();
            assert!(inner.buffer.usage_index_buffer());     // TODO: error
            device = inner.buffer.device().clone();
            raw_buffer = inner.buffer.internal_object();
            offset = inner.offset as vk::DeviceSize;
        }

        CmdBindIndexBuffer {
            previous: previous,
            raw_buffer: raw_buffer,
            offset: offset,
            index_type: I::ty() as vk::IndexType,
            device: device,
            buffer: buffer,
        }
    }
}

impl<L, B> CmdBindIndexBuffer<L, B> where L: CommandsList, B: TrackedBuffer {
    #[inline]
    fn append<'a>(&'a self, builder: &mut CommandsListSink<'a>) {
        self.previous.append(builder);

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

        builder.add_buffer_transition(&self.buffer, 0, self.buffer.size(), false);

        builder.add_command(Box::new(move |raw: &mut RawCommandBufferPrototype| {
            let params = (self.raw_buffer, self.offset, self.index_type);
            if raw.bound_index_buffer == params {
                return;
            }

            raw.bound_index_buffer = params;

            unsafe {
                let vk = raw.device.pointers();
                let cmd = raw.command_buffer.clone().take().unwrap();
                vk.CmdBindIndexBuffer(cmd, self.raw_buffer, self.offset, self.index_type);
            }
        }));
    }
}

{'fraction_non_alphanumeric': 0.11091881686595342, 'fraction_numerical': 0.0028319697923222154, 'mean_word_length': 2.2483392948390395, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4549949', 'n_tokens_mistral': 1878, 'n_tokens_neox': 1853, 'n_words': 534}