172 lines
6.3 KiB
Rust
172 lines
6.3 KiB
Rust
use crate::vulkan::{VkDevice, VkInstance, VkPhysicalDevice, VkSurface, VkSwapchain};
|
|
use ash::vk;
|
|
use std::sync::Arc;
|
|
|
|
pub struct VkRenderContext {
|
|
instance: Arc<VkInstance>,
|
|
surface: Arc<VkSurface>,
|
|
device: Arc<VkDevice>,
|
|
|
|
swapchain: Arc<VkSwapchain>,
|
|
// present_queue: vk::Queue,
|
|
//
|
|
// pool: vk::CommandPool,
|
|
//
|
|
// setup_command_buffer: vk::CommandBuffer,
|
|
// draw_command_buffer: vk::CommandBuffer,
|
|
//
|
|
// draw_commands_reuse_fence: vk::Fence,
|
|
// setup_commands_reuse_fence: vk::Fence,
|
|
//
|
|
// present_complete_semaphore: vk::Semaphore,
|
|
// rendering_complete_semaphore: vk::Semaphore,
|
|
}
|
|
|
|
impl VkRenderContext {
|
|
pub fn init(window: &crate::display::Window) -> anyhow::Result<Self> {
|
|
let required_extensions = window.required_extensions()?;
|
|
|
|
let instance = Arc::new(VkInstance::new(&required_extensions));
|
|
let surface = Arc::new(VkSurface::new(&window, instance.clone())?);
|
|
|
|
let mut physical_devices = instance.get_physical_devices();
|
|
physical_devices.sort_by(|a, b| b.priority().cmp(&a.priority()));
|
|
|
|
let (physical_device, queue_family_index, properties) =
|
|
VkPhysicalDevice::pick_physical_device_and_queue_by(
|
|
&physical_devices,
|
|
Some(vk::QueueFlags::GRAPHICS),
|
|
Some(&surface),
|
|
)
|
|
.ok_or_else(|| anyhow::anyhow!("Unable to find physical device"))?;
|
|
log::debug!(
|
|
"Selected queue {properties:#?} for physical device {:?}",
|
|
physical_device.properties.device_name_as_c_str()
|
|
);
|
|
|
|
let device = Arc::new(VkDevice::new_graphics_device(
|
|
instance.clone(),
|
|
&physical_device,
|
|
queue_family_index,
|
|
)?);
|
|
|
|
let swapchain = Arc::new(VkSwapchain::new(
|
|
&window,
|
|
surface.clone(),
|
|
device.clone(),
|
|
&physical_device,
|
|
)?);
|
|
|
|
// let present_queue = device.get_device_queue(0);
|
|
//
|
|
// let pool_create_info = vk::CommandPoolCreateInfo::default()
|
|
// .flags(vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER);
|
|
//
|
|
// let pool = device.create_command_pool(&pool_create_info)
|
|
// .expect("Failed to create command pool");
|
|
//
|
|
// let command_buffer_allocate_info = vk::CommandBufferAllocateInfo::default()
|
|
// .command_buffer_count(2)
|
|
// .command_pool(pool)
|
|
// .level(vk::CommandBufferLevel::PRIMARY);
|
|
//
|
|
// let command_buffers = device
|
|
// .allocate_command_buffers(&command_buffer_allocate_info)
|
|
// .expect("Failed to create command buffers");
|
|
// let setup_command_buffer = command_buffers[0];
|
|
// let draw_command_buffer = command_buffers[1];
|
|
//
|
|
// let fence_create_info =
|
|
// vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED);
|
|
//
|
|
// let draw_commands_reuse_fence = device
|
|
// .create_fence(&fence_create_info)
|
|
// .expect("Failed to create draw commands fence");
|
|
// let setup_commands_reuse_fence = device
|
|
// .create_fence(&fence_create_info)
|
|
// .expect("Failed to create setup commands fence");
|
|
//
|
|
// let semaphore_create_info = vk::SemaphoreCreateInfo::default();
|
|
//
|
|
// let present_complete_semaphore = device
|
|
// .create_semaphore(&semaphore_create_info)
|
|
// .expect("Failed to create present complete semaphore");
|
|
// let rendering_complete_semaphore = device
|
|
// .create_semaphore(&semaphore_create_info)
|
|
// .expect("Failed to create rendering complete semaphore");
|
|
|
|
Ok(Self {
|
|
instance,
|
|
surface,
|
|
device,
|
|
|
|
swapchain,
|
|
// present_queue,
|
|
//
|
|
// pool,
|
|
//
|
|
// setup_command_buffer,
|
|
// draw_command_buffer,
|
|
//
|
|
// present_complete_semaphore,
|
|
// rendering_complete_semaphore,
|
|
//
|
|
// draw_commands_reuse_fence,
|
|
// setup_commands_reuse_fence,
|
|
})
|
|
}
|
|
|
|
pub fn render(&mut self) -> anyhow::Result<()> {
|
|
// unsafe {
|
|
// self.device.handle
|
|
// .wait_for_fences(&[self.draw_commands_reuse_fence], true, u64::MAX)
|
|
// .expect("Wait for fence failed.");
|
|
//
|
|
// self.device.handle
|
|
// .reset_fences(&[self.draw_commands_reuse_fence])
|
|
// .expect("Reset fences failed.");
|
|
//
|
|
// self.device.handle
|
|
// .reset_command_buffer(
|
|
// self.draw_command_buffer,
|
|
// vk::CommandBufferResetFlags::RELEASE_RESOURCES,
|
|
// )
|
|
// .expect("Reset command buffer failed.");
|
|
//
|
|
// let command_buffer_begin_info = vk::CommandBufferBeginInfo::default()
|
|
// .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT);
|
|
//
|
|
// self.device.handle
|
|
// .begin_command_buffer(self.draw_command_buffer, &command_buffer_begin_info)
|
|
// .expect("Begin commandbuffer");
|
|
//
|
|
// self.device.handle
|
|
// .end_command_buffer(self.draw_command_buffer)
|
|
// .expect("End commandbuffer");
|
|
//
|
|
// let command_buffers = vec![self.draw_command_buffer];
|
|
// let semaphores = vec![self.rendering_complete_semaphore];
|
|
// let wait_mask = vec![vk::PipelineStageFlags::default()];
|
|
//
|
|
// let submit_info = vk::SubmitInfo::default()
|
|
// .wait_semaphores(&semaphores)
|
|
// .wait_dst_stage_mask(&wait_mask)
|
|
// .command_buffers(&command_buffers)
|
|
// .signal_semaphores(&semaphores);
|
|
//
|
|
// self.device.handle
|
|
// .queue_submit(self.present_queue, &[submit_info], self.draw_commands_reuse_fence)
|
|
// .expect("queue submit failed.");
|
|
// }
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn update_resolution(&mut self, width: u32, height: u32) -> anyhow::Result<()> {
|
|
if let Some(swapchain) = Arc::get_mut(&mut self.swapchain) {
|
|
swapchain.update_resolution(width, height)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|