vk: fix lifetime of array references after building vulkan info struct

This commit is contained in:
chyyran 2023-01-13 00:07:03 -05:00
parent 98bfb77232
commit e39d8e9a65
10 changed files with 172 additions and 148 deletions

View file

@ -41,7 +41,7 @@ pub struct Vulkan {
command_pool: vk::CommandPool, command_pool: vk::CommandPool,
pipeline_cache: vk::PipelineCache, pipeline_cache: vk::PipelineCache,
pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties, pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
debug: DebugUtils, // debug: DebugUtils,
} }
type ShaderPassMeta = ( type ShaderPassMeta = (
@ -102,7 +102,7 @@ impl TryFrom<VulkanInfo<'_>> for Vulkan {
command_pool, command_pool,
pipeline_cache, pipeline_cache,
memory_properties: vulkan.memory_properties.clone(), memory_properties: vulkan.memory_properties.clone(),
debug, // debug,
}) })
} }
} }
@ -148,7 +148,7 @@ impl
command_pool, command_pool,
pipeline_cache, pipeline_cache,
memory_properties: value.2, memory_properties: value.2,
debug: value.3, // debug: value.3,
}) })
} }
} }
@ -273,7 +273,6 @@ impl FilterChainVulkan {
let mut feedback_textures = Vec::new(); let mut feedback_textures = Vec::new();
feedback_textures.resize_with(filters.len(), || None); feedback_textures.resize_with(filters.len(), || None);
eprintln!("filters initialized ok.");
Ok(FilterChainVulkan { Ok(FilterChainVulkan {
common: FilterCommon { common: FilterCommon {
luts, luts,
@ -311,7 +310,7 @@ impl FilterChainVulkan {
let passes = passes let passes = passes
.into_iter() .into_iter()
.map(|shader| { .map(|shader| {
eprintln!("[vk] loading {}", &shader.name.display()); // eprintln!("[vk] loading {}", &shader.name.display());
let source: ShaderSource = ShaderSource::load(&shader.name)?; let source: ShaderSource = ShaderSource::load(&shader.name)?;
let spirv = GlslangCompilation::compile(&source)?; let spirv = GlslangCompilation::compile(&source)?;
@ -505,13 +504,13 @@ impl FilterChainVulkan {
// not using frame history; // not using frame history;
if required_images <= 1 { if required_images <= 1 {
println!("[history] not using frame history"); // println!("[history] not using frame history");
return Ok((VecDeque::new(), Box::new([]))); return Ok((VecDeque::new(), Box::new([])));
} }
// history0 is aliased with the original // 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); let mut images = Vec::with_capacity(required_images);
images.resize_with(required_images, || { images.resize_with(required_images, || {
OwnedImage::new(&vulkan, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1) OwnedImage::new(&vulkan, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, 1)
@ -537,7 +536,7 @@ impl FilterChainVulkan {
if back.image.size != input.size if back.image.size != input.size
|| (input.format != vk::Format::UNDEFINED && input.format != back.image.format) || (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? // old back will get dropped.. do we need to defer?
let old_back = std::mem::replace( let old_back = std::mem::replace(
&mut back, &mut back,

View file

@ -29,6 +29,7 @@ impl VulkanDebug {
let debug_utils_loader = DebugUtils::new(entry, instance); let debug_utils_loader = DebugUtils::new(entry, instance);
dbg!("got to dbg");
unsafe { unsafe {
let debug_call_back = let debug_call_back =
debug_utils_loader.create_debug_utils_messenger(&debug_info, None)?; debug_utils_loader.create_debug_utils_messenger(&debug_info, None)?;

View file

@ -139,20 +139,20 @@ impl VulkanWindow {
fn draw_frame(frame: usize, vulkan: &VulkanDraw, filter: &mut FilterChainVulkan) { fn draw_frame(frame: usize, vulkan: &VulkanDraw, filter: &mut FilterChainVulkan) {
let index = frame % MAX_FRAMES_IN_FLIGHT; let index = frame % MAX_FRAMES_IN_FLIGHT;
let in_flight = vulkan.sync.in_flight[index]; let in_flight = [vulkan.sync.in_flight[index]];
let image_available = vulkan.sync.image_available[index]; let image_available = [vulkan.sync.image_available[index]];
let render_finished = vulkan.sync.render_finished[index]; let render_finished = [vulkan.sync.render_finished[index]];
unsafe { unsafe {
vulkan vulkan
.base .base
.device .device
.wait_for_fences(&[in_flight], true, u64::MAX) .wait_for_fences(&in_flight, true, u64::MAX)
.unwrap(); .unwrap();
vulkan vulkan
.base .base
.device .device
.reset_fences(&[in_flight]) .reset_fences(&in_flight)
.unwrap(); .unwrap();
let (swapchain_index, _) = vulkan let (swapchain_index, _) = vulkan
@ -161,7 +161,7 @@ impl VulkanWindow {
.acquire_next_image( .acquire_next_image(
vulkan.swapchain.swapchain, vulkan.swapchain.swapchain,
u64::MAX, u64::MAX,
image_available, image_available[0],
vk::Fence::null(), vk::Fence::null(),
) )
.unwrap(); .unwrap();
@ -314,27 +314,31 @@ impl VulkanWindow {
.end_command_buffer(cmd) .end_command_buffer(cmd)
.expect("failed to record commandbuffer"); .expect("failed to record commandbuffer");
let submit_info = vk::SubmitInfo::builder() let stage_mask = [vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT];
.wait_dst_stage_mask(&[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT]) let cmd = [cmd];
.wait_semaphores(&[image_available]) let submit_info = [vk::SubmitInfo::builder()
.signal_semaphores(&[render_finished]) .wait_dst_stage_mask(&stage_mask)
.command_buffers(&[cmd]) .wait_semaphores(&image_available)
.build(); .signal_semaphores(&render_finished)
.command_buffers(&cmd)
.build()];
vulkan vulkan
.base .base
.device .device
.queue_submit( .queue_submit(
vulkan.base.graphics_queue, vulkan.base.graphics_queue,
&[submit_info], &submit_info,
in_flight, in_flight[0],
) )
.expect("failed to submit queue"); .expect("failed to submit queue");
let swapchain_index = [swapchain_index];
let swapchain = [vulkan.swapchain.swapchain];
let present_info = vk::PresentInfoKHR::builder() let present_info = vk::PresentInfoKHR::builder()
.wait_semaphores(&[render_finished]) .wait_semaphores(&render_finished)
.swapchains(&[vulkan.swapchain.swapchain]) .swapchains(&swapchain)
.image_indices(&[swapchain_index]) .image_indices(&swapchain_index)
.build(); .build();
vulkan vulkan
@ -344,9 +348,9 @@ impl VulkanWindow {
.unwrap(); .unwrap();
//oops i pooped my pants //oops i pooped my pants
std::mem::forget(intermediates); // std::mem::forget(intermediates);
// vulkan.base.device.device_wait_idle().unwrap(); vulkan.base.device.device_wait_idle().unwrap();
// drop(intermediates) drop(intermediates)
} }
} }
} }

View file

@ -9,6 +9,7 @@ use bytemuck::offset_of;
use std::ffi::CStr; use std::ffi::CStr;
use std::io::Cursor; use std::io::Cursor;
use std::mem::align_of; 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)] #[derive(Default, Clone, Debug, Copy)]
struct Vertex { struct Vertex {
@ -150,7 +151,7 @@ impl VulkanPipeline {
let vertex_stage_info = vk::PipelineShaderStageCreateInfo::builder() let vertex_stage_info = vk::PipelineShaderStageCreateInfo::builder()
.module(vertex_shader_info.module) .module(vertex_shader_info.module)
.stage(vk::ShaderStageFlags::VERTEX) .stage(vk::ShaderStageFlags::VERTEX)
.name(CStr::from_bytes_with_nul_unchecked(b"main\0")) .name(ENTRY_POINT)
.build(); .build();
let mut frag_spv_file = let mut frag_spv_file =
@ -161,7 +162,7 @@ impl VulkanPipeline {
let frag_stage_info = vk::PipelineShaderStageCreateInfo::builder() let frag_stage_info = vk::PipelineShaderStageCreateInfo::builder()
.module(frag_shader_info.module) .module(frag_shader_info.module)
.stage(vk::ShaderStageFlags::FRAGMENT) .stage(vk::ShaderStageFlags::FRAGMENT)
.name(CStr::from_bytes_with_nul_unchecked(b"main\0")) .name(ENTRY_POINT)
.build(); .build();
let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo::builder() let vertex_input_state_info = vk::PipelineVertexInputStateCreateInfo::builder()
@ -194,8 +195,9 @@ impl VulkanPipeline {
.create_pipeline_layout(&layout_create_info, None) .create_pipeline_layout(&layout_create_info, None)
.unwrap(); .unwrap();
let states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR];
let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder() let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder()
.dynamic_states(&[vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]) .dynamic_states(&states)
.build(); .build();
let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder() let viewport_state_info = vk::PipelineViewportStateCreateInfo::builder()

View file

@ -94,17 +94,17 @@ impl VulkanSwapchain {
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 // base.debug
.loader // .loader
.set_debug_utils_object_name( // .set_debug_utils_object_name(
base.device.handle(), // base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder() // &vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(image.as_raw()) // .object_handle(image.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImage\0")) // .object_name(CStr::from_bytes_with_nul_unchecked(b"RenderImage\0"))
.object_type(vk::ObjectType::IMAGE) // .object_type(vk::ObjectType::IMAGE)
.build(), // .build(),
) // )
.expect("could not set object name"); // .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)
@ -146,34 +146,34 @@ 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 { // unsafe {
base.debug // base.debug
.loader // .loader
.set_debug_utils_object_name( // .set_debug_utils_object_name(
base.device.handle(), // base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder() // &vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(image.as_raw()) // .object_handle(image.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked( // .object_name(CStr::from_bytes_with_nul_unchecked(
b"SwapchainImage\0", // b"SwapchainImage\0",
)) // ))
.object_type(vk::ObjectType::IMAGE) // .object_type(vk::ObjectType::IMAGE)
.build(), // .build(),
) // )
.expect("could not set object name"); // .expect("could not set object name");
base.debug // base.debug
.loader // .loader
.set_debug_utils_object_name( // .set_debug_utils_object_name(
base.device.handle(), // base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder() // &vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(view.as_raw()) // .object_handle(view.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked( // .object_name(CStr::from_bytes_with_nul_unchecked(
b"SwapchainImageView\0", // b"SwapchainImageView\0",
)) // ))
.object_type(vk::ObjectType::IMAGE_VIEW) // .object_type(vk::ObjectType::IMAGE_VIEW)
.build(), // .build(),
) // )
.expect("could not set object name"); // .expect("could not set object name");
} // }
Ok(view) Ok(view)
}) })
.collect(); .collect();
@ -201,21 +201,21 @@ 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 { // unsafe {
base.debug // base.debug
.loader // .loader
.set_debug_utils_object_name( // .set_debug_utils_object_name(
base.device.handle(), // base.device.handle(),
&vk::DebugUtilsObjectNameInfoEXT::builder() // &vk::DebugUtilsObjectNameInfoEXT::builder()
.object_handle(view.as_raw()) // .object_handle(view.as_raw())
.object_name(CStr::from_bytes_with_nul_unchecked( // .object_name(CStr::from_bytes_with_nul_unchecked(
b"RenderImageView\0", // b"RenderImageView\0",
)) // ))
.object_type(vk::ObjectType::IMAGE_VIEW) // .object_type(vk::ObjectType::IMAGE_VIEW)
.build(), // .build(),
) // )
.expect("could not set object name"); // .expect("could not set object name");
} // }
Ok(view) Ok(view)
}) })
.collect(); .collect();

View file

@ -9,7 +9,8 @@ use crate::hello_triangle::surface::VulkanSurface;
use ash::prelude::VkResult; use ash::prelude::VkResult;
use std::ffi::{CStr, CString}; 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 struct VulkanBase {
pub entry: ash::Entry, pub entry: ash::Entry,
@ -23,17 +24,15 @@ pub struct VulkanBase {
impl VulkanBase { impl VulkanBase {
pub fn new(entry: ash::Entry) -> VkResult<VulkanBase> { pub fn new(entry: ash::Entry) -> VkResult<VulkanBase> {
let app_name = CString::new(WINDOW_TITLE).unwrap();
let engine_name = CString::new("librashader").unwrap();
let app_info = vk::ApplicationInfo::builder() let app_info = vk::ApplicationInfo::builder()
.application_name(&app_name) .application_name(unsafe { &CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) })
.engine_name(&engine_name) .engine_name(unsafe { &CStr::from_bytes_with_nul_unchecked(WINDOW_TITLE) })
.engine_version(0) .engine_version(0)
.application_version(0) .application_version(0)
.api_version(vk::make_api_version(0, 1, 3, 0)) .api_version(vk::make_api_version(0, 1, 3, 0))
.build(); .build();
dbg!("entry");
// todo: make this xplat // todo: make this xplat
let extensions = [ let extensions = [
ash::extensions::khr::Surface::name().as_ptr(), ash::extensions::khr::Surface::name().as_ptr(),
@ -42,7 +41,7 @@ impl VulkanBase {
]; ];
let layers = unsafe { 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() let create_info = vk::InstanceCreateInfo::builder()
@ -57,9 +56,12 @@ impl VulkanBase {
let physical_device = pick_physical_device(&instance); let physical_device = pick_physical_device(&instance);
dbg!("picked physdev");
let (device, queue) = VulkanBase::create_device(&instance, &physical_device)?; let (device, queue) = VulkanBase::create_device(&instance, &physical_device)?;
dbg!("created device");
let mem_props = unsafe { instance.get_physical_device_memory_properties(physical_device) }; let mem_props = unsafe { instance.get_physical_device_memory_properties(physical_device) };
dbg!("got memprops");
Ok(VulkanBase { Ok(VulkanBase {
entry, entry,
@ -76,15 +78,15 @@ impl VulkanBase {
instance: &ash::Instance, instance: &ash::Instance,
physical_device: &vk::PhysicalDevice, physical_device: &vk::PhysicalDevice,
) -> VkResult<(ash::Device, vk::Queue)> { ) -> VkResult<(ash::Device, vk::Queue)> {
let debug = unsafe { let debug = [unsafe {
CStr::from_bytes_with_nul_unchecked(b"VK_LAYER_KHRONOS_validation\0").as_ptr() CStr::from_bytes_with_nul_unchecked(KHRONOS_VALIDATION).as_ptr()
}; }];
let indices = find_queue_family(&instance, *physical_device); 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_family_index(indices.graphics_family())
.queue_priorities(&[1.0f32]) .queue_priorities(&[1.0f32])
.build(); .build()];
// let physical_device_features = vk::PhysicalDeviceFeatures::default(); // let physical_device_features = vk::PhysicalDeviceFeatures::default();
@ -96,13 +98,15 @@ impl VulkanBase {
// vk::PhysicalDeviceFeatures2::builder().push_next(&mut physical_device_features) // vk::PhysicalDeviceFeatures2::builder().push_next(&mut physical_device_features)
// .build(); // .build();
let extensions = [
ash::extensions::khr::Swapchain::name().as_ptr(),
ash::extensions::khr::DynamicRendering::name().as_ptr(),
];
let device_create_info = vk::DeviceCreateInfo::builder() let device_create_info = vk::DeviceCreateInfo::builder()
.queue_create_infos(&[queue_info]) .queue_create_infos(&queue_info)
.enabled_layer_names(&[debug]) .enabled_layer_names(&debug)
.enabled_extension_names(&[ .enabled_extension_names(&extensions)
ash::extensions::khr::Swapchain::name().as_ptr(),
ash::extensions::khr::DynamicRendering::name().as_ptr(),
])
.push_next(&mut physical_device_features) .push_next(&mut physical_device_features)
// .enabled_features(&physical_device_features) // .enabled_features(&physical_device_features)
.build(); .build();
@ -122,29 +126,29 @@ unsafe extern "system" fn vulkan_debug_callback(
p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT, p_callback_data: *const vk::DebugUtilsMessengerCallbackDataEXT,
_user_data: *mut std::os::raw::c_void, _user_data: *mut std::os::raw::c_void,
) -> vk::Bool32 { ) -> vk::Bool32 {
let callback_data = *p_callback_data; // let callback_data = *p_callback_data;
let message_id_number: i32 = callback_data.message_id_number as i32; // 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() { // let message_id_name = if callback_data.p_message_id_name.is_null() {
Cow::from("") // Cow::from("")
} else { // } else {
CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy() // CStr::from_ptr(callback_data.p_message_id_name).to_string_lossy()
}; // };
//
let message = if callback_data.p_message.is_null() { // let message = if callback_data.p_message.is_null() {
Cow::from("") // Cow::from("")
} else { // } else {
CStr::from_ptr(callback_data.p_message).to_string_lossy() // CStr::from_ptr(callback_data.p_message).to_string_lossy()
}; // };
//
println!( // println!(
"{:?}:\n{:?} [{} ({})] : {}\n", // "{:?}:\n{:?} [{} ({})] : {}\n",
message_severity, // message_severity,
message_type, // message_type,
message_id_name, // message_id_name,
&message_id_number.to_string(), // &message_id_number.to_string(),
message, // message,
); // );
vk::FALSE vk::FALSE
} }

View file

@ -28,10 +28,12 @@ mod tests {
fn triangle_vk() { fn triangle_vk() {
let entry = unsafe { ash::Entry::load().unwrap() }; let entry = unsafe { ash::Entry::load().unwrap() };
let base = VulkanBase::new(entry).unwrap(); let base = VulkanBase::new(entry).unwrap();
dbg!("finished");
let mut filter = FilterChainVulkan::load_from_path( let mut filter = FilterChainVulkan::load_from_path(
&base, &base,
// "../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp", // "../test/slang-shaders/border/gameboy-player/gameboy-player-crt-royale.slangp",
"../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp", "../test/slang-shaders/bezel/Mega_Bezel/Presets/MBZ__0__SMOOTH-ADV.slangp",
// "../test/basic.slangp",
None, None,
) )
.unwrap(); .unwrap();

View file

@ -38,29 +38,30 @@ impl VkUboRing {
binding: u32, binding: u32,
storage: &impl UniformStorageAccess, storage: &impl UniformStorageAccess,
) -> error::Result<()> { ) -> error::Result<()> {
let mut buffer = self.ring.current_mut();
// todo: write directly to allocated buffer. // todo: write directly to allocated buffer.
unsafe { unsafe {
let mut buffer = self.ring.current_mut();
let mut map = buffer.map()?; let mut map = buffer.map()?;
map.copy_from(0, storage.ubo_slice()) map.copy_from(0, storage.ubo_slice())
} }
let buffer = self.ring.current();
unsafe { unsafe {
let buffer_info = vk::DescriptorBufferInfo::builder() let buffer_info = [vk::DescriptorBufferInfo::builder()
.buffer(buffer.handle) .buffer(buffer.handle)
.offset(0) .offset(0)
.range(storage.ubo_slice().len() as vk::DeviceSize) .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) .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER)
.dst_set(descriptor_set) .dst_set(descriptor_set)
.dst_binding(binding) .dst_binding(binding)
.dst_array_element(0) .dst_array_element(0)
.buffer_info(&[buffer_info]) .buffer_info(&buffer_info)
.build(); .build()];
self.device.update_descriptor_sets(&[write_info], &[]) self.device.update_descriptor_sets(&write_info, &[])
} }
self.ring.next(); self.ring.next();
Ok(()) Ok(())

View file

@ -124,6 +124,9 @@ impl Drop for VulkanBuffer {
impl<'a> VulkanBufferMapHandle<'a> { impl<'a> VulkanBufferMapHandle<'a> {
pub unsafe fn copy_from(&mut self, offset: usize, src: &[u8]) { 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( std::ptr::copy_nonoverlapping(
src.as_ptr(), src.as_ptr(),
self.ptr self.ptr

View file

@ -6,6 +6,8 @@ use librashader_reflect::reflect::semantics::{TextureBinding, UboReflection};
use librashader_reflect::reflect::ShaderReflection; use librashader_reflect::reflect::ShaderReflection;
use std::ffi::CStr; use std::ffi::CStr;
const ENTRY_POINT: &'static CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") } ;
pub struct PipelineDescriptors { pub struct PipelineDescriptors {
pub replicas: u32, pub replicas: u32,
pub layout_bindings: Vec<vk::DescriptorSetLayoutBinding>, pub layout_bindings: Vec<vk::DescriptorSetLayoutBinding>,
@ -119,12 +121,14 @@ impl PipelineLayoutObjects {
let layout = unsafe { device.create_pipeline_layout(&pipeline_create_info, None)? }; 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 { let pool = unsafe {
device.create_descriptor_pool( device.create_descriptor_pool(
&vk::DescriptorPoolCreateInfo::builder() &pool_info,
.max_sets(replicas)
.pool_sizes(&descriptors.pool_sizes)
.build(),
None, None,
)? )?
}; };
@ -136,7 +140,8 @@ impl PipelineLayoutObjects {
.build(); .build();
for _ in 0..replicas { 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<vk::DescriptorSet> = let descriptor_sets: Vec<vk::DescriptorSet> =
@ -209,14 +214,14 @@ impl VulkanGraphicsPipeline {
}, },
]; ];
let input_binding = vk::VertexInputBindingDescription::builder() let input_binding = [vk::VertexInputBindingDescription::builder()
.binding(0) .binding(0)
.stride(4 * std::mem::size_of::<f32>() as u32) .stride(4 * std::mem::size_of::<f32>() as u32)
.input_rate(vk::VertexInputRate::VERTEX) .input_rate(vk::VertexInputRate::VERTEX)
.build(); .build()];
let pipeline_input_state = vk::PipelineVertexInputStateCreateInfo::builder() let pipeline_input_state = vk::PipelineVertexInputStateCreateInfo::builder()
.vertex_binding_descriptions(&[input_binding]) .vertex_binding_descriptions(&input_binding)
.vertex_attribute_descriptions(&vao_state) .vertex_attribute_descriptions(&vao_state)
.build(); .build();
@ -230,11 +235,13 @@ impl VulkanGraphicsPipeline {
.line_width(1.0) .line_width(1.0)
.build(); .build();
let attachments = [vk::PipelineColorBlendAttachmentState::builder()
.blend_enable(false)
.color_write_mask(vk::ColorComponentFlags::from_raw(0xf))
.build()];
let blend_state = vk::PipelineColorBlendStateCreateInfo::builder() let blend_state = vk::PipelineColorBlendStateCreateInfo::builder()
.attachments(&[vk::PipelineColorBlendAttachmentState::builder() .attachments(&attachments)
.blend_enable(false)
.color_write_mask(vk::ColorComponentFlags::from_raw(0xf))
.build()])
.build(); .build();
let viewport_state = vk::PipelineViewportStateCreateInfo::builder() let viewport_state = vk::PipelineViewportStateCreateInfo::builder()
@ -255,8 +262,9 @@ impl VulkanGraphicsPipeline {
.rasterization_samples(vk::SampleCountFlags::TYPE_1) .rasterization_samples(vk::SampleCountFlags::TYPE_1)
.build(); .build();
let states = [vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR];
let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder() let dynamic_state = vk::PipelineDynamicStateCreateInfo::builder()
.dynamic_states(&[vk::DynamicState::VIEWPORT, vk::DynamicState::SCISSOR]) .dynamic_states(&states)
.build(); .build();
let vertex_info = vk::ShaderModuleCreateInfo::builder() let vertex_info = vk::ShaderModuleCreateInfo::builder()
@ -272,12 +280,12 @@ impl VulkanGraphicsPipeline {
let shader_stages = [ let shader_stages = [
vk::PipelineShaderStageCreateInfo::builder() vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::VERTEX) .stage(vk::ShaderStageFlags::VERTEX)
.name(unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") }) .name(&ENTRY_POINT)
.module(vertex_module.shader.clone()) .module(vertex_module.shader.clone())
.build(), .build(),
vk::PipelineShaderStageCreateInfo::builder() vk::PipelineShaderStageCreateInfo::builder()
.stage(vk::ShaderStageFlags::FRAGMENT) .stage(vk::ShaderStageFlags::FRAGMENT)
.name(unsafe { CStr::from_bytes_with_nul_unchecked(b"main\0") }) .name(&ENTRY_POINT)
.module(fragment_module.shader.clone()) .module(fragment_module.shader.clone())
.build(), .build(),
]; ];