Browse Source

add uniform handling

master
Alison Watson 4 months ago
parent
commit
6b4ca3bb31
11 changed files with 443 additions and 137 deletions
  1. +11
    -1
      glsl/main.vert
  2. +66
    -19
      source/main.rs
  3. +7
    -1
      source/render.rs
  4. +110
    -79
      source/render/buffer.rs
  5. +47
    -20
      source/render/cmd.rs
  6. +39
    -0
      source/render/descriptorlayout.rs
  7. +115
    -0
      source/render/descriptorpool.rs
  8. +5
    -7
      source/render/pipeline.rs
  9. +18
    -8
      source/render/pipelinelayout.rs
  10. +23
    -0
      source/render/uniforms.rs
  11. +2
    -2
      source/render/vertex.rs

+ 11
- 1
glsl/main.vert View File

@@ -3,8 +3,18 @@ layout(location = 1) in vec3 in_color;

layout(location = 0) out vec3 frag_color;

layout(binding = 0) uniform Uniforms {
mat4 object;
mat4 camera;
mat4 projection;
} uniforms;

void main() {
gl_Position = vec4(in_position, 0.0, 1.0);
gl_Position =
uniforms.projection *
uniforms.camera *
uniforms.object *
vec4(in_position, 0.0, 1.0);
frag_color = in_color;
}



+ 66
- 19
source/main.rs View File

@@ -12,7 +12,7 @@ use crate::{
};

use ash::{version::DeviceV1_0, vk};
use cgmath::{Vector2, Vector3};
use cgmath::{prelude::*, Matrix4, Point3, Rad, Vector2, Vector3};
use std::rc::Rc;

struct Pipelines {
@@ -20,9 +20,10 @@ struct Pipelines {
}

struct SwapchainData<'a> {
swapchain: Rc<Swapchain>,
image_f: Vec<Option<&'a Fence>>,
cmd_pool: Rc<CommandPool>,
swapchain: Rc<Swapchain>,
image_f: Vec<Option<&'a Fence>>,
descriptor_pool: Rc<DescriptorPool>,
cmd_pool: Rc<CommandPool>,
}

impl Pipelines {
@@ -45,7 +46,7 @@ impl SwapchainData<'_> {
queue_graphics: &Queue,
queue_surface: &Queue,
conf: &render::Conf,
) -> Result<Self, vk::Result> {
) -> Result<Self, ErrBufferCreate> {
let swapchain = Swapchain::create(
device.clone(),
&phys_device,
@@ -70,7 +71,7 @@ impl SwapchainData<'_> {
PipelineCreateInfo::info_basic(
shader_vert,
shader_frag,
layout,
layout.clone(),
render_pass.clone(),
swapchain.extent,
),
@@ -86,35 +87,53 @@ impl SwapchainData<'_> {
swapchain.extent,
)?;

let uniform_buffers =
framebuffers
.iter()
.map(|_| Buffer::create_uniform(device.clone(), phys_device))
.collect::<Result<_, _>>()?;

let descriptor_pool = DescriptorPool::create(
device.clone(),
uniform_buffers,
layout.descriptor.clone(),
)?;

let cmd_pool = CommandPool::create_graphics(
device,
queue_graphics.index,
&framebuffers,
render_pass,
swapchain.extent,
|cmd| {
|cmd, framebuffer_num| {
cmd.bind_pipeline(pipelines.main.clone());
cmd.bind_vertex_buffer(vertex_buffer.clone());
cmd.bind_index_buffer(index_buffer.clone());
cmd.bind_descriptor_pool(
descriptor_pool.clone(),
layout.clone(),
framebuffer_num,
);
cmd.draw(INDICES.len());
},
)?;

Ok(Self { swapchain, image_f, cmd_pool })
Ok(Self { swapchain, image_f, descriptor_pool, cmd_pool })
}
}

fn draw_frame<'a>(
sc_data: &mut SwapchainData<'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: &[vk::CommandBuffer],
queue_graphics: &Queue,
queue_surface: &Queue,
time_ms: u128,
) -> Result<(), vk::Result> {
let cmd_buffers = sc_data.cmd_pool.buf_handles();

let fences = [**frame_f];

unsafe {
@@ -125,7 +144,7 @@ fn draw_frame<'a>(
device
.swapchain_ext
.acquire_next_image(
**swapchain,
**sc_data.swapchain,
u64::max_value(),
**image_avail_s,
vk::Fence::null(),
@@ -133,14 +152,40 @@ fn draw_frame<'a>(
.0 as usize
};

if let Some(fence) = image_f[image_index] {
if let Some(fence) = sc_data.image_f[image_index] {
let fences = [**fence];
unsafe {
device.wait_for_fences(&fences, true, u64::max_value())?;
}
}

image_f[image_index] = Some(frame_f);
sc_data.image_f[image_index] = Some(frame_f);

let uniforms = Uniforms {
object:
Matrix4::from_angle_z(Rad::full_turn() * time_ms as f32 / 10_000.0),
camera: Matrix4::look_at(
Point3::new(2.0, 2.0, 2.0),
Point3::new(0.0, 0.0, 0.0),
Vector3::new(0.0, 0.0, 1.0),
),
projection:
cgmath::perspective(
Rad::turn_div_4(),
sc_data.swapchain.extent.width as f32 /
sc_data.swapchain.extent.height as f32,
0.01,
100_000.0,
) *
Matrix4::new(
1.0, 0.0, 0.0, 0.0,
0.0, -1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
),
};

sc_data.descriptor_pool.buffers[image_index].write_data(&[uniforms])?;

let wait_semaphores = [**image_avail_s];
let wait_stages = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];
@@ -167,7 +212,7 @@ fn draw_frame<'a>(
device.queue_submit(**queue_graphics, &submit_info, **frame_f)?;
}

let swapchains = [**swapchain];
let swapchains = [**sc_data.swapchain];
let image_indices = [image_index as u32];

let present_info = vk::PresentInfoKHR {
@@ -198,6 +243,8 @@ fn fallback_main(
conf: &conf::Conf,
lg: &log::Log,
) -> Result<(), Box<dyn std::error::Error>> {
let start_time = std::time::Instant::now();

/*
let main = {
use std::io::prelude::*;
@@ -257,7 +304,8 @@ fn fallback_main(

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

let layout = PipelineLayout::create(device.clone())?;
let desc_layout = DescriptorSetLayout::create(device.clone())?;
let layout = PipelineLayout::create(desc_layout)?;

let spir_vert = Spir::read(MAIN_VERT);
let spir_frag = Spir::read(MAIN_FRAG);
@@ -289,15 +337,14 @@ fn fallback_main(
}

let frame = draw_frame(
&mut sc_data,
&device,
&sc_data.swapchain,
&image_avail_s[cur_c_frame],
&render_fini_s[cur_c_frame],
&frame_f[cur_c_frame],
&mut sc_data.image_f,
sc_data.cmd_pool.buf_handles(),
&queue_graphics,
&queue_surface,
start_time.elapsed().as_millis(),
);

match frame {


+ 7
- 1
source/render.rs View File

@@ -1,6 +1,8 @@
mod buffer;
mod cmd;
mod conf;
mod descriptorlayout;
mod descriptorpool;
mod device;
mod fence;
mod framebuffer;
@@ -17,12 +19,15 @@ mod shader;
mod spir;
mod surface;
mod swapchain;
mod uniforms;
mod vertex;

pub use self::{
buffer::Buffer,
buffer::{Buffer, ErrBufferCreate},
cmd::{CommandBuffer, CommandPool},
conf::{Conf, PresentMode},
descriptorlayout::DescriptorSetLayout,
descriptorpool::{DescriptorPool, DescriptorSet},
device::{Device, ErrDeviceCreate, ErrPhysicalDeviceGet, PhysicalDevice},
fence::Fence,
framebuffer::Framebuffer,
@@ -40,6 +45,7 @@ pub use self::{
surface::Surface,
swapchain::Swapchain,
vertex::Vertex,
uniforms::Uniforms,
};

// EOF

+ 110
- 79
source/render/buffer.rs View File

@@ -1,4 +1,6 @@
use crate::render::{CommandPool, Device, PhysicalDevice, Queue, Vertex};
use crate::render::{
CommandPool, Device, PhysicalDevice, Queue, Uniforms, Vertex,
};
use ash::{
version::{DeviceV1_0, InstanceV1_0},
vk,
@@ -78,127 +80,156 @@ unsafe fn create_buffer(
Ok((handle, memory))
}

unsafe fn copy_buffer(
src_handle: vk::Buffer,
dst_handle: vk::Buffer,
size: vk::DeviceSize,
device: Rc<Device>,
xfer_queue: &Queue,
) -> Result<(), vk::Result> {
let pool = CommandPool::create_transfer(
device.clone(),
xfer_queue.index,
|cmd| cmd.transfer(src_handle, dst_handle, size),
)?;

let submit_buffers = pool.buf_handles();

let submit_info = [
vk::SubmitInfo {
command_buffer_count: submit_buffers.len() as u32,
p_command_buffers: submit_buffers.as_ptr(),
..Default::default()
}
];

device.queue_submit(
**xfer_queue,
&submit_info,
vk::Fence::null(),
)?;

device.queue_wait_idle(**xfer_queue)
/// Returns the size of `data` as a `vk::DeviceSize`.
fn dev_size_of<T>(data: &[T]) -> vk::DeviceSize {
(std::mem::size_of::<T>() * data.len()) as vk::DeviceSize
}

impl Buffer {
/// Creates a vertex buffer.
pub fn create_vertex(
device: Rc<Device>,
phys_device: &PhysicalDevice,
vertices: &[Vertex],
xfer_queue: &Queue,
queue: &Queue,
) -> Result<Rc<Self>, ErrBufferCreate> {
let size = std::mem::size_of::<Vertex>() * vertices.len();
let size = size as vk::DeviceSize;
let size = dev_size_of(vertices);

let (handle, memory) = unsafe {
let (src_handle, src_memory) = create_buffer(
unsafe {
let (handle, memory) = create_buffer(
&device,
phys_device,
size,
vk::BufferUsageFlags::TRANSFER_SRC,
vk::MemoryPropertyFlags::HOST_VISIBLE |
vk::MemoryPropertyFlags::HOST_COHERENT,
vk::BufferUsageFlags::TRANSFER_DST |
vk::BufferUsageFlags::VERTEX_BUFFER,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
)?;

let mem_flg = vk::MemoryMapFlags::empty();
let mem_map = device.map_memory(src_memory, 0, size, mem_flg)?;
(mem_map as *mut Vertex).copy_from(vertices.as_ptr(), vertices.len());
device.unmap_memory(src_memory);
let dst = Self { handle, memory, device };

let (dst_handle, dst_memory) = create_buffer(
dst.xfer_data(queue, phys_device, vertices)?;

Ok(Rc::new(dst))
}
}

/// Creates an index buffer.
pub fn create_index(
device: Rc<Device>,
phys_device: &PhysicalDevice,
indices: &[u16],
queue: &Queue,
) -> Result<Rc<Self>, ErrBufferCreate> {
let size = dev_size_of(indices);

unsafe {
let (handle, memory) = create_buffer(
&device,
phys_device,
size,
vk::BufferUsageFlags::TRANSFER_DST |
vk::BufferUsageFlags::VERTEX_BUFFER,
vk::BufferUsageFlags::INDEX_BUFFER,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
)?;

copy_buffer(src_handle, dst_handle, size, device.clone(), xfer_queue)?;

// TODO: express with Drop
device.free_memory(src_memory, None);
device.destroy_buffer(src_handle, None);
let dst = Self { handle, memory, device };

(dst_handle, dst_memory)
};
dst.xfer_data(queue, phys_device, indices)?;

Ok(Rc::new(Self { handle, device, memory }))
Ok(Rc::new(dst))
}
}

pub fn create_index(
/// Creates a uniform buffer.
pub fn create_uniform(
device: Rc<Device>,
phys_device: &PhysicalDevice,
indices: &[u16],
xfer_queue: &Queue,
) -> Result<Rc<Self>, ErrBufferCreate> {
let size = std::mem::size_of::<u16>() * indices.len();
let size = size as vk::DeviceSize;

let (handle, memory) = unsafe {
let (src_handle, src_memory) = create_buffer(
create_buffer(
&device,
phys_device,
size,
vk::BufferUsageFlags::TRANSFER_SRC,
std::mem::size_of::<Uniforms>() as vk::DeviceSize,
vk::BufferUsageFlags::UNIFORM_BUFFER,
vk::MemoryPropertyFlags::HOST_VISIBLE |
vk::MemoryPropertyFlags::HOST_COHERENT,
)?;
)?
};

let mem_flg = vk::MemoryMapFlags::empty();
let mem_map = device.map_memory(src_memory, 0, size, mem_flg)?;
(mem_map as *mut u16).copy_from(indices.as_ptr(), indices.len());
device.unmap_memory(src_memory);
Ok(Rc::new(Self { handle, memory, device }))
}

let (dst_handle, dst_memory) = create_buffer(
&device,
/// Copies the contents of `src` to `self` using a transient pool.
unsafe fn copy_buffer(
&self,
src: &Self,
size: vk::DeviceSize,
queue: &Queue,
) -> Result<(), vk::Result> {
let pool = CommandPool::create_transfer(
self.device.clone(),
queue.index,
|cmd| cmd.transfer(src.handle, self.handle, size),
)?;

let submit_buffers = pool.buf_handles();

let submit_info = [
vk::SubmitInfo {
command_buffer_count: submit_buffers.len() as u32,
p_command_buffers: submit_buffers.as_ptr(),
..Default::default()
}
];

self.device.queue_submit(**queue, &submit_info, vk::Fence::null())?;

self.device.queue_wait_idle(**queue)
}

/// Transfers `data` from the client to the server.
pub fn xfer_data<T>(
&self,
queue: &Queue,
phys_device: &PhysicalDevice,
data: &[T],
) -> Result<(), ErrBufferCreate> {
let size = dev_size_of(data);

unsafe {
let (handle, memory) = create_buffer(
&self.device,
phys_device,
size,
vk::BufferUsageFlags::TRANSFER_DST |
vk::BufferUsageFlags::INDEX_BUFFER,
vk::MemoryPropertyFlags::DEVICE_LOCAL,
vk::BufferUsageFlags::TRANSFER_SRC,
vk::MemoryPropertyFlags::HOST_VISIBLE |
vk::MemoryPropertyFlags::HOST_COHERENT,
)?;

copy_buffer(src_handle, dst_handle, size, device.clone(), xfer_queue)?;
let src = Self { handle, memory, device: self.device.clone() };

// TODO: express with Drop
device.free_memory(src_memory, None);
device.destroy_buffer(src_handle, None);
src.write_data(data)?;

(dst_handle, dst_memory)
};
self.copy_buffer(&src, size, queue)?;
}

Ok(())
}

/// Writes `data` to `self`.
pub fn write_data<T>(&self, data: &[T]) -> Result<(), vk::Result> {
let size = dev_size_of(data);

unsafe {
let flg = vk::MemoryMapFlags::empty();
let map = self.device.map_memory(self.memory, 0, size, flg)?;

(map as *mut T).copy_from(data.as_ptr(), data.len());

self.device.unmap_memory(self.memory);
}

Ok(Rc::new(Self { handle, device, memory }))
Ok(())
}
}



+ 47
- 20
source/render/cmd.rs View File

@@ -1,4 +1,7 @@
use crate::render::{Buffer, Device, Framebuffer, Pipeline, RenderPass};
use crate::render::{
Buffer, DescriptorPool, Device, Framebuffer, Pipeline, PipelineLayout,
RenderPass,
};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

@@ -16,12 +19,13 @@ pub struct CommandPool {
pub struct CommandBuffer {
handle: vk::CommandBuffer,

device: Rc<Device>,
render_pass: Option<Rc<RenderPass>>,
framebuffer: Option<Rc<Framebuffer>>,
pipeline: Option<Rc<Pipeline>>,
vertex_buffer: Option<Rc<Buffer>>,
index_buffer: Option<Rc<Buffer>>,
device: Rc<Device>,
render_pass: Option<Rc<RenderPass>>,
framebuffer: Option<Rc<Framebuffer>>,
pipeline: Option<Rc<Pipeline>>,
vertex_buffer: Option<Rc<Buffer>>,
index_buffer: Option<Rc<Buffer>>,
descriptor_pool: Option<Rc<DescriptorPool>>,
}

impl CommandPool {
@@ -31,7 +35,7 @@ impl CommandPool {
framebuffers: &[Rc<Framebuffer>],
render_pass: Rc<RenderPass>,
extent: vk::Extent2D,
f: impl Fn(&mut CommandBuffer) + Copy,
f: impl Fn(&mut CommandBuffer, usize) + Copy,
) -> Result<Rc<Self>, vk::Result> {
let (handle, buffers) = unsafe {
Self::create_inner(
@@ -46,14 +50,15 @@ impl CommandPool {
buffers
.iter()
.zip(framebuffers.iter())
.map(|(&handle, framebuffer)| {
.enumerate()
.map(|(framebuffer_num, (&handle, framebuffer))| {
Ok(CommandBuffer::create_graphics(
handle,
device.clone(),
render_pass.clone(),
framebuffer.clone(),
extent,
f,
|cmd| f(cmd, framebuffer_num),
)?)
})
.collect::<Result<Vec<_>, vk::Result>>()?;
@@ -166,6 +171,26 @@ impl CommandBuffer {
}
}

pub fn bind_descriptor_pool(
&mut self,
descriptor_pool: Rc<DescriptorPool>,
pipeline_layout: Rc<PipelineLayout>,
which: usize,
) {
unsafe {
self.device.cmd_bind_descriptor_sets(
self.handle,
vk::PipelineBindPoint::GRAPHICS,
**pipeline_layout,
0,
&[*descriptor_pool.sets[which]],
&[],
);

self.descriptor_pool = Some(descriptor_pool);
}
}

pub fn draw(&self, num: usize) {
unsafe {
self.device.cmd_draw_indexed(self.handle, num as u32, 1, 0, 0, 0);
@@ -221,11 +246,12 @@ impl CommandBuffer {
let mut this = Self {
handle,
device,
render_pass: Some(render_pass),
framebuffer: Some(framebuffer),
pipeline: None,
vertex_buffer: None,
index_buffer: None,
render_pass: Some(render_pass),
framebuffer: Some(framebuffer),
pipeline: None,
vertex_buffer: None,
index_buffer: None,
descriptor_pool: None,
};

unsafe {
@@ -260,11 +286,12 @@ impl CommandBuffer {
let mut this = Self {
handle,
device,
render_pass: None,
framebuffer: None,
pipeline: None,
vertex_buffer: None,
index_buffer: None,
render_pass: None,
framebuffer: None,
pipeline: None,
vertex_buffer: None,
index_buffer: None,
descriptor_pool: None,
};

unsafe {


+ 39
- 0
source/render/descriptorlayout.rs View File

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

pub struct DescriptorSetLayout {
handle: vk::DescriptorSetLayout,

pub device: Rc<Device>,
}

impl DescriptorSetLayout {
pub fn create(device: Rc<Device>) -> Result<Rc<Self>, vk::Result> {
let create_info = vk::DescriptorSetLayoutCreateInfo {
binding_count: Uniforms::BIND_DESC.len() as u32,
p_bindings: Uniforms::BIND_DESC.as_ptr(),
..Default::default()
};
let handle =
unsafe { device.create_descriptor_set_layout(&create_info, None)? };
Ok(Rc::new(Self { handle, device }))
}
}

impl Drop for DescriptorSetLayout {
fn drop(&mut self) {
unsafe {
self.device.destroy_descriptor_set_layout(self.handle, None);
}
}
}

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

// EOF

+ 115
- 0
source/render/descriptorpool.rs View File

@@ -0,0 +1,115 @@
use crate::render::{Buffer, DescriptorSetLayout, Device, Uniforms};
use ash::{version::DeviceV1_0, vk};
use std::rc::Rc;

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

pub struct DescriptorPool {
handle: vk::DescriptorPool,

pub device: Rc<Device>,
pub buffers: Vec<Rc<Buffer>>,
pub sets: Vec<DescriptorSet>,
}

impl DescriptorPool {
pub fn create(
device: Rc<Device>,
buffers: Vec<Rc<Buffer>>,
layout: Rc<DescriptorSetLayout>,
) -> Result<Rc<Self>, vk::Result> {
let size_info = [
vk::DescriptorPoolSize {
ty: vk::DescriptorType::UNIFORM_BUFFER,
descriptor_count: buffers.len() as u32,
..Default::default()
}
];

let create_info = vk::DescriptorPoolCreateInfo {
pool_size_count: size_info.len() as u32,
p_pool_sizes: size_info.as_ptr(),
max_sets: buffers.len() as u32,
..Default::default()
};

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

let set_layouts = vec![**layout; buffers.len()];

let alloc_info = vk::DescriptorSetAllocateInfo {
descriptor_pool: handle,
descriptor_set_count: set_layouts.len() as u32,
p_set_layouts: set_layouts.as_ptr(),
..Default::default()
};

let sets = unsafe {
device
.allocate_descriptor_sets(&alloc_info)?
.iter()
.map(|&handle| DescriptorSet { handle })
.collect::<Vec<_>>()
};

let buffer_infos =
buffers
.iter()
.map(|buffer| {
vk::DescriptorBufferInfo {
buffer: ***buffer,
range: std::mem::size_of::<Uniforms>() as vk::DeviceSize,
..Default::default()
}
})
.collect::<Vec<_>>();

let write_descriptors =
sets
.iter()
.zip(&buffer_infos)
.map(|(dst_set, buffer_info)| {
vk::WriteDescriptorSet {
dst_set: **dst_set,
descriptor_type: vk::DescriptorType::UNIFORM_BUFFER,
descriptor_count: 1,
p_buffer_info: &*buffer_info,
..Default::default()
}
})
.collect::<Vec<_>>();

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

Ok(Rc::new(Self { handle, device, buffers, sets }))
}
}

impl Drop for DescriptorPool {
fn drop(&mut self) {
unsafe {
self.device.destroy_descriptor_pool(self.handle, None);
}
}
}

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

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

// EOF

+ 5
- 7
source/render/pipeline.rs View File

@@ -33,8 +33,6 @@ impl PipelineCreateInfo {
render_pass: Rc<RenderPass>,
extent: vk::Extent2D,
) -> Self {
let bind_desc = &Vertex::BIND_DESCR;
let attr_desc = &Vertex::ATTR_DESCR;
Self {
layout,
render_pass,
@@ -54,10 +52,10 @@ impl PipelineCreateInfo {
},
],
vertex_input_state: vk::PipelineVertexInputStateCreateInfo {
vertex_binding_description_count: bind_desc.len() as u32,
p_vertex_binding_descriptions: bind_desc.as_ptr(),
vertex_attribute_description_count: attr_desc.len() as u32,
p_vertex_attribute_descriptions: attr_desc.as_ptr(),
vertex_binding_description_count: Vertex::BIND_DESC.len() as u32,
p_vertex_binding_descriptions: Vertex::BIND_DESC.as_ptr(),
vertex_attribute_description_count: Vertex::ATTR_DESC.len() as u32,
p_vertex_attribute_descriptions: Vertex::ATTR_DESC.as_ptr(),
..Default::default()
},
input_assembly_state: vk::PipelineInputAssemblyStateCreateInfo {
@@ -82,7 +80,7 @@ impl PipelineCreateInfo {
polygon_mode: vk::PolygonMode::FILL,
line_width: 1.0,
cull_mode: vk::CullModeFlags::BACK,
front_face: vk::FrontFace::CLOCKWISE,
front_face: vk::FrontFace::COUNTER_CLOCKWISE,
..Default::default()
},
multisample_state: vk::PipelineMultisampleStateCreateInfo {


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

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

pub struct PipelineLayout {
handle: vk::PipelineLayout,

pub device: Rc<Device>,
pub descriptor: Rc<DescriptorSetLayout>,
}

impl PipelineLayout {
pub fn create(device: Rc<Device>) -> Result<Rc<Self>, vk::Result> {
let create_info = vk::PipelineLayoutCreateInfo::default();
pub fn create(
descriptor: Rc<DescriptorSetLayout>,
) -> Result<Rc<Self>, vk::Result> {
let set_layouts = [ **descriptor ];

let handle =
unsafe { device.create_pipeline_layout(&create_info, None)? };
Ok(Rc::new(Self { handle, device }))
let create_info = vk::PipelineLayoutCreateInfo {
set_layout_count: set_layouts.len() as u32,
p_set_layouts: set_layouts.as_ptr(),
..Default::default()
};

let handle = unsafe {
descriptor.device.create_pipeline_layout(&create_info, None)?
};

Ok(Rc::new(Self { handle, descriptor }))
}
}

impl Drop for PipelineLayout {
fn drop(&mut self) {
unsafe {
self.device.destroy_pipeline_layout(self.handle, None);
self.descriptor.device.destroy_pipeline_layout(self.handle, None);
}
}
}


+ 23
- 0
source/render/uniforms.rs View File

@@ -0,0 +1,23 @@
use ash::vk;
use cgmath::Matrix4;

#[repr(C, align(16))]
pub struct Uniforms {
pub object: Matrix4<f32>,
pub camera: Matrix4<f32>,
pub projection: Matrix4<f32>,
}

impl Uniforms {
pub const BIND_DESC: [vk::DescriptorSetLayoutBinding; 1] = [
vk::DescriptorSetLayoutBinding {
binding: 0,
descriptor_type: vk::DescriptorType::UNIFORM_BUFFER,
descriptor_count: 1,
stage_flags: vk::ShaderStageFlags::VERTEX,
p_immutable_samplers: std::ptr::null(),
}
];
}

// EOF

+ 2
- 2
source/render/vertex.rs View File

@@ -8,7 +8,7 @@ pub struct Vertex {
}

impl Vertex {
pub const BIND_DESCR: [vk::VertexInputBindingDescription; 1] = [
pub const BIND_DESC: [vk::VertexInputBindingDescription; 1] = [
vk::VertexInputBindingDescription {
binding: 0,
stride: std::mem::size_of::<Self>() as u32,
@@ -16,7 +16,7 @@ impl Vertex {
}
];

pub const ATTR_DESCR: [vk::VertexInputAttributeDescription; 2] = [
pub const ATTR_DESC: [vk::VertexInputAttributeDescription; 2] = [
vk::VertexInputAttributeDescription {
location: 0,
binding: 0,


Loading…
Cancel
Save