vk-video 0.1.0

A library for hardware video coding using Vulkan Video, with wgpu integration.
Documentation
use std::sync::Arc;

use ash::vk;

use crate::vulkan_decoder::{VulkanCtxError, VulkanDecoderError};

use super::Device;

pub(crate) struct CommandPool {
    pub(crate) command_pool: vk::CommandPool,
    device: Arc<Device>,
}

impl CommandPool {
    pub(crate) fn new(
        device: Arc<Device>,
        queue_family_index: usize,
    ) -> Result<Self, VulkanCtxError> {
        let create_info = vk::CommandPoolCreateInfo::default()
            .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
            .queue_family_index(queue_family_index as u32);

        let command_pool = unsafe { device.create_command_pool(&create_info, None)? };

        Ok(Self {
            device,
            command_pool,
        })
    }
}

impl Drop for CommandPool {
    fn drop(&mut self) {
        unsafe {
            self.device.destroy_command_pool(self.command_pool, None);
        }
    }
}

impl std::ops::Deref for CommandPool {
    type Target = vk::CommandPool;

    fn deref(&self) -> &Self::Target {
        &self.command_pool
    }
}

pub(crate) struct CommandBuffer {
    pool: Arc<CommandPool>,
    pub(crate) buffer: vk::CommandBuffer,
}

impl CommandBuffer {
    pub(crate) fn new_primary(pool: Arc<CommandPool>) -> Result<Self, VulkanDecoderError> {
        let allocate_info = vk::CommandBufferAllocateInfo::default()
            .command_pool(**pool)
            .level(vk::CommandBufferLevel::PRIMARY)
            .command_buffer_count(1);

        let buffer = unsafe { pool.device.allocate_command_buffers(&allocate_info)?[0] };

        Ok(Self { pool, buffer })
    }

    pub(crate) fn begin(&self) -> Result<(), VulkanDecoderError> {
        unsafe {
            self.device().begin_command_buffer(
                self.buffer,
                &vk::CommandBufferBeginInfo::default()
                    .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT),
            )?
        };
        Ok(())
    }

    pub(crate) fn end(&self) -> Result<(), VulkanDecoderError> {
        unsafe { self.device().end_command_buffer(self.buffer)? };

        Ok(())
    }

    fn device(&self) -> &Device {
        &self.pool.device
    }
}

impl std::ops::Deref for CommandBuffer {
    type Target = vk::CommandBuffer;

    fn deref(&self) -> &Self::Target {
        &self.buffer
    }
}

impl Drop for CommandBuffer {
    fn drop(&mut self) {
        unsafe {
            self.pool
                .device
                .free_command_buffers(**self.pool, &[self.buffer])
        };
    }
}