This commit is contained in:
parent
c0367144a6
commit
dd8a5a97ea
9 changed files with 83 additions and 13 deletions
10
res/shaders/vertex.frag
Normal file
10
res/shaders/vertex.frag
Normal file
|
@ -0,0 +1,10 @@
|
|||
#version 450
|
||||
#extension GL_ARB_separate_shader_objects: enable
|
||||
|
||||
layout (location = 0) in vec3 fragColor;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
outColor = vec4(fragColor, 1.0);
|
||||
}
|
1
res/shaders/vertex.vert
Normal file
1
res/shaders/vertex.vert
Normal file
|
@ -0,0 +1 @@
|
|||
#version 450
#extension GL_ARB_separate_shader_objects: enable
// NOTE: names must match the `Vertex` struct in Rust
layout (location = 0) in vec2 pos;
layout (location = 1) in vec3 color;
layout (location = 0) out vec3 fragColor;
out gl_PerVertex {
vec4 gl_Position;
};
void main() {
gl_Position = vec4(pos, 0.0, 1.0);
fragColor = color;
}
|
|
@ -38,3 +38,4 @@ mod vk_fence;
|
|||
pub(self) use vk_fence::VkFence;
|
||||
|
||||
mod utils;
|
||||
mod vertex;
|
||||
|
|
33
src/vulkan/vertex.rs
Normal file
33
src/vulkan/vertex.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
use ash::vk;
|
||||
use std::mem::offset_of;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Vertex {
|
||||
pub position: [f32; 2],
|
||||
pub color: [f32; 3],
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
pub fn get_binding_description() -> vk::VertexInputBindingDescription {
|
||||
vk::VertexInputBindingDescription::default()
|
||||
.binding(0)
|
||||
.stride(size_of::<Self>() as u32)
|
||||
.input_rate(vk::VertexInputRate::VERTEX)
|
||||
}
|
||||
|
||||
pub fn get_attribute_descriptions() -> [vk::VertexInputAttributeDescription; 2] {
|
||||
let position_attribute = vk::VertexInputAttributeDescription::default()
|
||||
.binding(0)
|
||||
.location(0)
|
||||
.format(vk::Format::R32G32_SFLOAT)
|
||||
.offset(offset_of!(Vertex, position) as u32);
|
||||
|
||||
let color_attribute = vk::VertexInputAttributeDescription::default()
|
||||
.binding(0)
|
||||
.location(1)
|
||||
.format(vk::Format::R32G32B32_SFLOAT)
|
||||
.offset(offset_of!(Vertex, color) as u32);
|
||||
|
||||
[position_attribute, color_attribute]
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ use std::sync::Arc;
|
|||
|
||||
pub struct VkGraphicsPipeline {
|
||||
device: Arc<VkDevice>,
|
||||
swapchain: Arc<VkSwapchain>,
|
||||
render_pass: Arc<VkRenderPass>,
|
||||
|
||||
pub(super) pipeline_layout: vk::PipelineLayout,
|
||||
|
@ -18,7 +17,6 @@ pub struct VkGraphicsPipeline {
|
|||
impl VkGraphicsPipeline {
|
||||
pub fn new(
|
||||
device: &Arc<VkDevice>,
|
||||
swapchain: &Arc<VkSwapchain>,
|
||||
render_pass: &Arc<VkRenderPass>,
|
||||
) -> anyhow::Result<Self> {
|
||||
let shader_entry_name = CStr::from_bytes_with_nul(b"main\0")?;
|
||||
|
@ -99,7 +97,6 @@ impl VkGraphicsPipeline {
|
|||
|
||||
Ok(Self {
|
||||
device: device.clone(),
|
||||
swapchain: swapchain.clone(),
|
||||
render_pass: render_pass.clone(),
|
||||
pipeline_layout,
|
||||
pipeline,
|
||||
|
|
|
@ -62,7 +62,7 @@ impl VkRenderContext {
|
|||
.create_framebuffers(&render_pass)
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get framebuffers"))?;
|
||||
|
||||
let pipeline = Arc::new(VkGraphicsPipeline::new(&device, &swapchain, &render_pass)?);
|
||||
let pipeline = Arc::new(VkGraphicsPipeline::new(&device, &render_pass)?);
|
||||
|
||||
let command_pool = VkCommandPool::new(&device)?;
|
||||
|
||||
|
@ -109,6 +109,10 @@ impl VkRenderContext {
|
|||
.swapchain
|
||||
.acquire_next_image(&self.image_available_semaphore)?;
|
||||
|
||||
// if self.swapchain.is_dirty() {
|
||||
// self.update_swapchain()?
|
||||
// }
|
||||
|
||||
let command_buffer = self.command_buffers[index as usize];
|
||||
unsafe { self.device.handle.reset_command_buffer(command_buffer, vk::CommandBufferResetFlags::default())? };
|
||||
|
||||
|
@ -152,7 +156,7 @@ impl VkRenderContext {
|
|||
|
||||
unsafe { self.device.handle.cmd_set_viewport(command_buffer, 0, &[viewport]) }
|
||||
|
||||
let scissor = vk::Rect2D::default().extent(self.swapchain.surface_resolution);
|
||||
let scissor = self.swapchain.surface_resolution.into();
|
||||
|
||||
unsafe { self.device.handle.cmd_set_scissor(command_buffer, 0, &[scissor]) }
|
||||
|
||||
|
@ -196,8 +200,9 @@ impl VkRenderContext {
|
|||
}
|
||||
|
||||
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)?;
|
||||
match Arc::get_mut(&mut self.swapchain) {
|
||||
Some(swapchain) => swapchain.update_resolution(width, height)?,
|
||||
None => log::warn!("Impossible to get mutable swapchain"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -206,4 +211,19 @@ impl VkRenderContext {
|
|||
pub fn exit(&self) {
|
||||
unsafe { self.device.handle.device_wait_idle().unwrap() }
|
||||
}
|
||||
|
||||
fn update_swapchain(&mut self) -> anyhow::Result<()> {
|
||||
match Arc::get_mut(&mut self.swapchain) {
|
||||
Some(swapchain) => {
|
||||
swapchain.create_swapchain()?;
|
||||
|
||||
self.framebuffers = self.swapchain
|
||||
.create_framebuffers(&self.render_pass)
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to get framebuffers"))?;
|
||||
}
|
||||
None => log::warn!("Impossible to get mutable swapchain"),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ use std::sync::Arc;
|
|||
|
||||
pub struct VkRenderPass {
|
||||
device: Arc<VkDevice>,
|
||||
swapchain: Arc<VkSwapchain>,
|
||||
|
||||
pub(super) handle: vk::RenderPass,
|
||||
}
|
||||
|
@ -42,7 +41,6 @@ impl VkRenderPass {
|
|||
|
||||
Ok(Self {
|
||||
device: device.clone(),
|
||||
swapchain: swapchain.clone(),
|
||||
handle: render_pass,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ pub struct SwapchainSupportDetails(
|
|||
|
||||
pub struct VkSurface {
|
||||
instance: Arc<VkInstance>,
|
||||
|
||||
pub(super) surface: vk::SurfaceKHR,
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ pub struct VkSwapchain {
|
|||
pub(super) desired_image_count: u32,
|
||||
pub(super) surface_format: vk::SurfaceFormatKHR,
|
||||
pub(super) surface_resolution: vk::Extent2D,
|
||||
pub(super) new_requested_surface_resolution: Option<vk::Extent2D>,
|
||||
pub(super) present_mode: vk::PresentModeKHR,
|
||||
pub(super) pre_transform: vk::SurfaceTransformFlagsKHR,
|
||||
|
||||
|
@ -64,6 +65,7 @@ impl VkSwapchain {
|
|||
device: device.clone(),
|
||||
|
||||
swapchain: None,
|
||||
new_requested_surface_resolution: None,
|
||||
swapchain_support_details,
|
||||
desired_image_count,
|
||||
surface_format,
|
||||
|
@ -80,6 +82,11 @@ impl VkSwapchain {
|
|||
}
|
||||
|
||||
pub(super) fn create_swapchain(&mut self) -> VkResult<()> {
|
||||
if let Some(new_requested_surface_resolution) = self.new_requested_surface_resolution {
|
||||
self.surface_resolution = new_requested_surface_resolution;
|
||||
self.new_requested_surface_resolution = None;
|
||||
}
|
||||
|
||||
let mut swapchain_create_info = self.create_swapchain_info(&self.surface);
|
||||
|
||||
if let Some(old_swapchain) = self.swapchain {
|
||||
|
@ -154,14 +161,12 @@ impl VkSwapchain {
|
|||
if chosen_extent.width != self.surface_resolution.width
|
||||
|| chosen_extent.height != self.surface_resolution.height
|
||||
{
|
||||
self.surface_resolution = chosen_extent;
|
||||
self.new_requested_surface_resolution = Some(chosen_extent);
|
||||
log::debug!(
|
||||
"New resolution applied ({}x{})",
|
||||
"New resolution submitted ({}x{})",
|
||||
chosen_extent.width,
|
||||
chosen_extent.height
|
||||
);
|
||||
|
||||
self.create_swapchain()?;
|
||||
} else {
|
||||
log::debug!("New resolution skipped ({width}x{height}) : Same resolution");
|
||||
}
|
||||
|
@ -180,6 +185,10 @@ impl VkSwapchain {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn is_dirty(&self) -> bool {
|
||||
self.new_requested_surface_resolution.is_some()
|
||||
}
|
||||
|
||||
fn create_swapchain_info(&self, surface: &VkSurface) -> vk::SwapchainCreateInfoKHR {
|
||||
vk::SwapchainCreateInfoKHR::default()
|
||||
.surface(surface.surface)
|
||||
|
|
Loading…
Reference in a new issue