rotex-vulkan 0.1.1

A Vulkan backend for rotex_core
Documentation
use ash::vk;

use super::buffer::RotexBuffer;
use super::device::Device;
use crate::error::vk_error;
use crate::Error;

pub struct DescriptorSet {
    handle: vk::DescriptorSet,
}

impl DescriptorSet {
    pub fn handle(&self) -> vk::DescriptorSet {
        self.handle
    }

    pub fn write_buffer(
        &self,
        device: &Device,
        binding: u32,
        buffer: &RotexBuffer,
        offset: vk::DeviceSize,
        range: vk::DeviceSize,
        descriptor_type: vk::DescriptorType,
    ) {
        let buffer_info = [vk::DescriptorBufferInfo::default()
            .buffer(buffer.handle())
            .offset(offset)
            .range(range)];

        let write = [vk::WriteDescriptorSet::default()
            .dst_set(self.handle)
            .dst_binding(binding)
            .descriptor_type(descriptor_type)
            .buffer_info(&buffer_info)];

        unsafe {
            device.logical_device().update_descriptor_sets(&write, &[]);
        }
    }

    pub fn write_image_sampler(
        &self,
        device: &Device,
        binding: u32,
        image_view: vk::ImageView,
        sampler: vk::Sampler,
        image_layout: vk::ImageLayout,
    ) {
        let image_info = [vk::DescriptorImageInfo::default()
            .image_layout(image_layout)
            .image_view(image_view)
            .sampler(sampler)];

        let write = [vk::WriteDescriptorSet::default()
            .dst_set(self.handle)
            .dst_binding(binding)
            .descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
            .image_info(&image_info)];

        unsafe {
            device.logical_device().update_descriptor_sets(&write, &[]);
        }
    }
}

pub struct DescriptorPool {
    handle: vk::DescriptorPool,
}

impl DescriptorPool {
    pub fn new(
        device: &Device,
        max_sets: u32,
        pool_sizes: &[vk::DescriptorPoolSize],
    ) -> Result<Self, Error> {
        let create_info = vk::DescriptorPoolCreateInfo::default()
            .max_sets(max_sets)
            .pool_sizes(pool_sizes)
            .flags(vk::DescriptorPoolCreateFlags::FREE_DESCRIPTOR_SET);

        let handle = unsafe {
            device
                .logical_device()
                .create_descriptor_pool(&create_info, None)
        }
        .map_err(vk_error)?;

        Ok(Self { handle })
    }

    pub fn allocate_sets(
        &self,
        device: &Device,
        layouts: &[vk::DescriptorSetLayout],
    ) -> Result<Vec<DescriptorSet>, Error> {
        let alloc_info = vk::DescriptorSetAllocateInfo::default()
            .descriptor_pool(self.handle)
            .set_layouts(layouts);

        let sets = unsafe {
            device
                .logical_device()
                .allocate_descriptor_sets(&alloc_info)
        }
        .map_err(vk_error)?;

        Ok(sets
            .into_iter()
            .map(|handle| DescriptorSet { handle })
            .collect())
    }

    pub fn handle(&self) -> vk::DescriptorPool {
        self.handle
    }

    pub fn free_sets(&self, device: &Device, sets: &[DescriptorSet]) -> Result<(), Error> {
        if sets.is_empty() {
            return Ok(());
        }
        let set_handles = sets.iter().map(|set| set.handle).collect::<Vec<_>>();
        unsafe {
            device
                .logical_device()
                .free_descriptor_sets(self.handle, &set_handles)
        }
        .map_err(vk_error)
    }

    pub fn destroy(&self, device: &Device) {
        unsafe {
            device
                .logical_device()
                .destroy_descriptor_pool(self.handle, None);
        }
    }
}