Add Descriptor layout and its buffer
This commit is contained in:
parent
399cce3d81
commit
fafbf868bf
@ -14,5 +14,5 @@ png = "0.17"
|
||||
pretty_env_logger = "0.4"
|
||||
thiserror = "1"
|
||||
tobj = { version = "3", features = ["log"] }
|
||||
vulkanalia = { version = "=0.16.0", features = ["libloading", "window", "provisional"] }
|
||||
vulkanalia = { version = "0.16.0", features = ["libloading", "window", "provisional"] }
|
||||
winit = "0.27"
|
||||
|
@ -1,11 +1,17 @@
|
||||
#version 450
|
||||
|
||||
layout(binding = 0) uniform UniformBufferObject {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
} ubo;
|
||||
|
||||
layout(location = 0) in vec2 inPosition;
|
||||
layout(location = 1) in vec3 inColor;
|
||||
|
||||
layout(location = 0) out vec3 fragColor;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(inPosition, 0.0, 1.0);
|
||||
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);
|
||||
fragColor = inColor;
|
||||
}
|
||||
|
BIN
shaders/vert.spv
BIN
shaders/vert.spv
Binary file not shown.
49
src/app.rs
49
src/app.rs
@ -9,6 +9,8 @@ use ::anyhow::{anyhow, Result};
|
||||
use ::lazy_static::lazy_static;
|
||||
use ::nalgebra_glm as glm;
|
||||
use ::std::mem::size_of;
|
||||
use ::std::ptr::copy_nonoverlapping as memcpy;
|
||||
use ::std::time::Instant;
|
||||
use ::vulkanalia::loader::{LibloadingLoader, LIBRARY};
|
||||
use ::vulkanalia::prelude::v1_0::*;
|
||||
use ::vulkanalia::vk::{KhrSurfaceExtension, KhrSwapchainExtension};
|
||||
@ -49,6 +51,7 @@ pub struct App {
|
||||
pub device: Device,
|
||||
frame: usize,
|
||||
pub resized: bool,
|
||||
start: Instant,
|
||||
}
|
||||
|
||||
impl App {
|
||||
@ -72,6 +75,7 @@ impl App {
|
||||
device,
|
||||
frame: 0,
|
||||
resized: false,
|
||||
start: Instant::now(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -82,7 +86,6 @@ impl App {
|
||||
/// Here be Dragons
|
||||
pub fn destroy(&mut self) {
|
||||
unsafe {
|
||||
self.data.destroy_swapchain(&self.device);
|
||||
self.data.destroy(&self.instance, &self.device);
|
||||
}
|
||||
}
|
||||
@ -117,6 +120,8 @@ impl App {
|
||||
|
||||
self.data.images_in_flight[image_index] = in_flight_fence;
|
||||
|
||||
self.update_uniform_buffer(image_index)?;
|
||||
|
||||
let wait_semaphores = &[self.data.image_available_semaphores[self.frame]];
|
||||
let wait_stages = &[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];
|
||||
let command_buffers = &[self.data.command_buffers[image_index]];
|
||||
@ -158,6 +163,48 @@ impl App {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn update_uniform_buffer(&self, image_index: usize) -> Result<()> {
|
||||
let time = self.start.elapsed().as_secs_f32();
|
||||
|
||||
let model = glm::rotate(
|
||||
&glm::identity(),
|
||||
time * glm::radians(&glm::vec1(90.0))[0],
|
||||
&glm::vec3(0.0, 0.0, 1.0),
|
||||
);
|
||||
|
||||
let view = glm::look_at(
|
||||
&glm::vec3(2.0, 2.0, 2.0),
|
||||
&glm::vec3(0.0, 0.0, 0.0),
|
||||
&glm::vec3(0.0, 0.0, 1.0),
|
||||
);
|
||||
|
||||
let mut proj = glm::perspective(
|
||||
self.data.swapchain_extent.width as f32 / self.data.swapchain_extent.height as f32,
|
||||
glm::radians(&glm::vec1(45.0))[0],
|
||||
0.1,
|
||||
10.0,
|
||||
);
|
||||
|
||||
// Flip the image right-side-up
|
||||
proj[(1, 1)] *= -1.0;
|
||||
|
||||
let ubo = UniformBufferObject { model, view, proj };
|
||||
|
||||
let memory = self.device.map_memory(
|
||||
self.data.uniform_buffers_memory[image_index],
|
||||
0,
|
||||
size_of::<UniformBufferObject>() as u64,
|
||||
vk::MemoryMapFlags::empty(),
|
||||
)?;
|
||||
|
||||
memcpy(&ubo, memory.cast(), 1);
|
||||
|
||||
self.device
|
||||
.unmap_memory(self.data.uniform_buffers_memory[image_index]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Recreates the swapchain
|
||||
///
|
||||
/// # Safety
|
||||
|
107
src/app/data.rs
107
src/app/data.rs
@ -48,12 +48,13 @@ pub(crate) struct AppData {
|
||||
pub(super) present_queue: vk::Queue,
|
||||
// Swapchain
|
||||
swapchain_format: vk::Format,
|
||||
swapchain_extent: vk::Extent2D,
|
||||
pub(super) swapchain_extent: vk::Extent2D,
|
||||
pub(super) swapchain: vk::SwapchainKHR,
|
||||
swapchain_images: Vec<vk::Image>,
|
||||
swapchain_image_views: Vec<vk::ImageView>,
|
||||
// Pipeline
|
||||
render_pass: vk::RenderPass,
|
||||
descriptor_set_layout: vk::DescriptorSetLayout,
|
||||
pipeline_layout: vk::PipelineLayout,
|
||||
pipeline: vk::Pipeline,
|
||||
// Framebuffers
|
||||
@ -65,6 +66,8 @@ pub(crate) struct AppData {
|
||||
vertex_buffer_memory: vk::DeviceMemory,
|
||||
index_buffer: vk::Buffer,
|
||||
index_buffer_memory: vk::DeviceMemory,
|
||||
uniform_buffers: Vec<vk::Buffer>,
|
||||
pub(super) uniform_buffers_memory: Vec<vk::DeviceMemory>,
|
||||
// Command Buffers
|
||||
pub(super) command_buffers: Vec<vk::CommandBuffer>,
|
||||
// Sync Objects
|
||||
@ -93,22 +96,20 @@ impl AppData {
|
||||
self.create_swapchain(window, &instance, &device)?;
|
||||
self.create_swapchain_image_views(&device)?;
|
||||
self.create_render_pass(&instance, &device)?;
|
||||
self.create_descriptor_set_layout(&device)?;
|
||||
self.create_pipeline(&device)?;
|
||||
self.create_framebuffers(&device)?;
|
||||
self.create_command_pool(&instance, &device)?;
|
||||
self.create_vertex_buffer(&instance, &device)?;
|
||||
self.create_index_buffer(&instance, &device)?;
|
||||
self.create_uniform_buffers(&instance, &device)?;
|
||||
self.create_command_buffers(&device)?;
|
||||
self.create_sync_objects(&device)?;
|
||||
|
||||
Ok((instance, device))
|
||||
}
|
||||
|
||||
pub(super) unsafe fn create_instance(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
entry: &Entry,
|
||||
) -> Result<Instance> {
|
||||
unsafe fn create_instance(&mut self, window: &Window, entry: &Entry) -> Result<Instance> {
|
||||
// Application Info
|
||||
let application_info = vk::ApplicationInfo::builder()
|
||||
.application_name(b"Vulkan Tutorial\0")
|
||||
@ -192,7 +193,13 @@ impl AppData {
|
||||
///
|
||||
/// # Safety
|
||||
/// Here be Dragons
|
||||
pub(super) unsafe fn destroy_swapchain(&mut self, device: &Device) {
|
||||
unsafe fn destroy_swapchain(&mut self, device: &Device) {
|
||||
self.uniform_buffers
|
||||
.iter()
|
||||
.for_each(|b| device.destroy_buffer(*b, None));
|
||||
self.uniform_buffers_memory
|
||||
.iter()
|
||||
.for_each(|m| device.free_memory(*m, None));
|
||||
self.framebuffers
|
||||
.iter()
|
||||
.for_each(|f| device.destroy_framebuffer(*f, None));
|
||||
@ -211,6 +218,9 @@ impl AppData {
|
||||
/// # Safety
|
||||
/// Here be Dragons
|
||||
pub unsafe fn destroy(&mut self, instance: &Instance, device: &Device) {
|
||||
self.destroy_swapchain(device);
|
||||
device.destroy_descriptor_set_layout(self.descriptor_set_layout, None);
|
||||
|
||||
device.destroy_buffer(self.index_buffer, None);
|
||||
device.free_memory(self.index_buffer_memory, None);
|
||||
device.destroy_buffer(self.vertex_buffer, None);
|
||||
@ -240,7 +250,7 @@ impl AppData {
|
||||
// Physical Device
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn pick_physical_device(&mut self, instance: &Instance) -> Result<()> {
|
||||
unsafe fn pick_physical_device(&mut self, instance: &Instance) -> Result<()> {
|
||||
for physical_device in instance.enumerate_physical_devices()? {
|
||||
let properties = instance.get_physical_device_properties(physical_device);
|
||||
|
||||
@ -279,7 +289,7 @@ impl AppData {
|
||||
// Logical Device
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_logical_device(&mut self, instance: &Instance) -> Result<Device> {
|
||||
unsafe fn create_logical_device(&mut self, instance: &Instance) -> Result<Device> {
|
||||
// Queue Create Infos
|
||||
let indices = QueueFamilyIndices::get(instance, self, self.physical_device)?;
|
||||
|
||||
@ -342,7 +352,7 @@ impl AppData {
|
||||
// Swapchain
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_swapchain(
|
||||
unsafe fn create_swapchain(
|
||||
&mut self,
|
||||
window: &Window,
|
||||
instance: &Instance,
|
||||
@ -412,6 +422,7 @@ impl AppData {
|
||||
self.create_render_pass(instance, device)?;
|
||||
self.create_pipeline(device)?;
|
||||
self.create_framebuffers(device)?;
|
||||
self.create_uniform_buffers(instance, device)?;
|
||||
self.create_command_buffers(device)?;
|
||||
|
||||
self.images_in_flight
|
||||
@ -420,7 +431,7 @@ impl AppData {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) unsafe fn create_swapchain_image_views(&mut self, device: &Device) -> Result<()> {
|
||||
unsafe fn create_swapchain_image_views(&mut self, device: &Device) -> Result<()> {
|
||||
self.swapchain_image_views = self
|
||||
.swapchain_images
|
||||
.iter()
|
||||
@ -456,11 +467,22 @@ impl AppData {
|
||||
// Pipeline
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_render_pass(
|
||||
&mut self,
|
||||
_instance: &Instance,
|
||||
device: &Device,
|
||||
) -> Result<()> {
|
||||
unsafe fn create_descriptor_set_layout(&mut self, device: &Device) -> Result<()> {
|
||||
let ubo_binding = vk::DescriptorSetLayoutBinding::builder()
|
||||
.binding(0)
|
||||
.descriptor_type(vk::DescriptorType::UNIFORM_BUFFER)
|
||||
.descriptor_count(1)
|
||||
.stage_flags(vk::ShaderStageFlags::VERTEX);
|
||||
|
||||
let bindings = &[ubo_binding];
|
||||
let info = vk::DescriptorSetLayoutCreateInfo::builder().bindings(bindings);
|
||||
|
||||
self.descriptor_set_layout = device.create_descriptor_set_layout(&info, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn create_render_pass(&mut self, _instance: &Instance, device: &Device) -> Result<()> {
|
||||
let color_attachment = vk::AttachmentDescription::builder()
|
||||
.format(self.swapchain_format)
|
||||
.samples(vk::SampleCountFlags::_1)
|
||||
@ -500,7 +522,7 @@ impl AppData {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) unsafe fn create_pipeline(&mut self, device: &Device) -> Result<()> {
|
||||
unsafe fn create_pipeline(&mut self, device: &Device) -> Result<()> {
|
||||
let vert = include_bytes!("../../shaders/vert.spv");
|
||||
let frag = include_bytes!("../../shaders/frag.spv");
|
||||
|
||||
@ -575,7 +597,8 @@ impl AppData {
|
||||
.attachments(attachments)
|
||||
.blend_constants([0.0, 0.0, 0.0, 0.0]);
|
||||
|
||||
let layout_info = vk::PipelineLayoutCreateInfo::builder();
|
||||
let set_layouts = &[self.descriptor_set_layout];
|
||||
let layout_info = vk::PipelineLayoutCreateInfo::builder().set_layouts(set_layouts);
|
||||
self.pipeline_layout = device.create_pipeline_layout(&layout_info, None)?;
|
||||
|
||||
let stages = &[vert_stage, frag_stage];
|
||||
@ -602,7 +625,7 @@ impl AppData {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) unsafe fn create_framebuffers(&mut self, device: &Device) -> Result<()> {
|
||||
unsafe fn create_framebuffers(&mut self, device: &Device) -> Result<()> {
|
||||
self.framebuffers = self
|
||||
.swapchain_image_views
|
||||
.iter()
|
||||
@ -626,11 +649,7 @@ impl AppData {
|
||||
// Command Pool
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_command_pool(
|
||||
&mut self,
|
||||
instance: &Instance,
|
||||
device: &Device,
|
||||
) -> Result<()> {
|
||||
unsafe fn create_command_pool(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
let indices = QueueFamilyIndices::get(instance, self, self.physical_device)?;
|
||||
|
||||
let info = vk::CommandPoolCreateInfo::builder()
|
||||
@ -711,11 +730,7 @@ impl AppData {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) unsafe fn create_vertex_buffer(
|
||||
&mut self,
|
||||
instance: &Instance,
|
||||
device: &Device,
|
||||
) -> Result<()> {
|
||||
unsafe fn create_vertex_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
// Create staging buffer
|
||||
let size = (size_of::<Vertex>() * VERTICES.len()) as u64;
|
||||
let (staging_buffer, staging_buffer_memory) = self.create_buffer(
|
||||
@ -753,11 +768,7 @@ impl AppData {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) unsafe fn create_index_buffer(
|
||||
&mut self,
|
||||
instance: &Instance,
|
||||
device: &Device,
|
||||
) -> Result<()> {
|
||||
unsafe fn create_index_buffer(&mut self, instance: &Instance, device: &Device) -> Result<()> {
|
||||
let size = (size_of::<u16>() * INDICES.len()) as u64;
|
||||
let (staging_buffer, staging_buffer_memory) = self.create_buffer(
|
||||
instance,
|
||||
@ -791,11 +802,35 @@ impl AppData {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn create_uniform_buffers(
|
||||
&mut self,
|
||||
instance: &Instance,
|
||||
device: &Device,
|
||||
) -> Result<()> {
|
||||
self.uniform_buffers.clear();
|
||||
self.uniform_buffers_memory.clear();
|
||||
|
||||
for _ in 0..self.swapchain_images.len() {
|
||||
let (uniform_buffer, uniform_buffer_memory) = self.create_buffer(
|
||||
instance,
|
||||
device,
|
||||
size_of::<UniformBufferObject>() as u64,
|
||||
vk::BufferUsageFlags::UNIFORM_BUFFER,
|
||||
vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE,
|
||||
)?;
|
||||
|
||||
self.uniform_buffers.push(uniform_buffer);
|
||||
self.uniform_buffers_memory.push(uniform_buffer_memory);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
//================================================
|
||||
// Command Buffers
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_command_buffers(&mut self, device: &Device) -> Result<()> {
|
||||
unsafe fn create_command_buffers(&mut self, device: &Device) -> Result<()> {
|
||||
// Create the buffers
|
||||
let allocate_info = vk::CommandBufferAllocateInfo::builder()
|
||||
.command_pool(self.command_pool)
|
||||
@ -857,7 +892,7 @@ impl AppData {
|
||||
// Sync Objects
|
||||
//================================================
|
||||
|
||||
pub(super) unsafe fn create_sync_objects(&mut self, device: &Device) -> Result<()> {
|
||||
unsafe fn create_sync_objects(&mut self, device: &Device) -> Result<()> {
|
||||
let semaphore_info = vk::SemaphoreCreateInfo::builder();
|
||||
let fence_info = vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED);
|
||||
|
||||
|
@ -132,3 +132,14 @@ impl Vertex {
|
||||
[pos, color]
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Resource Descriptors
|
||||
// ----------------------------------------------------------------------------
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct UniformBufferObject {
|
||||
pub(crate) model: glm::Mat4,
|
||||
pub(crate) view: glm::Mat4,
|
||||
pub(crate) proj: glm::Mat4,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user