Browse Source

make everything use Rc

master
Alison Watson 1 year ago
parent
commit
2875887764
17 changed files with 275 additions and 267 deletions
  1. +48
    -49
      source/main.rs
  2. +1
    -1
      source/render.rs
  3. +32
    -29
      source/render/cmd.rs
  4. +18
    -18
      source/render/device.rs
  5. +11
    -10
      source/render/fence.rs
  6. +21
    -18
      source/render/framebuffer.rs
  7. +11
    -28
      source/render/image.rs
  8. +16
    -14
      source/render/imageview.rs
  9. +3
    -3
      source/render/instance.rs
  10. +27
    -26
      source/render/pipeline.rs
  11. +8
    -7
      source/render/pipelinelayout.rs
  12. +13
    -12
      source/render/queue.rs
  13. +9
    -8
      source/render/renderpass.rs
  14. +11
    -10
      source/render/semaphore.rs
  15. +9
    -8
      source/render/shader.rs
  16. +10
    -9
      source/render/surface.rs
  17. +27
    -17
      source/render/swapchain.rs

+ 48
- 49
source/main.rs View File

@@ -10,15 +10,14 @@ use crate::{
util::{log, meta},
};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

struct Pipelines<'shd, 'lay, 'ren, 'dev, 'ins> {
main: Pipeline<'shd, 'lay, 'ren, 'dev, 'ins>,
struct Pipelines {
main: Rc<Pipeline>,
}

impl<'shd, 'lay, 'ren, 'dev, 'ins> Pipelines<'shd, 'lay, 'ren, 'dev, 'ins> {
fn create_from(
mut pipelines: Vec<Pipeline<'shd, 'lay, 'ren, 'dev, 'ins>>
) -> Self {
impl Pipelines {
fn create_from(mut pipelines: Vec<Rc<Pipeline>>) -> Self {
let main = pipelines.pop().unwrap();
Self { main }
}
@@ -29,16 +28,16 @@ const MAIN_VERT: &[u8] =
const MAIN_FRAG: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/main.frag.o"));

fn draw_frame<'fen, 'dev, 'ins>(
device: &'dev Device,
swapchain: &Swapchain,
image_available_s: &Semaphore,
render_finished_s: &Semaphore,
frame_f: &'fen Fence<'dev, 'ins>,
image_f: &mut [Option<&'fen Fence<'dev, 'ins>>],
cmd_buffers: &[CommandBuffer],
queue_graphics: &Queue,
queue_surface: &Queue,
fn draw_frame<'a>(
device: &Device,
swapchain: &Swapchain,
image_avail_s: &Semaphore,
render_fini_s: &Semaphore,
frame_f: &'a Fence,
image_f: &mut [Option<&'a Fence>],
cmd_buffers: &[Rc<CommandBuffer>],
queue_graphics: &Queue,
queue_surface: &Queue,
) -> Result<(), vk::Result> {
let fences = [**frame_f];

@@ -52,7 +51,7 @@ fn draw_frame<'fen, 'dev, 'ins>(
.acquire_next_image(
**swapchain,
u64::max_value(),
**image_available_s,
**image_avail_s,
vk::Fence::null(),
)?
.0 as usize
@@ -67,12 +66,12 @@ fn draw_frame<'fen, 'dev, 'ins>(

image_f[image_index] = Some(frame_f);

let wait_semaphores = [**image_available_s];
let wait_semaphores = [**image_avail_s];
let wait_stages = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];

let signal_semaphores = [**render_finished_s];
let signal_semaphores = [**render_fini_s];

let submit_cmd_buffers = [*cmd_buffers[image_index]];
let submit_cmd_buffers = [**cmd_buffers[image_index]];

let submit_info = [
vk::SubmitInfo {
@@ -124,72 +123,72 @@ fn fallback_main(
let entry = ash::Entry::new()?;
let instance = Instance::create(&conf.render, entry, &window)?;

let phys_device = PhysicalDevice::get(&instance, &conf.render)?;
let phys_device = PhysicalDevice::get(instance.clone(), &conf.render)?;

let surface = Surface::create(&instance, &window)?;
let surface = Surface::create(instance.clone(), &window)?;

let qf_info = QueueFamilyInfo::collect(&instance, &surface, &phys_device)?;

let device = Device::create(&instance, &phys_device, &qf_info)?;
let device = Device::create(instance.clone(), &phys_device, &qf_info)?;

let image_available_s = Semaphore::create_all(&device, concur_frames)?;
let render_finished_s = Semaphore::create_all(&device, concur_frames)?;
let image_avail_s = Semaphore::create_all(device.clone(), concur_frames)?;
let render_fini_s = Semaphore::create_all(device.clone(), concur_frames)?;

let frame_f = Fence::create_all(&device, concur_frames)?;
let frame_f = Fence::create_all(device.clone(), concur_frames)?;

let layout = PipelineLayout::create(&device)?;
let cmd_pool = CommandPool::create(&device, qf_info.gfx_index)?;
let layout = PipelineLayout::create(device.clone())?;
let cmd_pool = CommandPool::create(device.clone(), qf_info.gfx_index)?;

let spir_vert = Spir::read(MAIN_VERT);
let spir_frag = Spir::read(MAIN_FRAG);

let shader_vert = ShaderModule::create(&device, &spir_vert)?;
let shader_frag = ShaderModule::create(&device, &spir_frag)?;
let shader_vert = ShaderModule::create(device.clone(), &spir_vert)?;
let shader_frag = ShaderModule::create(device.clone(), &spir_frag)?;

let queue_graphics = Queue::get(&device, qf_info.gfx_index);
let queue_surface = Queue::get(&device, qf_info.srf_index);
let queue_graphics = Queue::get(device.clone(), qf_info.gfx_index);
let queue_surface = Queue::get(device.clone(), qf_info.srf_index);

let swapchain = Swapchain::create(
&instance,
&device,
device.clone(),
&phys_device,
&surface,
surface.clone(),
&conf.render,
&qf_info,
)?;

let images = swapchain.get_images()?;
let images = Swapchain::get_images(swapchain.clone())?;

let mut image_f = vec![None; images.len()];

let image_views =
ImageView::create_all(&device, &images, swapchain.format)?;
ImageView::create_all(device.clone(), &images, swapchain.format)?;

let render_pass = RenderPass::create(&device, swapchain.format)?;
let render_pass = RenderPass::create(device.clone(), swapchain.format)?;

let pipelines = Pipeline::create_all(
&device,
device.clone(),
&[
PipelineCreateInfo::info_basic(
&shader_vert,
&shader_frag,
&layout,
&render_pass,
shader_vert.clone(),
shader_frag.clone(),
layout.clone(),
render_pass.clone(),
swapchain.extent,
),
],
)?;

let pipelines = Pipelines::create_from(pipelines);
let pipelines = Pipelines::create_from(pipelines.clone());

let framebuffers = Framebuffer::create_all(
&device,
&render_pass,
device.clone(),
render_pass.clone(),
&image_views,
swapchain.extent
)?;

let cmd_buffers = cmd_pool.allocate_and_bind_buffers(
let cmd_buffers = CommandPool::allocate_and_bind_buffers(
cmd_pool.clone(),
&framebuffers,
&render_pass,
&pipelines.main,
@@ -209,8 +208,8 @@ fn fallback_main(
let frame = draw_frame(
&device,
&swapchain,
&image_available_s[cur_c_frame],
&render_finished_s[cur_c_frame],
&image_avail_s[cur_c_frame],
&render_fini_s[cur_c_frame],
&frame_f[cur_c_frame],
&mut image_f,
&cmd_buffers,


+ 1
- 1
source/render.rs View File

@@ -23,7 +23,7 @@ pub use self::{
device::{ErrDeviceCreate, ErrPhysicalDeviceGet, Device, PhysicalDevice},
fence::Fence,
framebuffer::Framebuffer,
image::Image,
image::OwnedImage,
imageview::ImageView,
instance::{ErrInstanceCreate, Instance},
pipeline::{Pipeline, PipelineCreateInfo},


+ 32
- 29
source/render/cmd.rs View File

@@ -1,24 +1,25 @@
use crate::render::{Device, Framebuffer, Pipeline, RenderPass};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct CommandPool<'dev, 'ins> {
pub struct CommandPool {
handle: vk::CommandPool,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
}

pub struct CommandBuffer<'cpl, 'dev, 'ins> {
pub struct CommandBuffer {
handle: vk::CommandBuffer,

pub device: &'dev Device<'ins>,
pub pool: &'cpl CommandPool<'dev, 'ins>,
pub device: Rc<Device>,
pub pool: Rc<CommandPool>,
}

impl<'dev, 'ins> CommandPool<'dev, 'ins> {
impl CommandPool {
pub fn create(
device: &'dev Device<'ins>,
device: Rc<Device>,
index: u32,
) -> Result<Self, vk::Result> {
) -> Result<Rc<Self>, vk::Result> {
let handle = unsafe {
device.create_command_pool(
&vk::CommandPoolCreateInfo {
@@ -28,29 +29,31 @@ impl<'dev, 'ins> CommandPool<'dev, 'ins> {
None,
)?
};
Ok(Self { handle, device })
Ok(Rc::new(Self { handle, device }))
}

pub fn allocate_buffers(
&self,
framebuffers: &[Framebuffer],
) -> Result<Vec<CommandBuffer>, vk::Result> {
this: Rc<Self>,
framebuffers: &[Rc<Framebuffer>],
) -> Result<Vec<Rc<CommandBuffer>>, vk::Result> {
let alloc_info = vk::CommandBufferAllocateInfo {
command_pool: **self,
command_pool: **this,
level: vk::CommandBufferLevel::PRIMARY,
command_buffer_count: framebuffers.len() as u32,
..Default::default()
};

let bufs = unsafe {
self
this
.device
.allocate_command_buffers(&alloc_info)?
.iter()
.map(|&handle| CommandBuffer {
handle,
device: self.device,
pool: self,
.map(|&handle| {
Rc::new(CommandBuffer {
handle,
device: this.device.clone(),
pool: this.clone(),
})
})
.collect()
};
@@ -59,13 +62,13 @@ impl<'dev, 'ins> CommandPool<'dev, 'ins> {
}

pub fn allocate_and_bind_buffers(
&self,
framebuffers: &[Framebuffer],
this: Rc<Self>,
framebuffers: &[Rc<Framebuffer>],
render_pass: &RenderPass,
pipeline: &Pipeline,
extent: vk::Extent2D,
) -> Result<Vec<CommandBuffer>, vk::Result> {
let cmd_buffers = self.allocate_buffers(framebuffers)?;
) -> Result<Vec<Rc<CommandBuffer>>, vk::Result> {
let cmd_buffers = Self::allocate_buffers(this, framebuffers)?;

CommandBuffer::bind_all(
&cmd_buffers,
@@ -79,7 +82,7 @@ impl<'dev, 'ins> CommandPool<'dev, 'ins> {
}
}

impl CommandBuffer<'_, '_, '_> {
impl CommandBuffer {
pub fn bind(
&self,
framebuffer: &Framebuffer,
@@ -137,8 +140,8 @@ impl CommandBuffer<'_, '_, '_> {
}

pub fn bind_all(
cmd_buffers: &[Self],
framebuffers: &[Framebuffer],
cmd_buffers: &[Rc<Self>],
framebuffers: &[Rc<Framebuffer>],
render_pass: &RenderPass,
pipeline: &Pipeline,
extent: vk::Extent2D,
@@ -153,7 +156,7 @@ impl CommandBuffer<'_, '_, '_> {
}
}

impl Drop for CommandPool<'_, '_> {
impl Drop for CommandPool {
fn drop(&mut self) {
unsafe {
self.device.destroy_command_pool(self.handle, None);
@@ -161,7 +164,7 @@ impl Drop for CommandPool<'_, '_> {
}
}

impl Drop for CommandBuffer<'_, '_, '_> {
impl Drop for CommandBuffer {
fn drop(&mut self) {
unsafe {
self.device.free_command_buffers(**self.pool, &[self.handle]);
@@ -169,14 +172,14 @@ impl Drop for CommandBuffer<'_, '_, '_> {
}
}

impl std::ops::Deref for CommandPool<'_, '_> {
impl std::ops::Deref for CommandPool {
type Target = vk::CommandPool;
fn deref(&self) -> &Self::Target {
&self.handle
}
}

impl std::ops::Deref for CommandBuffer<'_, '_, '_> {
impl std::ops::Deref for CommandBuffer {
type Target = vk::CommandBuffer;
fn deref(&self) -> &Self::Target {
&self.handle


+ 18
- 18
source/render/device.rs View File

@@ -6,19 +6,19 @@ use ash::{
version::{DeviceV1_0, InstanceV1_0},
vk,
};
use std::os::raw::c_char;
use std::{os::raw::c_char, rc::Rc};

pub struct Device<'ins> {
pub struct Device {
handle: ash::Device,

pub instance: &'ins Instance,
pub instance: Rc<Instance>,
pub swapchain_ext: khr::Swapchain,
}

pub struct PhysicalDevice<'ins> {
pub struct PhysicalDevice {
handle: vk::PhysicalDevice,

pub instance: &'ins Instance,
pub instance: Rc<Instance>,
}

#[derive(Debug)]
@@ -53,12 +53,12 @@ fn enable_device_extensions(
})
}

impl<'ins> Device<'ins> {
impl Device {
pub fn create(
instance: &'ins Instance,
phys_device: &PhysicalDevice<'ins>,
instance: Rc<Instance>,
phys_device: &PhysicalDevice,
qf_info: &QueueFamilyInfo,
) -> Result<Self, ErrDeviceCreate> {
) -> Result<Rc<Self>, ErrDeviceCreate> {
const QUEUE_PRIORITY: [f32; 1] = [1.0];

let queue_create_info = [
@@ -84,7 +84,7 @@ impl<'ins> Device<'ins> {
queue_create_info_count: queue_create_info.len() as u32,
p_queue_create_infos: queue_create_info.as_ptr(),
p_enabled_features: &device_features,
..enable_device_extensions(instance, phys_device, &extensions)?
..enable_device_extensions(&instance, phys_device, &extensions)?
};

let handle =
@@ -92,27 +92,27 @@ impl<'ins> Device<'ins> {

let swapchain_ext = khr::Swapchain::new(&**instance, &handle);

Ok(Self { handle, instance, swapchain_ext })
Ok(Rc::new(Self { handle, instance, swapchain_ext }))
}
}

impl<'ins> PhysicalDevice<'ins> {
impl PhysicalDevice {
pub fn get(
instance: &'ins Instance,
instance: Rc<Instance>,
conf: &Conf
) -> Result<Self, ErrPhysicalDeviceGet> {
) -> Result<Rc<Self>, ErrPhysicalDeviceGet> {
let devs = unsafe { instance.enumerate_physical_devices()? };

if conf.device < devs.len() {
let handle = devs[conf.device];
Ok(Self { handle, instance })
Ok(Rc::new(Self { handle, instance }))
} else {
Err(ErrPhysicalDeviceGet::NoDevice)
}
}
}

impl Drop for Device<'_> {
impl Drop for Device {
fn drop(&mut self) {
unsafe {
self.handle.destroy_device(None);
@@ -120,14 +120,14 @@ impl Drop for Device<'_> {
}
}

impl std::ops::Deref for Device<'_> {
impl std::ops::Deref for Device {
type Target = ash::Device;
fn deref(&self) -> &Self::Target {
&self.handle
}
}

impl std::ops::Deref for PhysicalDevice<'_> {
impl std::ops::Deref for PhysicalDevice {
type Target = vk::PhysicalDevice;
fn deref(&self) -> &Self::Target {
&self.handle


+ 11
- 10
source/render/fence.rs View File

@@ -1,31 +1,32 @@
use crate::render::Device;
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct Fence<'dev, 'ins> {
pub struct Fence {
handle: vk::Fence,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
}

impl<'dev, 'ins> Fence<'dev, 'ins> {
pub fn create(device: &'dev Device<'ins>) -> Result<Self, vk::Result> {
impl Fence {
pub fn create(device: Rc<Device>) -> Result<Rc<Self>, vk::Result> {
let create_info = vk::FenceCreateInfo {
flags: vk::FenceCreateFlags::SIGNALED,
..Default::default()
};
let handle = unsafe { device.create_fence(&create_info, None)? };
Ok(Self { handle, device })
Ok(Rc::new(Self { handle, device }))
}

pub fn create_all(
device: &'dev Device<'ins>,
device: Rc<Device>,
num: usize,
) -> Result<Vec<Self>, vk::Result> {
(0..num).map(|_| Self::create(&device)).collect()
) -> Result<Vec<Rc<Self>>, vk::Result> {
(0..num).map(|_| Self::create(device.clone())).collect()
}
}

impl Drop for Fence<'_, '_> {
impl Drop for Fence {
fn drop(&mut self) {
unsafe {
self.device.destroy_fence(self.handle, None);
@@ -33,7 +34,7 @@ impl Drop for Fence<'_, '_> {
}
}

impl std::ops::Deref for Fence<'_, '_> {
impl std::ops::Deref for Fence {
type Target = vk::Fence;
fn deref(&self) -> &Self::Target {
&self.handle


+ 21
- 18
source/render/framebuffer.rs View File

@@ -1,19 +1,22 @@
use crate::render::{Device, ImageView, RenderPass};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct Framebuffer<'dev, 'ins> {
pub struct Framebuffer {
handle: vk::Framebuffer,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
pub render_pass: Rc<RenderPass>,
pub image_view: Rc<ImageView>,
}

impl<'dev, 'ins> Framebuffer<'dev, 'ins> {
impl Framebuffer {
pub fn create(
device: &'dev Device<'ins>,
render_pass: &RenderPass,
image_view: &ImageView,
device: Rc<Device>,
render_pass: Rc<RenderPass>,
image_view: Rc<ImageView>,
image_extent: vk::Extent2D,
) -> Result<Self, vk::Result> {
) -> Result<Rc<Self>, vk::Result> {
let attachments = [**image_view];

let create_info = vk::FramebufferCreateInfo {
@@ -27,30 +30,30 @@ impl<'dev, 'ins> Framebuffer<'dev, 'ins> {
};

let handle = unsafe { device.create_framebuffer(&create_info, None)? };
Ok(Self { handle, device })
Ok(Rc::new(Self { handle, device, render_pass, image_view }))
}

pub fn create_all(
device: &'dev Device<'ins>,
render_pass: &RenderPass,
image_views: &[ImageView],
device: Rc<Device>,
render_pass: Rc<RenderPass>,
image_views: &[Rc<ImageView>],
extent: vk::Extent2D,
) -> Result<Vec<Self>, vk::Result> {
) -> Result<Vec<Rc<Self>>, vk::Result> {
image_views
.iter()
.map(|image_view| {
Self::create(
device,
render_pass,
image_view,
extent,
device.clone(),
render_pass.clone(),
image_view.clone(),
extent
)
})
.collect()
}
}

impl Drop for Framebuffer<'_, '_> {
impl Drop for Framebuffer {
fn drop(&mut self) {
unsafe {
self.device.destroy_framebuffer(self.handle, None);
@@ -58,7 +61,7 @@ impl Drop for Framebuffer<'_, '_> {
}
}

impl std::ops::Deref for Framebuffer<'_, '_> {
impl std::ops::Deref for Framebuffer {
type Target = vk::Framebuffer;
fn deref(&self) -> &Self::Target {
&self.handle


+ 11
- 28
source/render/image.rs View File

@@ -1,40 +1,23 @@
use crate::render::{Device, Swapchain};
use ash::{version::DeviceV1_0, vk};
use crate::render::Swapchain;
use ash::vk;
use std::rc::Rc;

pub enum ImageOwner<'swpa, 'deva, 'insa, 'devb, 'insb> {
Swapchain(&'swpa Swapchain<'deva, 'insa>),
Device(&'devb Device<'insb>),
}

pub struct Image<'swpa, 'deva, 'insa, 'devb, 'insb> {
pub struct OwnedImage {
handle: vk::Image,

pub owner: ImageOwner<'swpa, 'deva, 'insa, 'devb, 'insb>,
pub swapchain: Rc<Swapchain>,
}

impl<'swp, 'dev, 'ins> Image<'swp, 'dev, 'ins, '_, '_> {
impl OwnedImage {
pub fn own(
owner: &'swp Swapchain<'dev, 'ins>,
handle: vk::Image,
) -> Self {
Self { handle, owner: ImageOwner::Swapchain(owner) }
}
}

impl Drop for Image<'_, '_, '_, '_, '_> {
fn drop(&mut self) {
match self.owner {
ImageOwner::Swapchain(owner) => {
unsafe { owner.device.destroy_image(self.handle, None); }
},
ImageOwner::Device(owner) => {
unsafe { owner.destroy_image(self.handle, None); }
},
}
swapchain: Rc<Swapchain>,
handle: vk::Image,
) -> Rc<Self> {
Rc::new(Self { handle, swapchain })
}
}

impl std::ops::Deref for Image<'_, '_, '_, '_, '_> {
impl std::ops::Deref for OwnedImage {
type Target = vk::Image;
fn deref(&self) -> &Self::Target {
&self.handle


+ 16
- 14
source/render/imageview.rs View File

@@ -1,18 +1,20 @@
use crate::render::{Device, Image};
use crate::render::{Device, OwnedImage};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct ImageView<'dev, 'ins> {
pub struct ImageView {
handle: vk::ImageView,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
pub image: Rc<OwnedImage>,
}

impl<'dev, 'ins> ImageView<'dev, 'ins> {
impl ImageView {
pub fn create(
device: &'dev Device<'ins>,
image: &Image,
device: Rc<Device>,
image: Rc<OwnedImage>,
format: vk::Format,
) -> Result<Self, vk::Result> {
) -> Result<Rc<Self>, vk::Result> {
let create_info = vk::ImageViewCreateInfo {
format,
image: **image,
@@ -33,22 +35,22 @@ impl<'dev, 'ins> ImageView<'dev, 'ins> {
..Default::default()
};
let handle = unsafe { device.create_image_view(&create_info, None)? };
Ok(Self { handle, device })
Ok(Rc::new(Self { handle, device, image }))
}

pub fn create_all(
device: &'dev Device<'ins>,
images: &[Image],
device: Rc<Device>,
images: &[Rc<OwnedImage>],
format: vk::Format,
) -> Result<Vec<Self>, vk::Result> {
) -> Result<Vec<Rc<Self>>, vk::Result> {
images
.iter()
.map(|image| Self::create(device, image, format))
.map(|image| Self::create(device.clone(), image.clone(), format))
.collect()
}
}

impl Drop for ImageView<'_, '_> {
impl Drop for ImageView {
fn drop(&mut self) {
unsafe {
self.device.destroy_image_view(self.handle, None);
@@ -56,7 +58,7 @@ impl Drop for ImageView<'_, '_> {
}
}

impl std::ops::Deref for ImageView<'_, '_> {
impl std::ops::Deref for ImageView {
type Target = vk::ImageView;
fn deref(&self) -> &Self::Target {
&self.handle


+ 3
- 3
source/render/instance.rs View File

@@ -9,7 +9,7 @@ use ash::{
version::{EntryV1_0, InstanceV1_0},
vk, vk_make_version,
};
use std::os::raw::c_char;
use std::{os::raw::c_char, rc::Rc};

pub struct Instance {
#[allow(dead_code)]
@@ -48,7 +48,7 @@ impl Instance {
conf: &Conf,
entry: ash::Entry,
window: &crate::hal::Window,
) -> Result<Self, ErrInstanceCreate> {
) -> Result<Rc<Self>, ErrInstanceCreate> {
let exts = window.vulkan_instance_extensions()?;

let app_info = vk::ApplicationInfo {
@@ -72,7 +72,7 @@ impl Instance {

let handle = unsafe { entry.create_instance(&create_info, None)? };
let surface_ext = khr::Surface::new(&entry, &handle);
Ok(Self { entry, handle, surface_ext })
Ok(Rc::new(Self { entry, handle, surface_ext }))
}
}



+ 27
- 26
source/render/pipeline.rs View File

@@ -1,10 +1,11 @@
use crate::render::{Device, PipelineLayout, RenderPass, ShaderModule};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct PipelineCreateInfo<'shd, 'lay, 'ren, 'dev, 'ins> {
shader_data: Vec<&'shd ShaderModule<'dev, 'ins>>,
layout: &'lay PipelineLayout<'dev, 'ins>,
render_pass: &'ren RenderPass<'dev, 'ins>,
pub struct PipelineCreateInfo {
shader_data: Vec<Rc<ShaderModule>>,
layout: Rc<PipelineLayout>,
render_pass: Rc<RenderPass>,
shader_stages: Vec<vk::PipelineShaderStageCreateInfo>,
vertex_input_state: vk::PipelineVertexInputStateCreateInfo,
input_assembly_state: vk::PipelineInputAssemblyStateCreateInfo,
@@ -15,27 +16,27 @@ pub struct PipelineCreateInfo<'shd, 'lay, 'ren, 'dev, 'ins> {
color_blend_attachments: Vec<vk::PipelineColorBlendAttachmentState>,
}

pub struct Pipeline<'shd, 'lay, 'ren, 'dev, 'ins> {
pub struct Pipeline {
handle: vk::Pipeline,

pub device: &'dev Device<'ins>,
pub shader_data: Vec<&'shd ShaderModule<'dev, 'ins>>,
pub layout: &'lay PipelineLayout<'dev, 'ins>,
pub render_pass: &'ren RenderPass<'dev, 'ins>,
pub device: Rc<Device>,
pub shader_data: Vec<Rc<ShaderModule>>,
pub layout: Rc<PipelineLayout>,
pub render_pass: Rc<RenderPass>,
}

impl<'shd, 'lay, 'ren, 'dev, 'ins> PipelineCreateInfo<'shd, 'lay, 'ren, 'dev, 'ins> {
impl PipelineCreateInfo {
pub fn info_basic(
shader_vert: &'shd ShaderModule<'dev, 'ins>,
shader_frag: &'shd ShaderModule<'dev, 'ins>,
layout: &'lay PipelineLayout<'dev, 'ins>,
render_pass: &'ren RenderPass<'dev, 'ins>,
shader_vert: Rc<ShaderModule>,
shader_frag: Rc<ShaderModule>,
layout: Rc<PipelineLayout>,
render_pass: Rc<RenderPass>,
extent: vk::Extent2D,
) -> Self {
Self {
layout,
render_pass,
shader_data: vec![shader_vert, shader_frag],
shader_data: vec![shader_vert.clone(), shader_frag.clone()],
shader_stages: vec![
vk::PipelineShaderStageCreateInfo {
stage: vk::ShaderStageFlags::VERTEX,
@@ -92,11 +93,11 @@ impl<'shd, 'lay, 'ren, 'dev, 'ins> PipelineCreateInfo<'shd, 'lay, 'ren, 'dev, 'i
}
}

impl<'shd, 'lay, 'ren, 'dev, 'ins> Pipeline<'shd, 'lay, 'ren, 'dev, 'ins> {
impl Pipeline {
pub fn create_all(
device: &'dev Device<'ins>,
infos: &[PipelineCreateInfo<'shd, 'lay, 'ren, 'dev, 'ins>],
) -> Result<Vec<Self>, vk::Result> {
device: Rc<Device>,
infos: &[PipelineCreateInfo],
) -> Result<Vec<Rc<Self>>, vk::Result> {
let viewport_states =
infos
.iter()
@@ -161,13 +162,13 @@ impl<'shd, 'lay, 'ren, 'dev, 'ins> Pipeline<'shd, 'lay, 'ren, 'dev, 'ins> {
.iter()
.zip(infos.iter())
.map(|(&handle, info)| {
Self {
Rc::new(Self {
handle,
device,
device: device.clone(),
shader_data: info.shader_data.clone(),
layout: info.layout,
render_pass: info.render_pass,
}
layout: info.layout.clone(),
render_pass: info.render_pass.clone(),
})
})
.collect()
};
@@ -176,7 +177,7 @@ impl<'shd, 'lay, 'ren, 'dev, 'ins> Pipeline<'shd, 'lay, 'ren, 'dev, 'ins> {
}
}

impl Drop for Pipeline<'_, '_, '_, '_, '_> {
impl Drop for Pipeline {
fn drop(&mut self) {
unsafe {
self.device.destroy_pipeline(self.handle, None);
@@ -184,7 +185,7 @@ impl Drop for Pipeline<'_, '_, '_, '_, '_> {
}
}

impl std::ops::Deref for Pipeline<'_, '_, '_, '_, '_> {
impl std::ops::Deref for Pipeline {
type Target = vk::Pipeline;
fn deref(&self) -> &Self::Target {
&self.handle


+ 8
- 7
source/render/pipelinelayout.rs View File

@@ -1,23 +1,24 @@
use crate::render::Device;
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct PipelineLayout<'dev, 'ins> {
pub struct PipelineLayout {
handle: vk::PipelineLayout,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
}

impl<'dev, 'ins> PipelineLayout<'dev, 'ins> {
pub fn create(device: &'dev Device<'ins>) -> Result<Self, vk::Result> {
impl PipelineLayout {
pub fn create(device: Rc<Device>) -> Result<Rc<Self>, vk::Result> {
let create_info = vk::PipelineLayoutCreateInfo::default();

let handle =
unsafe { device.create_pipeline_layout(&create_info, None)? };
Ok(Self { handle, device })
Ok(Rc::new(Self { handle, device }))
}
}

impl Drop for PipelineLayout<'_, '_> {
impl Drop for PipelineLayout {
fn drop(&mut self) {
unsafe {
self.device.destroy_pipeline_layout(self.handle, None);
@@ -25,7 +26,7 @@ impl Drop for PipelineLayout<'_, '_> {
}
}

impl std::ops::Deref for PipelineLayout<'_, '_> {
impl std::ops::Deref for PipelineLayout {
type Target = vk::PipelineLayout;
fn deref(&self) -> &Self::Target {
&self.handle


+ 13
- 12
source/render/queue.rs View File

@@ -3,22 +3,23 @@ use ash::{
version::{DeviceV1_0, InstanceV1_0},
vk,
};

#[derive(Debug)]
pub enum ErrQueueFamilyCollect {
NoGfxQueue,
NoSrfQueue,
}
use std::rc::Rc;

pub struct QueueFamilyInfo {
pub gfx_index: u32,
pub srf_index: u32,
}

pub struct Queue<'dev, 'ins> {
pub struct Queue {
handle: vk::Queue,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
}

#[derive(Debug)]
pub enum ErrQueueFamilyCollect {
NoGfxQueue,
NoSrfQueue,
}

impl QueueFamilyInfo {
@@ -61,14 +62,14 @@ impl QueueFamilyInfo {
}
}

impl<'dev, 'ins> Queue<'dev, 'ins> {
pub fn get(device: &'dev Device<'ins>, index: u32) -> Self {
impl Queue {
pub fn get(device: Rc<Device>, index: u32) -> Rc<Self> {
let handle = unsafe { device.get_device_queue(index, 0) };
Self { handle, device }
Rc::new(Self { handle, device })
}
}

impl std::ops::Deref for Queue<'_, '_> {
impl std::ops::Deref for Queue {
type Target = vk::Queue;
fn deref(&self) -> &Self::Target {
&self.handle


+ 9
- 8
source/render/renderpass.rs View File

@@ -1,17 +1,18 @@
use crate::render::Device;
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct RenderPass<'dev, 'ins> {
pub struct RenderPass {
handle: vk::RenderPass,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
}

impl<'dev, 'ins> RenderPass<'dev, 'ins> {
impl RenderPass {
pub fn create(
device: &'dev Device<'ins>,
device: Rc<Device>,
format: vk::Format,
) -> Result<Self, vk::Result> {
) -> Result<Rc<Self>, vk::Result> {
let attachments = [
vk::AttachmentDescription {
format,
@@ -67,11 +68,11 @@ impl<'dev, 'ins> RenderPass<'dev, 'ins> {
};

let handle = unsafe { device.create_render_pass(&create_info, None)? };
Ok(Self { handle, device })
Ok(Rc::new(Self { handle, device }))
}
}

impl Drop for RenderPass<'_, '_> {
impl Drop for RenderPass {
fn drop(&mut self) {
unsafe {
self.device.destroy_render_pass(self.handle, None);
@@ -79,7 +80,7 @@ impl Drop for RenderPass<'_, '_> {
}
}

impl std::ops::Deref for RenderPass<'_, '_> {
impl std::ops::Deref for RenderPass {
type Target = vk::RenderPass;
fn deref(&self) -> &Self::Target {
&self.handle


+ 11
- 10
source/render/semaphore.rs View File

@@ -1,28 +1,29 @@
use crate::render::Device;
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct Semaphore<'dev, 'ins> {
pub struct Semaphore {
handle: vk::Semaphore,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
}

impl<'dev, 'ins> Semaphore<'dev, 'ins> {
pub fn create(device: &'dev Device<'ins>) -> Result<Self, vk::Result> {
impl Semaphore {
pub fn create(device: Rc<Device>) -> Result<Rc<Self>, vk::Result> {
let create_info = vk::SemaphoreCreateInfo::default();
let handle = unsafe { device.create_semaphore(&create_info, None)? };
Ok(Self { handle, device })
Ok(Rc::new(Self { handle, device }))
}

pub fn create_all(
device: &'dev Device<'ins>,
device: Rc<Device>,
num: usize,
) -> Result<Vec<Self>, vk::Result> {
(0..num).map(|_| Self::create(&device)).collect()
) -> Result<Vec<Rc<Self>>, vk::Result> {
(0..num).map(|_| Self::create(device.clone())).collect()
}
}

impl Drop for Semaphore<'_, '_> {
impl Drop for Semaphore {
fn drop(&mut self) {
unsafe {
self.device.destroy_semaphore(self.handle, None);
@@ -30,7 +31,7 @@ impl Drop for Semaphore<'_, '_> {
}
}

impl std::ops::Deref for Semaphore<'_, '_> {
impl std::ops::Deref for Semaphore {
type Target = vk::Semaphore;
fn deref(&self) -> &Self::Target {
&self.handle


+ 9
- 8
source/render/shader.rs View File

@@ -1,17 +1,18 @@
use crate::render::{Device, Spir};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

pub struct ShaderModule<'dev, 'ins> {
pub struct ShaderModule {
handle: vk::ShaderModule,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
}

impl<'dev, 'ins> ShaderModule<'dev, 'ins> {
impl ShaderModule {
pub fn create(
device: &'dev Device<'ins>,
device: Rc<Device>,
spir: &Spir,
) -> Result<Self, vk::Result> {
) -> Result<Rc<Self>, vk::Result> {
let create_info = vk::ShaderModuleCreateInfo {
code_size: spir.size,
p_code: spir.code.as_ptr(),
@@ -19,11 +20,11 @@ impl<'dev, 'ins> ShaderModule<'dev, 'ins> {
};

let handle = unsafe { device.create_shader_module(&create_info, None)? };
Ok(Self { handle, device })
Ok(Rc::new(Self { handle, device }))
}
}

impl Drop for ShaderModule<'_, '_> {
impl Drop for ShaderModule {
fn drop(&mut self) {
unsafe {
self.device.destroy_shader_module(self.handle, None);
@@ -31,7 +32,7 @@ impl Drop for ShaderModule<'_, '_> {
}
}

impl std::ops::Deref for ShaderModule<'_, '_> {
impl std::ops::Deref for ShaderModule {
type Target = vk::ShaderModule;
fn deref(&self) -> &Self::Target {
&self.handle


+ 10
- 9
source/render/surface.rs View File

@@ -1,23 +1,24 @@
use crate::render::Instance;
use ash::vk;
use std::rc::Rc;

pub struct Surface<'ins> {
pub struct Surface {
handle: vk::SurfaceKHR,

pub instance: &'ins Instance,
pub instance: Rc<Instance>,
}

impl<'ins> Surface<'ins> {
impl Surface {
pub fn create(
instance: &'ins Instance,
instance: Rc<Instance>,
window: &crate::hal::Window,
) -> Result<Self, crate::hal::ErrSdl> {
let handle = window.vulkan_create_surface(instance)?;
Ok(Self { handle, instance })
) -> Result<Rc<Self>, crate::hal::ErrSdl> {
let handle = window.vulkan_create_surface(&instance)?;
Ok(Rc::new(Self { handle, instance }))
}
}

impl Drop for Surface<'_> {
impl Drop for Surface {
fn drop(&mut self) {
unsafe {
self.instance.surface_ext.destroy_surface(self.handle, None);
@@ -25,7 +26,7 @@ impl Drop for Surface<'_> {
}
}

impl std::ops::Deref for Surface<'_> {
impl std::ops::Deref for Surface {
type Target = vk::SurfaceKHR;
fn deref(&self) -> &Self::Target {
&self.handle


+ 27
- 17
source/render/swapchain.rs View File

@@ -1,40 +1,42 @@
use crate::render::{
Conf, Device, Image, Instance, PhysicalDevice, QueueFamilyInfo, Surface,
Conf, Device, OwnedImage, PhysicalDevice, QueueFamilyInfo, Surface,
};
use ash::vk;
use std::rc::Rc;

pub struct Swapchain<'dev, 'ins> {
pub struct Swapchain {
handle: vk::SwapchainKHR,

pub device: &'dev Device<'ins>,
pub device: Rc<Device>,
pub surface: Rc<Surface>,

pub format: vk::Format,
pub extent: vk::Extent2D,
}

impl<'dev, 'ins> Swapchain<'dev, 'ins> {
impl Swapchain {
pub fn create(
instance: &Instance,
device: &'dev Device<'ins>,
device: Rc<Device>,
phys_device: &PhysicalDevice,
surface: &Surface,
surface: Rc<Surface>,
conf: &Conf,
qf_info: &QueueFamilyInfo,
) -> Result<Self, vk::Result> {
) -> Result<Rc<Self>, vk::Result> {
let capabilities = unsafe {
instance.surface_ext.get_physical_device_surface_capabilities(
device.instance.surface_ext.get_physical_device_surface_capabilities(
**phys_device,
**surface,
)?
};

let formats = unsafe {
instance
device.instance
.surface_ext
.get_physical_device_surface_formats(**phys_device, **surface)?
};

let modes = unsafe {
instance.surface_ext.get_physical_device_surface_present_modes(
device.instance.surface_ext.get_physical_device_surface_present_modes(
**phys_device,
**surface,
)?
@@ -107,21 +109,29 @@ impl<'dev, 'ins> Swapchain<'dev, 'ins> {
let handle =
unsafe { device.swapchain_ext.create_swapchain(&create_info, None)? };

Ok(Self { handle, device, format: format.format, extent })
Ok(Rc::new(Self {
handle,
device,
surface,
extent,
format: format.format,
}))
}

pub fn get_images(&self) -> Result<Vec<Image>, vk::Result> {
pub fn get_images(
this: Rc<Self>,
) -> Result<Vec<Rc<OwnedImage>>, vk::Result> {
let images = unsafe {
self.device.swapchain_ext.get_swapchain_images(self.handle)?
this.device.swapchain_ext.get_swapchain_images(this.handle)?
};
Ok(images
.iter()
.map(|&image| Image::own(self, image))
.map(|&image| OwnedImage::own(this.clone(), image))
.collect())
}
}

impl Drop for Swapchain<'_, '_> {
impl Drop for Swapchain {
fn drop(&mut self) {
unsafe {
self.device.swapchain_ext.destroy_swapchain(self.handle, None);
@@ -129,7 +139,7 @@ impl Drop for Swapchain<'_, '_> {
}
}

impl std::ops::Deref for Swapchain<'_, '_> {
impl std::ops::Deref for Swapchain {
type Target = vk::SwapchainKHR;
fn deref(&self) -> &Self::Target {
&self.handle


Loading…
Cancel
Save