Set up Framebuffers, Command Pool, and Command Buffers
This commit is contained in:
parent
1059dc028c
commit
b0159a299c
30
src/app.rs
30
src/app.rs
@ -1,6 +1,7 @@
|
|||||||
mod functions;
|
mod functions;
|
||||||
use functions::{
|
use functions::{
|
||||||
create_instance, create_logical_device, create_pipeline, create_render_pass, create_swapchain,
|
create_command_buffers, create_command_pool, create_framebuffers, create_instance,
|
||||||
|
create_logical_device, create_pipeline, create_render_pass, create_swapchain,
|
||||||
create_swapchain_image_views, pick_physical_device,
|
create_swapchain_image_views, pick_physical_device,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,6 +30,9 @@ pub struct App {
|
|||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
/// Creates our Vulkan app.
|
/// Creates our Vulkan app.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// Here be Dragons
|
||||||
pub unsafe fn create(window: &Window) -> Result<Self> {
|
pub unsafe fn create(window: &Window) -> Result<Self> {
|
||||||
let loader = LibloadingLoader::new(LIBRARY)?;
|
let loader = LibloadingLoader::new(LIBRARY)?;
|
||||||
let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
|
let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
|
||||||
@ -44,6 +48,9 @@ impl App {
|
|||||||
create_swapchain_image_views(&device, &mut data)?;
|
create_swapchain_image_views(&device, &mut data)?;
|
||||||
create_render_pass(&instance, &device, &mut data)?;
|
create_render_pass(&instance, &device, &mut data)?;
|
||||||
create_pipeline(&device, &mut data)?;
|
create_pipeline(&device, &mut data)?;
|
||||||
|
create_framebuffers(&device, &mut data)?;
|
||||||
|
create_command_pool(&instance, &device, &mut data)?;
|
||||||
|
create_command_buffers(&device, &mut data)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
entry,
|
entry,
|
||||||
@ -54,12 +61,24 @@ impl App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Renders a frame for our Vulkan app.
|
/// Renders a frame for our Vulkan app.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// Here be Dragons
|
||||||
pub unsafe fn render(&mut self, _window: &Window) -> Result<()> {
|
pub unsafe fn render(&mut self, _window: &Window) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroys our Vulkan app.
|
/// Destroys our Vulkan app, in reverse order of creation
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// Here be Dragons
|
||||||
pub unsafe fn destroy(&mut self) {
|
pub unsafe fn destroy(&mut self) {
|
||||||
|
self.device
|
||||||
|
.destroy_command_pool(self.data.command_pool, None);
|
||||||
|
self.data
|
||||||
|
.framebuffers
|
||||||
|
.iter()
|
||||||
|
.for_each(|f| self.device.destroy_framebuffer(*f, None));
|
||||||
self.device.destroy_pipeline(self.data.pipeline, None);
|
self.device.destroy_pipeline(self.data.pipeline, None);
|
||||||
self.device
|
self.device
|
||||||
.destroy_pipeline_layout(self.data.pipeline_layout, None);
|
.destroy_pipeline_layout(self.data.pipeline_layout, None);
|
||||||
@ -98,9 +117,16 @@ pub struct AppData {
|
|||||||
swapchain: vk::SwapchainKHR,
|
swapchain: vk::SwapchainKHR,
|
||||||
swapchain_images: Vec<vk::Image>,
|
swapchain_images: Vec<vk::Image>,
|
||||||
swapchain_image_views: Vec<vk::ImageView>,
|
swapchain_image_views: Vec<vk::ImageView>,
|
||||||
|
// Pipeline
|
||||||
render_pass: vk::RenderPass,
|
render_pass: vk::RenderPass,
|
||||||
pipeline_layout: vk::PipelineLayout,
|
pipeline_layout: vk::PipelineLayout,
|
||||||
pipeline: vk::Pipeline,
|
pipeline: vk::Pipeline,
|
||||||
|
// Framebuffers
|
||||||
|
framebuffers: Vec<vk::Framebuffer>,
|
||||||
|
// Command Pool
|
||||||
|
command_pool: vk::CommandPool,
|
||||||
|
// Command Buffers
|
||||||
|
command_buffers: Vec<vk::CommandBuffer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppData {}
|
impl AppData {}
|
||||||
|
@ -520,3 +520,98 @@ unsafe fn create_shader_module(device: &Device, bytecode: &[u8]) -> Result<vk::S
|
|||||||
|
|
||||||
Ok(device.create_shader_module(&info, None)?)
|
Ok(device.create_shader_module(&info, None)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) unsafe fn create_framebuffers(device: &Device, data: &mut AppData) -> Result<()> {
|
||||||
|
data.framebuffers = data
|
||||||
|
.swapchain_image_views
|
||||||
|
.iter()
|
||||||
|
.map(|i| {
|
||||||
|
let attachments = &[*i];
|
||||||
|
let create_info = vk::FramebufferCreateInfo::builder()
|
||||||
|
.render_pass(data.render_pass)
|
||||||
|
.attachments(attachments)
|
||||||
|
.width(data.swapchain_extent.width)
|
||||||
|
.height(data.swapchain_extent.height)
|
||||||
|
.layers(1);
|
||||||
|
|
||||||
|
device.create_framebuffer(&create_info, None)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================
|
||||||
|
// Command Pool
|
||||||
|
//================================================
|
||||||
|
|
||||||
|
pub(super) unsafe fn create_command_pool(
|
||||||
|
instance: &Instance,
|
||||||
|
device: &Device,
|
||||||
|
data: &mut AppData,
|
||||||
|
) -> Result<()> {
|
||||||
|
let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?;
|
||||||
|
|
||||||
|
let info = vk::CommandPoolCreateInfo::builder()
|
||||||
|
.flags(vk::CommandPoolCreateFlags::empty())
|
||||||
|
.queue_family_index(indices.graphics);
|
||||||
|
|
||||||
|
data.command_pool = device.create_command_pool(&info, None)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
//================================================
|
||||||
|
// Command Buffers
|
||||||
|
//================================================
|
||||||
|
|
||||||
|
pub(super) unsafe fn create_command_buffers(device: &Device, data: &mut AppData) -> Result<()> {
|
||||||
|
// Create the buffers
|
||||||
|
let allocate_info = vk::CommandBufferAllocateInfo::builder()
|
||||||
|
.command_pool(data.command_pool)
|
||||||
|
.level(vk::CommandBufferLevel::PRIMARY)
|
||||||
|
.command_buffer_count(data.framebuffers.len() as u32);
|
||||||
|
|
||||||
|
data.command_buffers = device.allocate_command_buffers(&allocate_info)?;
|
||||||
|
|
||||||
|
// Add commands
|
||||||
|
for (i, command_buffer) in data.command_buffers.iter().enumerate() {
|
||||||
|
let inheritance = vk::CommandBufferInheritanceInfo::builder();
|
||||||
|
|
||||||
|
let info = vk::CommandBufferBeginInfo::builder()
|
||||||
|
.flags(vk::CommandBufferUsageFlags::empty())
|
||||||
|
.inheritance_info(&inheritance);
|
||||||
|
|
||||||
|
device.begin_command_buffer(*command_buffer, &info)?;
|
||||||
|
|
||||||
|
let render_area = vk::Rect2D::builder()
|
||||||
|
.offset(vk::Offset2D::default())
|
||||||
|
.extent(data.swapchain_extent);
|
||||||
|
|
||||||
|
let color_clear_value = vk::ClearValue {
|
||||||
|
color: vk::ClearColorValue {
|
||||||
|
float32: [0.0, 0.0, 0.0, 1.0],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let clear_values = &[color_clear_value];
|
||||||
|
let info = vk::RenderPassBeginInfo::builder()
|
||||||
|
.render_pass(data.render_pass)
|
||||||
|
.framebuffer(data.framebuffers[i])
|
||||||
|
.render_area(render_area)
|
||||||
|
.clear_values(clear_values);
|
||||||
|
|
||||||
|
device.cmd_begin_render_pass(*command_buffer, &info, vk::SubpassContents::INLINE);
|
||||||
|
device.cmd_bind_pipeline(
|
||||||
|
*command_buffer,
|
||||||
|
vk::PipelineBindPoint::GRAPHICS,
|
||||||
|
data.pipeline,
|
||||||
|
);
|
||||||
|
device.cmd_draw(*command_buffer, 3, 1, 0, 0);
|
||||||
|
device.cmd_end_render_pass(*command_buffer);
|
||||||
|
|
||||||
|
device.end_command_buffer(*command_buffer)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
37
src/lib.rs
37
src/lib.rs
@ -2,10 +2,41 @@ mod app;
|
|||||||
pub use app::App;
|
pub use app::App;
|
||||||
|
|
||||||
use ::anyhow::Result;
|
use ::anyhow::Result;
|
||||||
use ::winit::window::Window;
|
use ::winit::dpi::LogicalSize;
|
||||||
|
use ::winit::event::{Event, WindowEvent};
|
||||||
|
use ::winit::event_loop::{ControlFlow, EventLoop};
|
||||||
|
use ::winit::window::WindowBuilder;
|
||||||
|
|
||||||
pub const VALIDATION_ENABLED: bool = cfg!(debug_assertions);
|
pub const VALIDATION_ENABLED: bool = cfg!(debug_assertions);
|
||||||
|
|
||||||
pub fn create_app(window: &Window) -> Result<App> {
|
pub fn run() -> Result<()> {
|
||||||
Ok(unsafe { App::create(&window)? })
|
// Window
|
||||||
|
let event_loop = EventLoop::new();
|
||||||
|
let window = WindowBuilder::new()
|
||||||
|
.with_title("Vulkan Tutorial (Rust)")
|
||||||
|
.with_inner_size(LogicalSize::new(1024, 768))
|
||||||
|
.build(&event_loop)?;
|
||||||
|
|
||||||
|
// App
|
||||||
|
let mut app = unsafe { App::create(&window)? };
|
||||||
|
let mut destroying = false;
|
||||||
|
event_loop.run(move |event, _, control_flow| {
|
||||||
|
*control_flow = ControlFlow::Poll;
|
||||||
|
match event {
|
||||||
|
// Render a frame if our Vulkan app is not being destroyed
|
||||||
|
Event::MainEventsCleared if !destroying => unsafe { app.render(&window) }.unwrap(),
|
||||||
|
// Destroy our Vulkan app.
|
||||||
|
Event::WindowEvent {
|
||||||
|
event: WindowEvent::CloseRequested,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
destroying = true;
|
||||||
|
*control_flow = ControlFlow::Exit;
|
||||||
|
unsafe {
|
||||||
|
app.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
43
src/main.rs
43
src/main.rs
@ -1,41 +1,4 @@
|
|||||||
use ::anyhow::Result;
|
fn main() -> ::anyhow::Result<()> {
|
||||||
use ::winit::dpi::LogicalSize;
|
::pretty_env_logger::init();
|
||||||
use ::winit::event::{Event, WindowEvent};
|
::vulkan_tutorial::run()
|
||||||
use ::winit::event_loop::{ControlFlow, EventLoop};
|
|
||||||
use ::winit::window::WindowBuilder;
|
|
||||||
|
|
||||||
use vulkan_tutorial::create_app;
|
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
|
||||||
pretty_env_logger::init();
|
|
||||||
|
|
||||||
// Window
|
|
||||||
let event_loop = EventLoop::new();
|
|
||||||
let window = WindowBuilder::new()
|
|
||||||
.with_title("Vulkan Tutorial (Rust)")
|
|
||||||
.with_inner_size(LogicalSize::new(1024, 768))
|
|
||||||
.build(&event_loop)?;
|
|
||||||
|
|
||||||
// App
|
|
||||||
let mut app = create_app(&window)?;
|
|
||||||
let mut destroying = false;
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
|
||||||
*control_flow = ControlFlow::Poll;
|
|
||||||
match event {
|
|
||||||
// Render a frame if our Vulkan app is not being destroyed
|
|
||||||
Event::MainEventsCleared if !destroying => unsafe { app.render(&window) }.unwrap(),
|
|
||||||
// Destroy our Vulkan app.
|
|
||||||
Event::WindowEvent {
|
|
||||||
event: WindowEvent::CloseRequested,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
destroying = true;
|
|
||||||
*control_flow = ControlFlow::Exit;
|
|
||||||
unsafe {
|
|
||||||
app.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user