First render !!!
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 1s
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 1s
This commit is contained in:
parent
2590db0a06
commit
c0367144a6
9 changed files with 123 additions and 70 deletions
|
@ -1,5 +1,5 @@
|
|||
use crate::vulkan::{
|
||||
VkCommandPool, VkDevice, VkFramebuffer, VkGraphicsPipeline, VkInstance, VkPhysicalDevice,
|
||||
VkCommandPool, VkDevice, VkFence, VkFramebuffer, VkGraphicsPipeline, VkInstance, VkPhysicalDevice,
|
||||
VkRenderPass, VkSemaphore, VkSurface, VkSwapchain,
|
||||
};
|
||||
use ash::vk;
|
||||
|
@ -18,6 +18,7 @@ pub struct VkRenderContext {
|
|||
command_buffers: Vec<vk::CommandBuffer>,
|
||||
image_available_semaphore: VkSemaphore,
|
||||
render_finished_semaphore: VkSemaphore,
|
||||
in_flight_fence: VkFence,
|
||||
}
|
||||
|
||||
impl VkRenderContext {
|
||||
|
@ -36,7 +37,7 @@ impl VkRenderContext {
|
|||
Some(vk::QueueFlags::GRAPHICS),
|
||||
Some(&surface),
|
||||
)
|
||||
.ok_or_else(|| anyhow::anyhow!("Unable to find physical device"))?;
|
||||
.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()
|
||||
|
@ -77,50 +78,9 @@ impl VkRenderContext {
|
|||
.allocate_command_buffers(&command_buffer_info)?
|
||||
};
|
||||
|
||||
// Same in VkGraphicsPipeline (TODO: Refactor this)
|
||||
let render_area = vk::Rect2D::default().extent(swapchain.surface_resolution);
|
||||
let clear_value = vk::ClearValue::default();
|
||||
for (index, command_buffer) in command_buffers.iter().enumerate() {
|
||||
let command_buffer_begin_info = vk::CommandBufferBeginInfo::default();
|
||||
unsafe {
|
||||
device
|
||||
.handle
|
||||
.begin_command_buffer(*command_buffer, &command_buffer_begin_info)?
|
||||
};
|
||||
|
||||
let clear_values = [clear_value];
|
||||
let framebuffer = framebuffers[index].as_ref();
|
||||
let render_pass_begin_info = vk::RenderPassBeginInfo::default()
|
||||
.render_pass(render_pass.handle)
|
||||
.framebuffer(framebuffer.handle)
|
||||
.render_area(render_area)
|
||||
.clear_values(&clear_values);
|
||||
|
||||
unsafe {
|
||||
device.handle.cmd_begin_render_pass(
|
||||
*command_buffer,
|
||||
&render_pass_begin_info,
|
||||
vk::SubpassContents::INLINE,
|
||||
);
|
||||
};
|
||||
|
||||
unsafe {
|
||||
device.handle.cmd_bind_pipeline(
|
||||
*command_buffer,
|
||||
vk::PipelineBindPoint::GRAPHICS,
|
||||
pipeline.pipeline,
|
||||
)
|
||||
};
|
||||
|
||||
unsafe { device.handle.cmd_draw(*command_buffer, 3, 1, 0, 0) };
|
||||
|
||||
unsafe { device.handle.cmd_end_render_pass(*command_buffer) };
|
||||
|
||||
unsafe { device.handle.end_command_buffer(*command_buffer)? };
|
||||
}
|
||||
|
||||
let image_available_semaphore = VkSemaphore::new(device.clone())?;
|
||||
let render_finished_semaphore = VkSemaphore::new(device.clone())?;
|
||||
let image_available_semaphore = VkSemaphore::new(&device)?;
|
||||
let render_finished_semaphore = VkSemaphore::new(&device)?;
|
||||
let in_flight_fence = VkFence::new(&device)?;
|
||||
|
||||
Ok(Self {
|
||||
instance,
|
||||
|
@ -137,35 +97,101 @@ impl VkRenderContext {
|
|||
|
||||
image_available_semaphore,
|
||||
render_finished_semaphore,
|
||||
in_flight_fence,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn render(&mut self) -> anyhow::Result<()> {
|
||||
let queue = self
|
||||
.device
|
||||
.get_device_queue(0)
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get a queue"))?;
|
||||
unsafe { self.device.handle.wait_for_fences(&[self.in_flight_fence.handle], true, u64::MAX)? };
|
||||
unsafe { self.device.handle.reset_fences(&[self.in_flight_fence.handle])? };
|
||||
|
||||
let (index, _) = self
|
||||
.swapchain
|
||||
.acquire_next_image(&self.image_available_semaphore)?;
|
||||
|
||||
let command_buffer = self.command_buffers[index as usize];
|
||||
unsafe { self.device.handle.reset_command_buffer(command_buffer, vk::CommandBufferResetFlags::default())? };
|
||||
|
||||
let render_area = vk::Rect2D::default().extent(self.swapchain.surface_resolution);
|
||||
let clear_value = vk::ClearValue::default();
|
||||
let command_buffer_begin_info = vk::CommandBufferBeginInfo::default();
|
||||
unsafe {
|
||||
self.device
|
||||
.handle
|
||||
.begin_command_buffer(command_buffer, &command_buffer_begin_info)?
|
||||
};
|
||||
|
||||
let clear_values = [clear_value];
|
||||
let framebuffer = self.framebuffers[index as usize].as_ref();
|
||||
let render_pass_begin_info = vk::RenderPassBeginInfo::default()
|
||||
.render_pass(self.render_pass.handle)
|
||||
.framebuffer(framebuffer.handle)
|
||||
.render_area(render_area)
|
||||
.clear_values(&clear_values);
|
||||
|
||||
unsafe {
|
||||
self.device.handle.cmd_begin_render_pass(
|
||||
command_buffer,
|
||||
&render_pass_begin_info,
|
||||
vk::SubpassContents::INLINE,
|
||||
);
|
||||
};
|
||||
|
||||
unsafe {
|
||||
self.device.handle.cmd_bind_pipeline(
|
||||
command_buffer,
|
||||
vk::PipelineBindPoint::GRAPHICS,
|
||||
self.pipeline.pipeline,
|
||||
)
|
||||
};
|
||||
|
||||
let viewport = vk::Viewport::default()
|
||||
.width(self.swapchain.surface_resolution.width as f32)
|
||||
.height(self.swapchain.surface_resolution.height as f32)
|
||||
.max_depth(1.0);
|
||||
|
||||
unsafe { self.device.handle.cmd_set_viewport(command_buffer, 0, &[viewport]) }
|
||||
|
||||
let scissor = vk::Rect2D::default().extent(self.swapchain.surface_resolution);
|
||||
|
||||
unsafe { self.device.handle.cmd_set_scissor(command_buffer, 0, &[scissor]) }
|
||||
|
||||
unsafe { self.device.handle.cmd_draw(command_buffer, 3, 1, 0, 0) };
|
||||
|
||||
unsafe { self.device.handle.cmd_end_render_pass(command_buffer) };
|
||||
|
||||
unsafe { self.device.handle.end_command_buffer(command_buffer)? };
|
||||
|
||||
let wait_semaphores = [self.image_available_semaphore.handle];
|
||||
let signal_semaphores = [self.render_finished_semaphore.handle];
|
||||
let wait_stages = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];
|
||||
let command_buffers_to_submit = [self.command_buffers[index as usize]];
|
||||
let command_buffers_to_submit = [command_buffer];
|
||||
let submit_info = vk::SubmitInfo::default()
|
||||
.wait_semaphores(&wait_semaphores)
|
||||
.wait_dst_stage_mask(&wait_stages)
|
||||
.command_buffers(&command_buffers_to_submit)
|
||||
.signal_semaphores(&signal_semaphores);
|
||||
|
||||
let queue = self
|
||||
.device
|
||||
.get_device_queue(0)
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get a queue"))?;
|
||||
|
||||
unsafe {
|
||||
self.device
|
||||
.handle
|
||||
.queue_submit(*queue, &[submit_info], vk::Fence::null())?
|
||||
.queue_submit(*queue, &[submit_info], self.in_flight_fence.handle)?
|
||||
};
|
||||
|
||||
let swapchains = [self.swapchain.swapchain.unwrap()];
|
||||
let indices = [index];
|
||||
let present_info = vk::PresentInfoKHR::default()
|
||||
.wait_semaphores(&signal_semaphores)
|
||||
.swapchains(&swapchains)
|
||||
.image_indices(&indices);
|
||||
|
||||
unsafe { self.device.swapchain_loader.queue_present(*queue, &present_info)? };
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue