use crate::ash::extensions::khr::{Surface, Swapchain};
use crate::ash::prelude::VkResult;
use crate::ash::version::{DeviceV1_0, EntryV1_0, InstanceV1_0};
use crate::ash::{vk, Device as VkDevice, Entry, Instance as VkInstance, InstanceError};
use crate::vk_mem::{
Allocation, AllocationCreateInfo, AllocationInfo, Allocator as VkAllocator, AllocatorCreateInfo,
};
use crate::winit::window::Window;
use std::cell::RefCell;
use std::collections::HashMap;
use std::ops::Deref;
use std::rc::Rc;
#[derive(Clone)]
pub struct Allocator {
pub inner: Rc<RcAllocator>,
}
impl Allocator {
pub fn new(
instance: &Instance,
physical_device: vk::PhysicalDevice,
device: &Device,
) -> vk_mem::error::Result<Self> {
use ::ash::version::{EntryV1_0, InstanceV1_0};
use ::ash::vk::Handle as __Handle;
use ::ash::Entry;
use vk::Handle;
let entry = Entry::new().unwrap();
let instance = unsafe {
::ash::Instance::load(
entry.static_fn(),
::ash::vk::Instance::from_raw(instance.handle().as_raw()),
)
};
let physical_device = ::ash::vk::PhysicalDevice::from_raw(physical_device.as_raw());
let vkdevice = unsafe {
::ash::Device::load(
instance.fp_v1_0(),
::ash::vk::Device::from_raw(device.handle().as_raw()),
)
};
Ok(Self {
inner: Rc::new(RcAllocator {
inner: RefCell::new(VkAllocator::new(&AllocatorCreateInfo {
instance,
physical_device,
device: vkdevice,
..Default::default()
})?),
device: device.clone(),
}),
})
}
}
impl Deref for Allocator {
type Target = RcAllocator;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcAllocator {
pub inner: RefCell<VkAllocator>,
pub device: Device,
}
impl Deref for RcAllocator {
type Target = RefCell<VkAllocator>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcAllocator {
fn drop(&mut self) {
self.borrow_mut().destroy();
}
}
#[derive(Clone, Debug)]
pub struct Buffer {
pub inner: Rc<RcBuffer>,
}
impl Buffer {
pub fn new(
allocator: &Allocator,
create_info: &vk::BufferCreateInfo,
allocation_create_info: &AllocationCreateInfo,
) -> VkResult<Self> {
let (inner, allocation, _) = allocator
.borrow_mut()
.create_buffer(
&unsafe {
*(create_info as *const crate::ash::vk::BufferCreateInfo
as *const ash::vk::BufferCreateInfo)
},
&allocation_create_info,
)
.map_err(|e| {
if let vk_mem::ErrorKind::Vulkan(e) = e.kind() {
crate::ash::vk::Result::from_raw(e.as_raw())
} else {
crate::ash::vk::Result::from_raw(-1)
}
})?;
let inner = {
use crate::ash::vk::Handle;
use ash::vk::Handle as __Handle;
crate::ash::vk::Buffer::from_raw(inner.as_raw())
};
Ok(Self {
inner: Rc::new(RcBuffer {
inner,
allocator: allocator.clone(),
allocation,
}),
})
}
pub fn flush(&self, offset: usize, size: usize) -> vk_mem::error::Result<()> {
let mut allocatior_mut = self.allocator.inner.inner.borrow_mut();
let max_size = allocatior_mut
.get_allocation_info(&self.allocation)
.unwrap()
.get_size()
- offset;
allocatior_mut.flush_allocation(
&self.allocation,
offset,
std::num::NonZeroUsize::new(size)
.unwrap_or_else(|| {
std::num::NonZeroUsize::new(max_size).expect("Bad size or offset")
})
.get(),
)
}
}
impl Deref for Buffer {
type Target = RcBuffer;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcBuffer {
pub inner: vk::Buffer,
pub allocator: Allocator,
pub allocation: Allocation,
}
impl std::fmt::Debug for RcBuffer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.inner)
}
}
impl Deref for RcBuffer {
type Target = vk::Buffer;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcBuffer {
fn drop(&mut self) {
let inner = {
use crate::ash::vk::Handle;
use ash::vk::Handle as __Handle;
ash::vk::Buffer::from_raw(self.as_raw())
};
self.allocator
.borrow_mut()
.destroy_buffer(inner, &self.allocation)
.unwrap();
}
}
#[derive(Clone)]
pub struct CommandBuffer {
pub inner: Rc<RcCommandBuffer>,
}
impl CommandBuffer {
pub fn new(
command_pool: &CommandPool,
create_info: vk::CommandBufferAllocateInfoBuilder,
) -> VkResult<Self> {
let create_info = create_info
.command_pool(***command_pool)
.command_buffer_count(1);
Ok(Self {
inner: Rc::new(RcCommandBuffer {
inner: unsafe { command_pool.device.allocate_command_buffers(&create_info) }?[0],
command_pool: command_pool.clone(),
}),
})
}
}
impl Deref for CommandBuffer {
type Target = RcCommandBuffer;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcCommandBuffer {
pub inner: vk::CommandBuffer,
pub command_pool: CommandPool,
}
impl Deref for RcCommandBuffer {
type Target = vk::CommandBuffer;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcCommandBuffer {
fn drop(&mut self) {
unsafe {
self.command_pool
.device
.free_command_buffers(**self.command_pool, std::slice::from_ref(&**self));
};
}
}
#[derive(Clone)]
pub struct CommandPool {
pub inner: Rc<RcCommandPool>,
}
impl CommandPool {
pub fn new(device: &Device, create_info: &vk::CommandPoolCreateInfo) -> VkResult<Self> {
Ok(Self {
inner: Rc::new(RcCommandPool {
inner: unsafe { device.create_command_pool(&create_info, None) }?,
device: device.clone(),
}),
})
}
}
impl Deref for CommandPool {
type Target = RcCommandPool;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcCommandPool {
pub inner: vk::CommandPool,
pub device: Device,
}
impl Deref for RcCommandPool {
type Target = vk::CommandPool;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcCommandPool {
fn drop(&mut self) {
unsafe {
self.device.destroy_command_pool(**self, None);
};
}
}
#[derive(Clone)]
pub struct DescriptorPool {
pub inner: Rc<RcDescriptorPool>,
}
impl DescriptorPool {
pub fn new(device: &Device, create_info: &vk::DescriptorPoolCreateInfo) -> VkResult<Self> {
Ok(Self {
inner: Rc::new(RcDescriptorPool {
inner: unsafe { device.create_descriptor_pool(&create_info, None) }?,
device: device.clone(),
}),
})
}
}
impl Deref for DescriptorPool {
type Target = RcDescriptorPool;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcDescriptorPool {
pub inner: vk::DescriptorPool,
pub device: Device,
}
impl Deref for RcDescriptorPool {
type Target = vk::DescriptorPool;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcDescriptorPool {
fn drop(&mut self) {
unsafe {
self.device.destroy_descriptor_pool(**self, None);
};
}
}
#[derive(Clone)]
pub struct DescriptorSet {
pub inner: Rc<RcDescriptorSet>,
pub descriptor_counts: Vec<(u32, u32)>,
}
#[derive(Clone)]
pub enum DescriptorSetContents {
Sampler(Sampler),
CombinedImageSampler(Sampler, ImageView),
SampledImage(ImageView),
StorageImage(ImageView),
UniformTexelBuffer(Buffer),
StorageTexelBuffer(Buffer),
UniformBuffer(Buffer),
StorageBuffer(Buffer),
UniformBufferDynamic(Buffer),
StorageBufferDynamic(Buffer),
InputAttachment,
}
impl DescriptorSet {
pub fn new(
descriptor_pool: &DescriptorPool,
descriptor_set_layouts: &[DescriptorSetLayout],
create_info: vk::DescriptorSetAllocateInfoBuilder,
) -> VkResult<Vec<Self>> {
let layouts = descriptor_set_layouts
.iter()
.map(|l| ***l)
.collect::<Vec<_>>();
let create_info = create_info
.descriptor_pool(***descriptor_pool)
.set_layouts(&layouts[..]);
let descriptor_sets = unsafe {
descriptor_pool
.device
.allocate_descriptor_sets(&create_info)
}?;
Ok(descriptor_sets
.into_iter()
.zip(
descriptor_set_layouts
.to_vec()
.into_iter()
.map(|l| l.descriptor_counts),
)
.map(|ret| {
let contents: RefCell<Vec<Option<DescriptorSetContents>>> = RefCell::default();
contents
.borrow_mut()
.resize_with(ret.1.last().unwrap().1 as _, Default::default);
Self {
inner: Rc::new(RcDescriptorSet {
inner: ret.0,
descriptor_pool: descriptor_pool.clone(),
descriptor_set_layouts: descriptor_set_layouts.to_vec(),
contents,
}),
descriptor_counts: ret.1,
}
})
.collect())
}
pub fn write_image(
&self,
contents: &DescriptorSetContents,
image_info: vk::DescriptorImageInfoBuilder,
write_descriptor_set: vk::WriteDescriptorSetBuilder,
) {
use DescriptorSetContents::*;
let image_info = match contents {
CombinedImageSampler(sampler, image_view) => image_info
.sampler(***sampler)
.image_view(***image_view)
.build(),
_ => panic!("Fix me 007"),
};
let write_descriptor_set = write_descriptor_set
.descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
.image_info(std::slice::from_ref(&image_info))
.dst_set(***self);
let mut index: usize = 0;
self.descriptor_counts
.iter()
.find(|t| {
let ret = t.0 >= write_descriptor_set.dst_binding;
if !ret {
index = t.1 as _;
};
ret
})
.unwrap();
self.contents.borrow_mut()[index] = Some(contents.clone());
unsafe {
self.descriptor_pool
.device
.update_descriptor_sets(std::slice::from_ref(&write_descriptor_set.build()), &[])
};
}
}
impl Deref for DescriptorSet {
type Target = RcDescriptorSet;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcDescriptorSet {
pub inner: vk::DescriptorSet,
pub descriptor_pool: DescriptorPool,
pub descriptor_set_layouts: Vec<DescriptorSetLayout>,
pub contents: RefCell<Vec<Option<DescriptorSetContents>>>,
}
impl Deref for RcDescriptorSet {
type Target = vk::DescriptorSet;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcDescriptorSet {
fn drop(&mut self) {
unsafe {
self.descriptor_pool
.device
.free_descriptor_sets(**self.descriptor_pool, std::slice::from_ref(&*self));
};
}
}
#[derive(Clone)]
pub struct DescriptorSetLayout {
pub inner: Rc<RcDescriptorSetLayout>,
pub descriptor_counts: Vec<(u32, u32)>,
}
impl DescriptorSetLayout {
pub fn new(
device: &Device,
bindings: &[vk::DescriptorSetLayoutBinding],
create_info: vk::DescriptorSetLayoutCreateInfoBuilder,
) -> VkResult<Self> {
let create_info = create_info.bindings(bindings);
let mut bindings = bindings.to_vec();
bindings.sort_by_key(|l| l.binding);
let mut sum: u32 = 0;
Ok(Self {
inner: Rc::new(RcDescriptorSetLayout {
inner: unsafe { device.create_descriptor_set_layout(&create_info, None) }?,
device: device.clone(),
}),
descriptor_counts: bindings
.into_iter()
.map(move |l| {
sum = sum + l.descriptor_count;
(l.binding, sum)
})
.collect(),
})
}
}
impl Deref for DescriptorSetLayout {
type Target = RcDescriptorSetLayout;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcDescriptorSetLayout {
pub inner: vk::DescriptorSetLayout,
pub device: Device,
}
impl Deref for RcDescriptorSetLayout {
type Target = vk::DescriptorSetLayout;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcDescriptorSetLayout {
fn drop(&mut self) {
unsafe {
self.device.destroy_descriptor_set_layout(**self, None);
};
}
}
#[derive(Clone)]
pub struct Device {
pub inner: Rc<RcDevice>,
}
impl Device {
pub fn new(
instance: &Instance,
physical_device: vk::PhysicalDevice,
create_info: &vk::DeviceCreateInfo,
) -> Result<Self, vk::Result> {
Ok(Self {
inner: Rc::new(RcDevice {
inner: unsafe { instance.create_device(physical_device, create_info, None) }?,
instance: instance.clone(),
}),
})
}
}
impl Deref for Device {
type Target = RcDevice;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcDevice {
pub inner: VkDevice,
pub instance: Instance,
}
impl Deref for RcDevice {
type Target = VkDevice;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcDevice {
fn drop(&mut self) {
unsafe {
self.inner.destroy_device(None);
};
}
}
#[derive(Clone)]
pub struct Fence {
pub inner: Rc<RcFence>,
}
impl Fence {
pub fn new(device: &Device, create_info: &vk::FenceCreateInfo) -> VkResult<Self> {
Ok(Self {
inner: Rc::new(RcFence {
inner: unsafe { device.create_fence(&create_info, None) }?,
device: device.clone(),
}),
})
}
}
impl Deref for Fence {
type Target = RcFence;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcFence {
pub inner: vk::Fence,
pub device: Device,
}
impl Deref for RcFence {
type Target = vk::Fence;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcFence {
fn drop(&mut self) {
unsafe {
self.device.inner.inner.destroy_fence(**self, None);
};
}
}
#[derive(Clone)]
pub struct Framebuffer {
pub inner: Rc<RcFramebuffer>,
}
impl Framebuffer {
pub fn new(
render_pass: &RenderPass,
create_info: vk::FramebufferCreateInfoBuilder,
) -> VkResult<Self> {
let create_info = create_info.render_pass(***render_pass);
Ok(Self {
inner: Rc::new(RcFramebuffer {
inner: unsafe { render_pass.device.create_framebuffer(&create_info, None) }?,
render_pass: render_pass.clone(),
}),
})
}
}
impl Deref for Framebuffer {
type Target = RcFramebuffer;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcFramebuffer {
pub inner: vk::Framebuffer,
pub render_pass: RenderPass,
}
impl Deref for RcFramebuffer {
type Target = vk::Framebuffer;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcFramebuffer {
fn drop(&mut self) {
unsafe {
self.render_pass.device.destroy_framebuffer(**self, None);
};
}
}
#[derive(Clone)]
pub struct Image {
pub inner: Rc<RcImage>,
}
#[derive(Clone)]
pub enum RcImageDepends {
Allocator {
allocator: Rc<RcAllocator>,
allocation: Allocation,
allocation_info: AllocationInfo,
},
SwapchainKHR(Rc<RcSwapchainKHR>),
}
impl Image {
pub fn new(
allocator: &Allocator,
create_info: &vk::ImageCreateInfo,
allocation_create_info: &AllocationCreateInfo,
) -> VkResult<Self> {
let (inner, allocation, allocation_info) = allocator
.borrow_mut()
.create_image(
&unsafe {
*(create_info as *const crate::ash::vk::ImageCreateInfo
as *const ash::vk::ImageCreateInfo)
},
&allocation_create_info,
)
.map_err(|e| {
if let vk_mem::ErrorKind::Vulkan(e) = e.kind() {
crate::ash::vk::Result::from_raw(e.as_raw())
} else {
crate::ash::vk::Result::from_raw(-1)
}
})?;
let inner = {
use crate::ash::vk::Handle;
use ash::vk::Handle as __Handle;
crate::ash::vk::Image::from_raw(inner.as_raw())
};
Ok(Self {
inner: Rc::new(RcImage {
inner,
depends: RcImageDepends::Allocator {
allocator: allocator.inner.clone(),
allocation,
allocation_info,
},
}),
})
}
}
impl Deref for Image {
type Target = RcImage;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcImage {
pub inner: vk::Image,
pub depends: RcImageDepends,
}
impl RcImage {
fn get_device(&self) -> Device {
match &self.depends {
RcImageDepends::Allocator { allocator, .. } => allocator.device.clone(),
RcImageDepends::SwapchainKHR(swapchain) => swapchain.device.clone(),
}
.clone()
}
}
impl Deref for RcImage {
type Target = vk::Image;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcImage {
fn drop(&mut self) {
match &self.depends {
RcImageDepends::Allocator {
allocator,
allocation,
..
} => {
let inner = {
use crate::ash::vk::Handle;
use ash::vk::Handle as __Handle;
ash::vk::Image::from_raw(self.as_raw())
};
allocator
.borrow_mut()
.destroy_image(inner, &allocation)
.unwrap();
}
RcImageDepends::SwapchainKHR(_) => {
}
}
}
}
#[derive(Clone)]
pub struct ImageView {
pub inner: Rc<RcImageView>,
}
impl ImageView {
pub fn new(image: &Image, create_info: vk::ImageViewCreateInfoBuilder) -> VkResult<Self> {
let create_info = create_info.image(***image);
Ok(Self {
inner: Rc::new(RcImageView {
inner: unsafe { image.get_device().create_image_view(&create_info, None) }?,
image: image.clone(),
}),
})
}
}
impl Deref for ImageView {
type Target = RcImageView;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcImageView {
pub inner: vk::ImageView,
pub image: Image,
}
impl Deref for RcImageView {
type Target = vk::ImageView;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcImageView {
fn drop(&mut self) {
let device = self.image.get_device();
unsafe {
device.destroy_image_view(**self, None);
};
}
}
#[derive(Clone)]
pub struct Instance {
pub inner: Rc<RcInstance>,
pub entry: Entry,
}
impl Instance {
pub fn new_simple(create_info: &vk::InstanceCreateInfo) -> Result<Self, InstanceError> {
let entry = Entry::new().unwrap();
Self::new(&entry, create_info)
}
pub fn new(entry: &Entry, create_info: &vk::InstanceCreateInfo) -> Result<Self, InstanceError> {
Ok(Self {
inner: Rc::new(RcInstance {
inner: unsafe { entry.create_instance(create_info, None) }?,
}),
entry: entry.clone(),
})
}
}
impl Deref for Instance {
type Target = RcInstance;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcInstance {
pub inner: VkInstance,
}
impl Deref for RcInstance {
type Target = VkInstance;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcInstance {
fn drop(&mut self) {
unsafe { self.destroy_instance(None) };
}
}
#[derive(Clone)]
pub struct Pipeline {
pub inner: Rc<RcPipeline>,
}
impl Pipeline {
pub fn new(
pipeline_layout: &PipelineLayout,
render_pass: &RenderPass,
shaders: &HashMap<vk::ShaderStageFlags, ShaderModule>,
shader_stages_create_info: &[vk::PipelineShaderStageCreateInfo],
create_info: vk::GraphicsPipelineCreateInfoBuilder,
) -> Result<Pipeline, (Vec<vk::Pipeline>, vk::Result)> {
let shader_stages_create_info = shader_stages_create_info
.to_vec()
.into_iter()
.map(|mut create_info| {
create_info.module = ***shaders.get(&create_info.stage).unwrap();
create_info
})
.collect::<Vec<_>>();
let create_info = create_info
.stages(&shader_stages_create_info)
.layout(***pipeline_layout)
.render_pass(***render_pass)
.build();
Ok(Self {
inner: Rc::new(RcPipeline {
inner: unsafe {
render_pass.device.create_graphics_pipelines(
vk::PipelineCache::null(),
std::slice::from_ref(&create_info),
None,
)
}?[0],
pipeline_layout: pipeline_layout.clone(),
render_pass: render_pass.clone(),
shaders: shaders.clone(),
}),
})
}
}
impl Deref for Pipeline {
type Target = RcPipeline;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcPipeline {
pub inner: vk::Pipeline,
pub pipeline_layout: PipelineLayout,
pub render_pass: RenderPass,
pub shaders: HashMap<vk::ShaderStageFlags, ShaderModule>,
}
impl Deref for RcPipeline {
type Target = vk::Pipeline;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcPipeline {
fn drop(&mut self) {
unsafe {
self.render_pass.device.destroy_pipeline(**self, None);
};
}
}
#[derive(Clone)]
pub struct PipelineLayout {
pub inner: Rc<RcPipelineLayout>,
}
impl PipelineLayout {
pub fn new(
device: &Device,
descriptor_set_layouts: &[DescriptorSetLayout],
create_info: vk::PipelineLayoutCreateInfoBuilder,
) -> VkResult<Self> {
let layouts = descriptor_set_layouts
.iter()
.map(|l| ***l)
.collect::<Vec<_>>();
let create_info = create_info.set_layouts(&layouts[..]);
Ok(Self {
inner: Rc::new(RcPipelineLayout {
inner: unsafe { device.create_pipeline_layout(&create_info, None) }?,
device: device.clone(),
descriptor_set_layouts: descriptor_set_layouts.to_vec(),
}),
})
}
}
impl Deref for PipelineLayout {
type Target = RcPipelineLayout;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcPipelineLayout {
pub inner: vk::PipelineLayout,
pub device: Device,
pub descriptor_set_layouts: Vec<DescriptorSetLayout>,
}
impl Deref for RcPipelineLayout {
type Target = vk::PipelineLayout;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcPipelineLayout {
fn drop(&mut self) {
unsafe {
self.device.destroy_pipeline_layout(**self, None);
};
}
}
#[derive(Clone)]
pub struct Queue {
pub inner: Rc<RcQueue>,
}
impl Queue {
pub fn new(device: &Device, queue_family_index: u32, queue_index: u32) -> Self {
Self {
inner: Rc::new(RcQueue {
device: device.clone(),
inner: unsafe { device.get_device_queue(queue_family_index, queue_index) },
}),
}
}
}
impl Deref for Queue {
type Target = RcQueue;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcQueue {
pub inner: vk::Queue,
pub device: Device,
}
impl Deref for RcQueue {
type Target = vk::Queue;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RenderPass {
pub inner: Rc<RcRenderPass>,
}
impl RenderPass {
pub fn new(device: &Device, create_info: &vk::RenderPassCreateInfo) -> VkResult<Self> {
Ok(Self {
inner: Rc::new(RcRenderPass {
inner: unsafe { device.create_render_pass(&create_info, None) }?,
device: device.clone(),
}),
})
}
}
impl Deref for RenderPass {
type Target = RcRenderPass;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcRenderPass {
pub inner: vk::RenderPass,
pub device: Device,
}
impl Deref for RcRenderPass {
type Target = vk::RenderPass;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcRenderPass {
fn drop(&mut self) {
unsafe {
self.device.destroy_render_pass(**self, None);
};
}
}
#[derive(Clone)]
pub struct Sampler {
pub inner: Rc<RcSampler>,
}
impl Sampler {
pub fn new(device: &Device, create_info: &vk::SamplerCreateInfo) -> VkResult<Self> {
Ok(Self {
inner: Rc::new(RcSampler {
inner: unsafe { device.create_sampler(&create_info, None) }?,
device: device.clone(),
}),
})
}
}
impl Deref for Sampler {
type Target = RcSampler;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcSampler {
pub inner: vk::Sampler,
pub device: Device,
}
impl Deref for RcSampler {
type Target = vk::Sampler;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcSampler {
fn drop(&mut self) {
unsafe {
self.device.inner.inner.destroy_sampler(**self, None);
};
}
}
#[derive(Clone)]
pub struct Semaphore {
pub inner: Rc<RcSemaphore>,
}
impl Semaphore {
pub fn new(device: &Device, create_info: &vk::SemaphoreCreateInfo) -> VkResult<Self> {
Ok(Self {
inner: Rc::new(RcSemaphore {
inner: unsafe { device.create_semaphore(&create_info, None) }?,
device: device.clone(),
}),
})
}
}
impl Deref for Semaphore {
type Target = RcSemaphore;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcSemaphore {
pub inner: vk::Semaphore,
pub device: Device,
}
impl Deref for RcSemaphore {
type Target = vk::Semaphore;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcSemaphore {
fn drop(&mut self) {
unsafe {
self.device.destroy_semaphore(**self, None);
};
}
}
#[derive(Clone)]
pub struct ShaderModule {
pub inner: Rc<RcShaderModule>,
}
impl ShaderModule {
pub fn new(device: &Device, create_info: &vk::ShaderModuleCreateInfo) -> VkResult<Self> {
Ok(Self {
inner: Rc::new(RcShaderModule {
inner: unsafe { device.create_shader_module(&create_info, None) }?,
device: device.clone(),
}),
})
}
pub fn new_simple(device: &Device, bin: &[u8]) -> VkResult<Self> {
let create_info = vk::ShaderModuleCreateInfo::builder().code(unsafe {
std::slice::from_raw_parts(
bin.as_ptr() as *const u32,
bin.len() * std::mem::size_of::<u8>() / std::mem::size_of::<u32>(),
)
});
Self::new(&device, &create_info)
}
}
impl Deref for ShaderModule {
type Target = RcShaderModule;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcShaderModule {
pub inner: vk::ShaderModule,
pub device: Device,
}
impl Deref for RcShaderModule {
type Target = vk::ShaderModule;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcShaderModule {
fn drop(&mut self) {
unsafe {
self.device.destroy_shader_module(**self, None);
};
}
}
#[derive(Clone)]
pub struct SurfaceKHR {
pub inner: Rc<RcSurfaceKHR>,
pub physical_device: vk::PhysicalDevice,
pub queue_family_index: u32,
pub surface_format: vk::SurfaceFormatKHR,
}
impl SurfaceKHR {
pub fn new(instance: &Instance, window: &Window, flags: vk::Flags) -> VkResult<Self> {
use crate::WindowExt;
let surface = window.create_surface(&instance.entry, instance, flags, None)?;
let physical_devices = unsafe { instance.enumerate_physical_devices() }?;
let surface_loader = Surface::new(&instance.entry, &***instance);
let (physical_device, queue_family_index) = physical_devices
.iter()
.map(|pdevice| {
unsafe { instance.get_physical_device_queue_family_properties(*pdevice) }
.iter()
.enumerate()
.filter_map(|(index, ref info)| {
let supports_graphic_and_surface = info
.queue_flags
.contains(crate::ash::vk::QueueFlags::GRAPHICS)
&& unsafe {
surface_loader.get_physical_device_surface_support(
*pdevice,
index as u32,
surface,
)
}
.unwrap();
match supports_graphic_and_surface {
true => Some((*pdevice, index)),
_ => None,
}
})
.nth(0)
})
.filter_map(|v| v)
.nth(0)
.expect("Couldn't find suitable device.");
let queue_family_index = queue_family_index as u32;
let surface_formats = unsafe {
surface_loader.get_physical_device_surface_formats(physical_device, surface)
}?;
let surface_format = surface_formats
.iter()
.map(|sfmt| match sfmt.format {
crate::ash::vk::Format::UNDEFINED => crate::ash::vk::SurfaceFormatKHR {
format: crate::ash::vk::Format::B8G8R8_UNORM,
color_space: sfmt.color_space,
},
_ => sfmt.clone(),
})
.nth(0)
.expect("Unable to find suitable surface format.");
Ok(Self {
inner: Rc::new(RcSurfaceKHR {
inner: surface,
instance: instance.clone(),
surface_loader,
}),
physical_device,
queue_family_index,
surface_format,
})
}
}
impl Deref for SurfaceKHR {
type Target = RcSurfaceKHR;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcSurfaceKHR {
pub inner: vk::SurfaceKHR,
pub instance: Instance,
pub surface_loader: crate::ash::extensions::khr::Surface,
}
impl Deref for RcSurfaceKHR {
type Target = vk::SurfaceKHR;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcSurfaceKHR {
fn drop(&mut self) {
unsafe {
self.surface_loader.destroy_surface(**self, None);
};
}
}
#[derive(Clone)]
pub struct SwapchainKHR {
pub inner: Rc<RcSwapchainKHR>,
pub present_images: Vec<Image>,
}
impl SwapchainKHR {
pub fn new(
device: &Device,
surface: &SurfaceKHR,
create_info: vk::SwapchainCreateInfoKHRBuilder,
) -> VkResult<Self> {
let swapchain_loader = Swapchain::new(&**device.instance, &***device);
let create_info = create_info.surface(***surface);
let swapchain = unsafe { swapchain_loader.create_swapchain(&create_info, None) }?;
let inner = Rc::new(RcSwapchainKHR {
inner: swapchain,
device: device.clone(),
surface: surface.clone(),
swapchain_loader: swapchain_loader.clone(),
});
let present_images = unsafe { swapchain_loader.get_swapchain_images(swapchain) }?
.iter()
.map(|image| Image {
inner: Rc::new(RcImage {
inner: *image,
depends: RcImageDepends::SwapchainKHR(inner.clone()),
}),
})
.collect();
Ok(Self {
inner,
present_images,
})
}
}
impl Deref for SwapchainKHR {
type Target = RcSwapchainKHR;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Clone)]
pub struct RcSwapchainKHR {
pub inner: vk::SwapchainKHR,
pub device: Device,
pub surface: SurfaceKHR,
pub swapchain_loader: Swapchain,
}
impl Deref for RcSwapchainKHR {
type Target = vk::SwapchainKHR;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl Drop for RcSwapchainKHR {
fn drop(&mut self) {
unsafe {
self.swapchain_loader.destroy_swapchain(**self, None);
};
}
}