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,
pipeline_cache: vk::PipelineCache,
pub(crate) memory_properties: vk::PhysicalDeviceMemoryProperties,
debug: DebugUtils,
// debug: DebugUtils,
}
type ShaderPassMeta = (
@ -102,7 +102,7 @@ impl TryFrom<VulkanInfo<'_>> 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,

View file

@ -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)?;

View file

@ -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)
}
}
}

View file

@ -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()

View file

@ -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();

View file

@ -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<VulkanBase> {
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
}

View file

@ -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();

View file

@ -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(())

View file

@ -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

View file

@ -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<vk::DescriptorSetLayoutBinding>,
@ -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<vk::DescriptorSet> =
@ -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::<f32>() 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(),
];