From e39d8e9a65ec90b4437ebf84d48583d650143029 Mon Sep 17 00:00:00 2001 From: chyyran Date: Fri, 13 Jan 2023 00:07:03 -0500 Subject: [PATCH] vk: fix lifetime of array references after building vulkan info struct --- librashader-runtime-vk/src/filter_chain.rs | 15 ++- .../src/hello_triangle/debug.rs | 1 + .../src/hello_triangle/mod.rs | 44 +++---- .../src/hello_triangle/pipeline.rs | 8 +- .../src/hello_triangle/swapchain.rs | 108 +++++++++--------- .../src/hello_triangle/vulkan_base.rs | 86 +++++++------- librashader-runtime-vk/src/lib.rs | 2 + librashader-runtime-vk/src/ubo_ring.rs | 15 +-- .../src/vulkan_primitives.rs | 3 + librashader-runtime-vk/src/vulkan_state.rs | 38 +++--- 10 files changed, 172 insertions(+), 148 deletions(-) diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index 78cb04a..68edc6f 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -41,7 +41,7 @@ pub struct Vulkan { command_pool: vk::CommandPool, pipeline_cache: vk::PipelineCache, pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties, - debug: DebugUtils, + // debug: DebugUtils, } type ShaderPassMeta = ( @@ -102,7 +102,7 @@ impl TryFrom> for Vulkan { command_pool, pipeline_cache, memory_properties: vulkan.memory_properties.clone(), - debug, + // debug, }) } } @@ -148,7 +148,7 @@ impl command_pool, pipeline_cache, memory_properties: value.2, - debug: value.3, + // debug: value.3, }) } } @@ -273,7 +273,6 @@ impl FilterChainVulkan { let mut feedback_textures = Vec::new(); feedback_textures.resize_with(filters.len(), || None); - eprintln!("filters initialized ok."); Ok(FilterChainVulkan { common: FilterCommon { luts, @@ -311,7 +310,7 @@ impl FilterChainVulkan { let passes = passes .into_iter() .map(|shader| { - eprintln!("[vk] loading {}", &shader.name.display()); + // eprintln!("[vk] loading {}", &shader.name.display()); let source: ShaderSource = ShaderSource::load(&shader.name)?; let spirv = GlslangCompilation::compile(&source)?; @@ -505,13 +504,13 @@ impl FilterChainVulkan { // not using frame history; if required_images <= 1 { - println!("[history] not using frame history"); + // println!("[history] not using frame history"); return Ok((VecDeque::new(), Box::new([]))); } // history0 is aliased with the original - eprintln!("[history] using frame history with {required_images} images"); + // eprintln!("[history] using frame history with {required_images} images"); let mut images = Vec::with_capacity(required_images); images.resize_with(required_images, || { OwnedImage::new(&vulkan, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1) @@ -537,7 +536,7 @@ impl FilterChainVulkan { if back.image.size != input.size || (input.format != vk::Format::UNDEFINED && input.format != back.image.format) { - eprintln!("[history] resizing"); + // eprintln!("[history] resizing"); // old back will get dropped.. do we need to defer? let old_back = std::mem::replace( &mut back, diff --git a/librashader-runtime-vk/src/hello_triangle/debug.rs b/librashader-runtime-vk/src/hello_triangle/debug.rs index 088af2e..b491ea6 100644 --- a/librashader-runtime-vk/src/hello_triangle/debug.rs +++ b/librashader-runtime-vk/src/hello_triangle/debug.rs @@ -29,6 +29,7 @@ impl VulkanDebug { let debug_utils_loader = DebugUtils::new(entry, instance); + dbg!("got to dbg"); unsafe { let debug_call_back = debug_utils_loader.create_debug_utils_messenger(&debug_info, None)?; diff --git a/librashader-runtime-vk/src/hello_triangle/mod.rs b/librashader-runtime-vk/src/hello_triangle/mod.rs index e20a5ef..dcb8b9b 100644 --- a/librashader-runtime-vk/src/hello_triangle/mod.rs +++ b/librashader-runtime-vk/src/hello_triangle/mod.rs @@ -139,20 +139,20 @@ impl VulkanWindow { fn draw_frame(frame: usize, vulkan: &VulkanDraw, filter: &mut FilterChainVulkan) { let index = frame % MAX_FRAMES_IN_FLIGHT; - let in_flight = vulkan.sync.in_flight[index]; - let image_available = vulkan.sync.image_available[index]; - let render_finished = vulkan.sync.render_finished[index]; + let in_flight = [vulkan.sync.in_flight[index]]; + let image_available = [vulkan.sync.image_available[index]]; + let render_finished = [vulkan.sync.render_finished[index]]; unsafe { vulkan .base .device - .wait_for_fences(&[in_flight], true, u64::MAX) + .wait_for_fences(&in_flight, true, u64::MAX) .unwrap(); vulkan .base .device - .reset_fences(&[in_flight]) + .reset_fences(&in_flight) .unwrap(); let (swapchain_index, _) = vulkan @@ -161,7 +161,7 @@ impl VulkanWindow { .acquire_next_image( vulkan.swapchain.swapchain, u64::MAX, - image_available, + image_available[0], vk::Fence::null(), ) .unwrap(); @@ -314,27 +314,31 @@ impl VulkanWindow { .end_command_buffer(cmd) .expect("failed to record commandbuffer"); - let submit_info = vk::SubmitInfo::builder() - .wait_dst_stage_mask(&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]) - .wait_semaphores(&[image_available]) - .signal_semaphores(&[render_finished]) - .command_buffers(&[cmd]) - .build(); + let stage_mask = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]; + let cmd = [cmd]; + let submit_info = [vk::SubmitInfo::builder() + .wait_dst_stage_mask(&stage_mask) + .wait_semaphores(&image_available) + .signal_semaphores(&render_finished) + .command_buffers(&cmd) + .build()]; vulkan .base .device .queue_submit( vulkan.base.graphics_queue, - &[submit_info], - in_flight, + &submit_info, + in_flight[0], ) .expect("failed to submit queue"); + let swapchain_index = [swapchain_index]; + let swapchain = [vulkan.swapchain.swapchain]; let present_info = vk::PresentInfoKHR::builder() - .wait_semaphores(&[render_finished]) - .swapchains(&[vulkan.swapchain.swapchain]) - .image_indices(&[swapchain_index]) + .wait_semaphores(&render_finished) + .swapchains(&swapchain) + .image_indices(&swapchain_index) .build(); vulkan @@ -344,9 +348,9 @@ impl VulkanWindow { .unwrap(); //oops i pooped my pants - std::mem::forget(intermediates); - // vulkan.base.device.device_wait_idle().unwrap(); - // drop(intermediates) + // std::mem::forget(intermediates); + vulkan.base.device.device_wait_idle().unwrap(); + drop(intermediates) } } } diff --git a/librashader-runtime-vk/src/hello_triangle/pipeline.rs b/librashader-runtime-vk/src/hello_triangle/pipeline.rs index 5538144..25ec3c5 100644 --- a/librashader-runtime-vk/src/hello_triangle/pipeline.rs +++ b/librashader-runtime-vk/src/hello_triangle/pipeline.rs @@ -9,6 +9,7 @@ use bytemuck::offset_of; use std::ffi::CStr; use std::io::Cursor; use std::mem::align_of; +const ENTRY_POINT: &'static CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") } ; #[derive(Default, Clone, Debug, Copy)] struct Vertex { @@ -150,7 +151,7 @@ impl VulkanPipeline { let vertex_stage_info = vk::PipelineShaderStageCreateInfo::builder() .module(vertex_shader_info.module) .stage(vk::ShaderStageFlags::VERTEX) - .name(CStr::from_bytes_with_nul_unchecked(b"main\0")) + .name(ENTRY_POINT) .build(); let mut frag_spv_file = @@ -161,7 +162,7 @@ impl VulkanPipeline { let frag_stage_info = vk::PipelineShaderStageCreateInfo::builder() .module(frag_shader_info.module) .stage(vk::ShaderStageFlags::FRAGMENT) - .name(CStr::from_bytes_with_nul_unchecked(b"main\0")) + .name(ENTRY_POINT) .build(); let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo::builder() @@ -194,8 +195,9 @@ impl VulkanPipeline { .create_pipeline_layout(&layout_create_info, None) .unwrap(); + let states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder() - .dynamic_states(&[vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]) + .dynamic_states(&states) .build(); let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder() diff --git a/librashader-runtime-vk/src/hello_triangle/swapchain.rs b/librashader-runtime-vk/src/hello_triangle/swapchain.rs index f1f1ee3..d816a62 100644 --- a/librashader-runtime-vk/src/hello_triangle/swapchain.rs +++ b/librashader-runtime-vk/src/hello_triangle/swapchain.rs @@ -94,17 +94,17 @@ impl VulkanSwapchain { let image = base.device.create_image(&create_info, None)?; 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"); + // 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() .allocation_size(mem_reqs.size) @@ -146,34 +146,34 @@ impl VulkanSwapchain { .build(); 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(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"); - } + // unsafe { + // 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"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(); @@ -201,21 +201,21 @@ impl VulkanSwapchain { .build(); 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"); - } + // 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) }) .collect(); diff --git a/librashader-runtime-vk/src/hello_triangle/vulkan_base.rs b/librashader-runtime-vk/src/hello_triangle/vulkan_base.rs index 1057cee..04d5331 100644 --- a/librashader-runtime-vk/src/hello_triangle/vulkan_base.rs +++ b/librashader-runtime-vk/src/hello_triangle/vulkan_base.rs @@ -9,7 +9,8 @@ use crate::hello_triangle::surface::VulkanSurface; use ash::prelude::VkResult; use std::ffi::{CStr, CString}; -const WINDOW_TITLE: &'static str = "librashader Vulkan"; +const WINDOW_TITLE: &'static [u8] = b"librashader Vulkan\0"; +const KHRONOS_VALIDATION: &'static [u8] = b"VK_LAYER_KHRONOS_validation\0"; pub struct VulkanBase { pub entry: ash::Entry, @@ -23,17 +24,15 @@ pub struct VulkanBase { impl VulkanBase { pub fn new(entry: ash::Entry) -> VkResult { - let app_name = CString::new(WINDOW_TITLE).unwrap(); - let engine_name = CString::new("librashader").unwrap(); - let app_info = vk::ApplicationInfo::builder() - .application_name(&app_name) - .engine_name(&engine_name) + .application_name(unsafe { &CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) }) + .engine_name(unsafe { &CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) }) .engine_version(0) .application_version(0) .api_version(vk::make_api_version(0, 1, 3, 0)) .build(); + dbg!("entry"); // todo: make this xplat let extensions = [ ash::extensions::khr::Surface::name().as_ptr(), @@ -42,7 +41,7 @@ impl VulkanBase { ]; let layers = unsafe { - [CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0").as_ptr()] + [KHRONOS_VALIDATION.as_ptr().cast()] }; let create_info = vk::InstanceCreateInfo::builder() @@ -57,9 +56,12 @@ impl VulkanBase { let physical_device = pick_physical_device(&instance); + dbg!("picked physdev"); let (device, queue) = VulkanBase::create_device(&instance, &physical_device)?; + dbg!("created device"); let mem_props = unsafe { instance.get_physical_device_memory_properties(physical_device) }; + dbg!("got memprops"); Ok(VulkanBase { entry, @@ -76,15 +78,15 @@ impl VulkanBase { instance: &ash::Instance, physical_device: &vk::PhysicalDevice, ) -> VkResult<(ash::Device, vk::Queue)> { - let debug = unsafe { - CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0").as_ptr() - }; + let debug = [unsafe { + CStr::from_bytes_with_nul_unchecked(KHRONOS_VALIDATION).as_ptr() + }]; let indices = find_queue_family(&instance, *physical_device); - let queue_info = vk::DeviceQueueCreateInfo::builder() + let queue_info = [vk::DeviceQueueCreateInfo::builder() .queue_family_index(indices.graphics_family()) .queue_priorities(&[1.0f32]) - .build(); + .build()]; // let physical_device_features = vk::PhysicalDeviceFeatures::default(); @@ -96,13 +98,15 @@ impl VulkanBase { // vk::PhysicalDeviceFeatures2::builder().push_next(&mut physical_device_features) // .build(); + let extensions = [ + ash::extensions::khr::Swapchain::name().as_ptr(), + ash::extensions::khr::DynamicRendering::name().as_ptr(), + ]; + let device_create_info = vk::DeviceCreateInfo::builder() - .queue_create_infos(&[queue_info]) - .enabled_layer_names(&[debug]) - .enabled_extension_names(&[ - ash::extensions::khr::Swapchain::name().as_ptr(), - ash::extensions::khr::DynamicRendering::name().as_ptr(), - ]) + .queue_create_infos(&queue_info) + .enabled_layer_names(&debug) + .enabled_extension_names(&extensions) .push_next(&mut physical_device_features) // .enabled_features(&physical_device_features) .build(); @@ -122,29 +126,29 @@ unsafe extern "system" fn vulkan_debug_callback( p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT, _user_data: *mut std::os::raw::c_void, ) -> vk::Bool32 { - let callback_data = *p_callback_data; - let message_id_number: i32 = callback_data.message_id_number as i32; - - let message_id_name = if callback_data.p_message_id_name.is_null() { - Cow::from("") - } else { - CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy() - }; - - let message = if callback_data.p_message.is_null() { - Cow::from("") - } else { - CStr::from_ptr(callback_data.p_message).to_string_lossy() - }; - - println!( - "{:?}:\n{:?} [{} ({})] : {}\n", - message_severity, - message_type, - message_id_name, - &message_id_number.to_string(), - message, - ); + // let callback_data = *p_callback_data; + // let message_id_number: i32 = callback_data.message_id_number as i32; + // + // let message_id_name = if callback_data.p_message_id_name.is_null() { + // Cow::from("") + // } else { + // CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy() + // }; + // + // let message = if callback_data.p_message.is_null() { + // Cow::from("") + // } else { + // CStr::from_ptr(callback_data.p_message).to_string_lossy() + // }; + // + // println!( + // "{:?}:\n{:?} [{} ({})] : {}\n", + // message_severity, + // message_type, + // message_id_name, + // &message_id_number.to_string(), + // message, + // ); vk::FALSE } diff --git a/librashader-runtime-vk/src/lib.rs b/librashader-runtime-vk/src/lib.rs index e8a3386..1b3b0ed 100644 --- a/librashader-runtime-vk/src/lib.rs +++ b/librashader-runtime-vk/src/lib.rs @@ -28,10 +28,12 @@ mod tests { fn triangle_vk() { let entry = unsafe { ash::Entry::load().unwrap() }; let base = VulkanBase::new(entry).unwrap(); + dbg!("finished"); let mut filter = FilterChainVulkan::load_from_path( &base, // "../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", + // "../test/basic.slangp", None, ) .unwrap(); diff --git a/librashader-runtime-vk/src/ubo_ring.rs b/librashader-runtime-vk/src/ubo_ring.rs index e595d12..d84d6ef 100644 --- a/librashader-runtime-vk/src/ubo_ring.rs +++ b/librashader-runtime-vk/src/ubo_ring.rs @@ -38,29 +38,30 @@ impl VkUboRing { binding: u32, storage: &impl UniformStorageAccess, ) -> error::Result<()> { - let mut buffer = self.ring.current_mut(); // todo: write directly to allocated buffer. unsafe { + let mut buffer = self.ring.current_mut(); let mut map = buffer.map()?; map.copy_from(0, storage.ubo_slice()) } + let buffer = self.ring.current(); unsafe { - let buffer_info = vk::DescriptorBufferInfo::builder() + let buffer_info = [vk::DescriptorBufferInfo::builder() .buffer(buffer.handle) .offset(0) .range(storage.ubo_slice().len() as vk::DeviceSize) - .build(); + .build()]; - let write_info = vk::WriteDescriptorSet::builder() + let write_info = [vk::WriteDescriptorSet::builder() .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER) .dst_set(descriptor_set) .dst_binding(binding) .dst_array_element(0) - .buffer_info(&[buffer_info]) - .build(); + .buffer_info(&buffer_info) + .build()]; - self.device.update_descriptor_sets(&[write_info], &[]) + self.device.update_descriptor_sets(&write_info, &[]) } self.ring.next(); Ok(()) diff --git a/librashader-runtime-vk/src/vulkan_primitives.rs b/librashader-runtime-vk/src/vulkan_primitives.rs index 9386df2..35ed634 100644 --- a/librashader-runtime-vk/src/vulkan_primitives.rs +++ b/librashader-runtime-vk/src/vulkan_primitives.rs @@ -124,6 +124,9 @@ impl Drop for VulkanBuffer { impl<'a> VulkanBufferMapHandle<'a> { pub unsafe fn copy_from(&mut self, offset: usize, src: &[u8]) { + if self.buffer.size > (offset + src.len()) as u64 { + panic!("invalid write") + } std::ptr::copy_nonoverlapping( src.as_ptr(), self.ptr diff --git a/librashader-runtime-vk/src/vulkan_state.rs b/librashader-runtime-vk/src/vulkan_state.rs index 45a050d..b0945e7 100644 --- a/librashader-runtime-vk/src/vulkan_state.rs +++ b/librashader-runtime-vk/src/vulkan_state.rs @@ -6,6 +6,8 @@ use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection}; use librashader_reflect::reflect::ShaderReflection; use std::ffi::CStr; +const ENTRY_POINT: &'static CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") } ; + pub struct PipelineDescriptors { pub replicas: u32, pub layout_bindings: Vec, @@ -119,12 +121,14 @@ impl PipelineLayoutObjects { let layout = unsafe { device.create_pipeline_layout(&pipeline_create_info, None)? }; + let pool_info = vk::DescriptorPoolCreateInfo::builder() + .max_sets(replicas) + .pool_sizes(&descriptors.pool_sizes) + .build(); + let pool = unsafe { device.create_descriptor_pool( - &vk::DescriptorPoolCreateInfo::builder() - .max_sets(replicas) - .pool_sizes(&descriptors.pool_sizes) - .build(), + &pool_info, None, )? }; @@ -136,7 +140,8 @@ impl PipelineLayoutObjects { .build(); for _ in 0..replicas { - unsafe { descriptor_sets.push(device.allocate_descriptor_sets(&alloc_info)?) } + let set = unsafe { device.allocate_descriptor_sets(&alloc_info)? }; + descriptor_sets.push(set) } let descriptor_sets: Vec = @@ -209,14 +214,14 @@ impl VulkanGraphicsPipeline { }, ]; - let input_binding = vk::VertexInputBindingDescription::builder() + let input_binding = [vk::VertexInputBindingDescription::builder() .binding(0) .stride(4 * std::mem::size_of::() as u32) .input_rate(vk::VertexInputRate::VERTEX) - .build(); + .build()]; let pipeline_input_state = vk::PipelineVertexInputStateCreateInfo::builder() - .vertex_binding_descriptions(&[input_binding]) + .vertex_binding_descriptions(&input_binding) .vertex_attribute_descriptions(&vao_state) .build(); @@ -230,11 +235,13 @@ impl VulkanGraphicsPipeline { .line_width(1.0) .build(); + let attachments = [vk::PipelineColorBlendAttachmentState::builder() + .blend_enable(false) + .color_write_mask(vk::ColorComponentFlags::from_raw(0xf)) + .build()]; + let blend_state = vk::PipelineColorBlendStateCreateInfo::builder() - .attachments(&[vk::PipelineColorBlendAttachmentState::builder() - .blend_enable(false) - .color_write_mask(vk::ColorComponentFlags::from_raw(0xf)) - .build()]) + .attachments(&attachments) .build(); let viewport_state = vk::PipelineViewportStateCreateInfo::builder() @@ -255,8 +262,9 @@ impl VulkanGraphicsPipeline { .rasterization_samples(vk::SampleCountFlags::TYPE_1) .build(); + let states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]; let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder() - .dynamic_states(&[vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]) + .dynamic_states(&states) .build(); let vertex_info = vk::ShaderModuleCreateInfo::builder() @@ -272,12 +280,12 @@ impl VulkanGraphicsPipeline { let shader_stages = [ vk::PipelineShaderStageCreateInfo::builder() .stage(vk::ShaderStageFlags::VERTEX) - .name(unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") }) + .name(&ENTRY_POINT) .module(vertex_module.shader.clone()) .build(), vk::PipelineShaderStageCreateInfo::builder() .stage(vk::ShaderStageFlags::FRAGMENT) - .name(unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") }) + .name(&ENTRY_POINT) .module(fragment_module.shader.clone()) .build(), ];