vk: fix validation errors for hello triangle

This commit is contained in:
chyyran 2023-01-10 19:35:36 -05:00
parent f8ba964b01
commit 5154ff620a
4 changed files with 126 additions and 71 deletions

View file

@ -4,7 +4,7 @@ use ash::vk;
use ash::vk::{DebugUtilsMessengerEXT, PFN_vkDebugUtilsMessengerCallbackEXT}; use ash::vk::{DebugUtilsMessengerEXT, PFN_vkDebugUtilsMessengerCallbackEXT};
pub struct VulkanDebug { pub struct VulkanDebug {
loader: DebugUtils, pub loader: DebugUtils,
messenger: DebugUtilsMessengerEXT, messenger: DebugUtilsMessengerEXT,
} }

View file

@ -8,6 +8,7 @@ mod swapchain;
mod syncobjects; mod syncobjects;
pub mod vulkan_base; pub mod vulkan_base;
use std::ffi::CString;
use crate::filter_chain::{FilterChainVulkan, Vulkan}; use crate::filter_chain::{FilterChainVulkan, Vulkan};
use crate::hello_triangle::command::VulkanCommandPool; use crate::hello_triangle::command::VulkanCommandPool;
use crate::hello_triangle::framebuffer::VulkanFramebuffer; use crate::hello_triangle::framebuffer::VulkanFramebuffer;
@ -18,7 +19,7 @@ use crate::hello_triangle::syncobjects::SyncObjects;
use crate::hello_triangle::vulkan_base::VulkanBase; use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::util; use crate::util;
use ash::vk; use ash::vk;
use ash::vk::RenderingInfo; use ash::vk::{Handle, RenderingInfo};
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}; use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder}; use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
use winit::platform::windows::EventLoopBuilderExtWindows; use winit::platform::windows::EventLoopBuilderExtWindows;
@ -95,18 +96,6 @@ impl VulkanWindow {
.clear_values(&clear_values) .clear_values(&clear_values)
.build(); .build();
vulkan
.base
.device
.reset_command_buffer(cmd, vk::CommandBufferResetFlags::empty())
.expect("could not reset command buffer");
vulkan
.base
.device
.begin_command_buffer(cmd, &vk::CommandBufferBeginInfo::default())
.expect("failed to begin command buffer");
vulkan.base.device.cmd_begin_render_pass( vulkan.base.device.cmd_begin_render_pass(
cmd, cmd,
&render_pass_begin, &render_pass_begin,
@ -172,9 +161,52 @@ impl VulkanWindow {
let framebuffer_image = vulkan.swapchain.render_images[swapchain_index as usize].0; let framebuffer_image = vulkan.swapchain.render_images[swapchain_index as usize].0;
let swapchain_image = vulkan.swapchain.swapchain_images[swapchain_index as usize]; let swapchain_image = vulkan.swapchain.swapchain_images[swapchain_index as usize];
vulkan
.base
.device
.reset_command_buffer(cmd, vk::CommandBufferResetFlags::empty())
.expect("could not reset command buffer");
vulkan
.base
.device
.begin_command_buffer(cmd, &vk::CommandBufferBeginInfo::default())
.expect("failed to begin command buffer");
// util::vulkan_image_layout_transition_levels(
// &vulkan.base.device,
// cmd,
// framebuffer_image,
// 1,
// vk::ImageLayout::UNDEFINED,
// vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
// vk::AccessFlags::empty(),
// vk::AccessFlags::SHADER_READ,
// vk::PipelineStageFlags::ALL_GRAPHICS,
// vk::PipelineStageFlags::VERTEX_SHADER,
// vk::QUEUE_FAMILY_IGNORED,
// vk::QUEUE_FAMILY_IGNORED
// );
Self::record_command_buffer(vulkan, framebuffer, cmd); Self::record_command_buffer(vulkan, framebuffer, cmd);
filter.frame(0, &vk::Viewport { // util::vulkan_image_layout_transition_levels(
// &vulkan.base.device,
// cmd,
// framebuffer_image,
// 1,
// vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
// vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
// vk::AccessFlags::empty(),
// vk::AccessFlags::SHADER_READ,
// vk::PipelineStageFlags::ALL_GRAPHICS,
// vk::PipelineStageFlags::VERTEX_SHADER,
// vk::QUEUE_FAMILY_IGNORED,
// vk::QUEUE_FAMILY_IGNORED
// );
let intermediates = filter.frame(0, &vk::Viewport {
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
width: vulkan.swapchain.extent.width as f32, width: vulkan.swapchain.extent.width as f32,
@ -188,16 +220,18 @@ impl VulkanWindow {
}, cmd, None) }, cmd, None)
.unwrap(); .unwrap();
eprintln!("{:x}", framebuffer_image.as_raw());
// todo: output image will remove need for ImageLayout::GENERAL
util::vulkan_image_layout_transition_levels( util::vulkan_image_layout_transition_levels(
&vulkan.base.device, &vulkan.base.device,
cmd, cmd,
framebuffer_image, framebuffer_image,
1, 1,
vk::ImageLayout::UNDEFINED, vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
vk::ImageLayout::TRANSFER_SRC_OPTIMAL, vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
vk::AccessFlags::COLOR_ATTACHMENT_WRITE, vk::AccessFlags::SHADER_READ,
vk::AccessFlags::TRANSFER_READ, vk::AccessFlags::TRANSFER_READ,
vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT, vk::PipelineStageFlags::VERTEX_SHADER,
vk::PipelineStageFlags::TRANSFER, vk::PipelineStageFlags::TRANSFER,
vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED,
vk::QUEUE_FAMILY_IGNORED, vk::QUEUE_FAMILY_IGNORED,
@ -245,7 +279,7 @@ impl VulkanWindow {
cmd, cmd,
swapchain_image, swapchain_image,
1, 1,
vk::ImageLayout::UNDEFINED, vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::ImageLayout::PRESENT_SRC_KHR, vk::ImageLayout::PRESENT_SRC_KHR,
vk::AccessFlags::empty(), vk::AccessFlags::empty(),
vk::AccessFlags::TRANSFER_READ, vk::AccessFlags::TRANSFER_READ,
@ -289,6 +323,8 @@ impl VulkanWindow {
.loader .loader
.queue_present(vulkan.base.graphics_queue, &present_info) .queue_present(vulkan.base.graphics_queue, &present_info)
.unwrap(); .unwrap();
drop(intermediates)
} }
} }
} }
@ -313,7 +349,6 @@ pub struct VulkanDraw {
base: VulkanBase, base: VulkanBase,
pub swapchain: VulkanSwapchain, pub swapchain: VulkanSwapchain,
pub pipeline: VulkanPipeline, pub pipeline: VulkanPipeline,
pub swapchain_framebuffers: Vec<VulkanFramebuffer>,
pub swapchain_command_pool: VulkanCommandPool, pub swapchain_command_pool: VulkanCommandPool,
pub render_command_pool: VulkanCommandPool, pub render_command_pool: VulkanCommandPool,
pub render_framebuffers: Vec<VulkanFramebuffer>, pub render_framebuffers: Vec<VulkanFramebuffer>,
@ -333,22 +368,8 @@ pub fn main(vulkan: VulkanBase, filter_chain: FilterChainVulkan) {
let pipeline = unsafe { VulkanPipeline::new(&vulkan, &swapchain) }.unwrap(); let pipeline = unsafe { VulkanPipeline::new(&vulkan, &swapchain) }.unwrap();
let mut swapchain_framebuffers = vec![];
for image in &swapchain.swapchain_image_views {
swapchain_framebuffers.push(
VulkanFramebuffer::new(
&vulkan.device,
image,
&pipeline.renderpass,
WINDOW_WIDTH,
WINDOW_HEIGHT,
)
.unwrap(),
)
}
let mut render_framebuffers = vec![]; let mut render_framebuffers = vec![];
for image in &swapchain.render_image_views { for (index, image) in swapchain.render_image_views.iter().enumerate() {
render_framebuffers.push( render_framebuffers.push(
VulkanFramebuffer::new( VulkanFramebuffer::new(
&vulkan.device, &vulkan.device,
@ -371,7 +392,6 @@ pub fn main(vulkan: VulkanBase, filter_chain: FilterChainVulkan) {
swapchain, swapchain,
base: vulkan, base: vulkan,
pipeline, pipeline,
swapchain_framebuffers,
swapchain_command_pool, swapchain_command_pool,
sync, sync,
render_command_pool, render_command_pool,

View file

@ -248,7 +248,8 @@ impl VulkanPipeline {
samples: vk::SampleCountFlags::TYPE_1, samples: vk::SampleCountFlags::TYPE_1,
load_op: vk::AttachmentLoadOp::CLEAR, load_op: vk::AttachmentLoadOp::CLEAR,
store_op: vk::AttachmentStoreOp::STORE, store_op: vk::AttachmentStoreOp::STORE,
final_layout: vk::ImageLayout::PRESENT_SRC_KHR, initial_layout: vk::ImageLayout::UNDEFINED,
final_layout: vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
..Default::default() ..Default::default()
}]; }];
let color_attachment_refs = [vk::AttachmentReference { let color_attachment_refs = [vk::AttachmentReference {

View file

@ -1,10 +1,11 @@
use std::ffi::CStr;
use crate::hello_triangle::surface::VulkanSurface; use crate::hello_triangle::surface::VulkanSurface;
use crate::hello_triangle::vulkan_base::VulkanBase; use crate::hello_triangle::vulkan_base::VulkanBase;
use crate::util::find_vulkan_memory_type; use crate::util::find_vulkan_memory_type;
use crate::vulkan_primitives::VulkanImageMemory; use crate::vulkan_primitives::VulkanImageMemory;
use ash::prelude::VkResult; use ash::prelude::VkResult;
use ash::vk; use ash::vk;
use ash::vk::Extent3D; use ash::vk::{Extent3D, Handle};
pub struct VulkanSwapchain { pub struct VulkanSwapchain {
pub swapchain: vk::SwapchainKHR, pub swapchain: vk::SwapchainKHR,
@ -15,7 +16,6 @@ pub struct VulkanSwapchain {
pub swapchain_images: Vec<vk::Image>, pub swapchain_images: Vec<vk::Image>,
pub render_images: Vec<(vk::Image, VulkanImageMemory)>, pub render_images: Vec<(vk::Image, VulkanImageMemory)>,
pub swapchain_image_views: Vec<vk::ImageView>,
pub render_image_views: Vec<vk::ImageView>, pub render_image_views: Vec<vk::ImageView>,
device: ash::Device, device: ash::Device,
} }
@ -67,6 +67,7 @@ impl VulkanSwapchain {
let mut render_images = vec![]; let mut render_images = vec![];
// create render imaghes
for _ in 0..swapchain_images.len() { for _ in 0..swapchain_images.len() {
let create_info = vk::ImageCreateInfo::builder() let create_info = vk::ImageCreateInfo::builder()
.extent(Extent3D { .extent(Extent3D {
@ -81,14 +82,21 @@ impl VulkanSwapchain {
.tiling(vk::ImageTiling::OPTIMAL) .tiling(vk::ImageTiling::OPTIMAL)
.array_layers(1) .array_layers(1)
.mip_levels(1) .mip_levels(1)
.usage(vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::COLOR_ATTACHMENT) .usage(vk::ImageUsageFlags::SAMPLED | vk::ImageUsageFlags::COLOR_ATTACHMENT | vk::ImageUsageFlags::TRANSFER_SRC)
.initial_layout(vk::ImageLayout::UNDEFINED); .initial_layout(vk::ImageLayout::UNDEFINED);
unsafe { unsafe {
let image = base.device.create_image(&create_info, None)?; let image = base.device.create_image(&create_info, None)?;
let mem_reqs = unsafe { base.device.get_image_memory_requirements(image.clone()) }; let mem_reqs = unsafe { base.device.get_image_memory_requirements(image.clone()) };
base.debug.loader.set_debug_utils_object_name(base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(image.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImage\0"))
.object_type(vk::ObjectType::IMAGE)
.build())
.expect("could not set object name");
let alloc_info = vk::MemoryAllocateInfo::builder() let alloc_info = vk::MemoryAllocateInfo::builder()
.allocation_size(mem_reqs.size) .allocation_size(mem_reqs.size)
.memory_type_index(find_vulkan_memory_type( .memory_type_index(find_vulkan_memory_type(
@ -106,33 +114,48 @@ impl VulkanSwapchain {
} }
} }
let image_views: VkResult<Vec<vk::ImageView>> = swapchain_images // let image_views: VkResult<Vec<vk::ImageView>> = swapchain_images
.iter() // .iter()
.map(|image| { // .map(|image| {
let create_info = vk::ImageViewCreateInfo::builder() // let create_info = vk::ImageViewCreateInfo::builder()
.view_type(vk::ImageViewType::TYPE_2D) // .view_type(vk::ImageViewType::TYPE_2D)
.format(format.format) // .format(format.format)
.components(vk::ComponentMapping { // .components(vk::ComponentMapping {
r: vk::ComponentSwizzle::IDENTITY, // r: vk::ComponentSwizzle::IDENTITY,
g: vk::ComponentSwizzle::IDENTITY, // g: vk::ComponentSwizzle::IDENTITY,
b: vk::ComponentSwizzle::IDENTITY, // b: vk::ComponentSwizzle::IDENTITY,
a: vk::ComponentSwizzle::IDENTITY, // a: vk::ComponentSwizzle::IDENTITY,
}) // })
.subresource_range(vk::ImageSubresourceRange { // .subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR, // aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0, // base_mip_level: 0,
level_count: 1, // level_count: 1,
base_array_layer: 0, // base_array_layer: 0,
layer_count: 1, // layer_count: 1,
}) // })
.image(*image) // .image(*image)
.build(); // .build();
//
let view = unsafe { base.device.create_image_view(&create_info, None)? }; // let view = unsafe { base.device.create_image_view(&create_info, None)? };
// unsafe {
Ok(view) // base.debug.loader.set_debug_utils_object_name(base.device.handle(),
}) // &vk::DebugUtilsObjectNameInfoEXT::builder()
.collect(); // .object_handle(image.as_raw())
// .object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImage\0"))
// .object_type(vk::ObjectType::IMAGE)
// .build())
// .expect("could not set object name");
// base.debug.loader.set_debug_utils_object_name(base.device.handle(),
// &vk::DebugUtilsObjectNameInfoEXT::builder()
// .object_handle(view.as_raw())
// .object_name(CStr::from_bytes_with_nul_unchecked(b"SwapchainImageView\0"))
// .object_type(vk::ObjectType::IMAGE_VIEW)
// .build())
// .expect("could not set object name");
// }
// Ok(view)
// })
// .collect();
let render_image_views: VkResult<Vec<vk::ImageView>> = render_images let render_image_views: VkResult<Vec<vk::ImageView>> = render_images
.iter() .iter()
@ -157,7 +180,15 @@ impl VulkanSwapchain {
.build(); .build();
let view = unsafe { base.device.create_image_view(&create_info, None)? }; let view = unsafe { base.device.create_image_view(&create_info, None)? };
unsafe {
base.debug.loader.set_debug_utils_object_name(base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(view.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImageView\0"))
.object_type(vk::ObjectType::IMAGE_VIEW)
.build())
.expect("could not set object name");
}
Ok(view) Ok(view)
}) })
.collect(); .collect();
@ -169,7 +200,7 @@ impl VulkanSwapchain {
mode, mode,
swapchain_images, swapchain_images,
render_images, render_images,
swapchain_image_views: image_views?, // swapchain_image_views: image_views?,
render_image_views: render_image_views?, render_image_views: render_image_views?,
device: base.device.clone(), device: base.device.clone(),
}) })
@ -179,9 +210,12 @@ impl VulkanSwapchain {
impl Drop for VulkanSwapchain { impl Drop for VulkanSwapchain {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
for view in &self.swapchain_image_views { for view in &self.render_image_views {
self.device.destroy_image_view(*view, None) self.device.destroy_image_view(*view, None)
} }
for (view, memory) in &self.render_images {
self.device.destroy_image(*view, None);
}
self.loader.destroy_swapchain(self.swapchain, None) self.loader.destroy_swapchain(self.swapchain, None)
} }
} }