diff --git a/src/enums.rs b/src/enums.rs index f470913..811b20d 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -28,7 +28,6 @@ pub enum Functions { CreateSwapchain(PFN_vkCreateSwapchainKHR), QueueSubmit(PFN_vkQueueSubmit), GetDeviceQueue(PFN_vkGetDeviceQueue), - AcquireNextImageKHR(PFN_vkAcquireNextImageKHR), } impl Functions { @@ -44,7 +43,6 @@ impl Functions { Functions::CreateSwapchain(func) => unsafe { mem::transmute(func) }, Functions::QueueSubmit(func) => unsafe { mem::transmute(func) }, Functions::GetDeviceQueue(func) => unsafe { mem::transmute(func) }, - Functions::AcquireNextImageKHR(func) => unsafe { mem::transmute(func) }, } } } diff --git a/src/lib.rs b/src/lib.rs index fe00ece..44e39f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -294,6 +294,9 @@ extern "system" fn create_swapchain( create_swapchain(_device, create_info, _allocator, p_swapchain); + write_log("-> created swapchain vk handle"); + + // if unsafe { !OVERLAY.has_rendering() } { let swapchain = match unsafe { Swapchain::from_raw(OVERLAY.device(), &*create_info, *p_swapchain) } { Ok(swapchain) => swapchain, @@ -303,9 +306,14 @@ extern "system" fn create_swapchain( } }; - // if let Err(err) = unsafe { OVERLAY.create_rendering(swapchain) } { - // write_log(format!("create overlay rendering struct failed: {:?}", err)); - // return VK_ERROR_INITIALIZATION_FAILED; + write_log("-> created Arc"); + + if let Err(err) = unsafe { OVERLAY.create_rendering(swapchain) } { + write_log(format!("create overlay rendering struct failed: {:?}", err)); + return VK_ERROR_INITIALIZATION_FAILED; + } + + write_log("-> created renderer"); // } VK_SUCCESS @@ -319,13 +327,9 @@ extern "system" fn submit_queue( ) -> VkResult { write_log(" ================== vulkan layer submit queue =================="); - unsafe { - return QUEUE_SUBMIT(queue, submit_count, submits, fence); - } - unsafe { let input_submit_info = slice::from_raw_parts(submits, submit_count as usize); - let overlay_submit = match OVERLAY.render(queue) { + let overlay_submit = match OVERLAY.render() { Ok(submit) => submit, Err(err) => { write_log(format!("overlay rendering failed: {:?}", err)); @@ -363,46 +367,16 @@ extern "system" fn get_device_queue( get_device_queue(device, queue_family_index, queue_index, p_queue); unsafe { - let arc_device = OVERLAY.device(); - OVERLAY.add_queue(Queue::new( - arc_device, - *p_queue, - queue_family_index, - queue_index, - )); - } -} - -extern "system" fn acquire_next_image( - _device: VkDevice, - swapchain: VkSwapchainKHR, - timeout: u64, - semaphore: VkSemaphore, - fence: VkFence, - image_index: *mut u32, -) -> VkResult { - write_log(" ================== vulkan layer acquire next image =================="); - - unsafe { - *image_index = match OVERLAY.device().acquire_next_image( - swapchain, - timeout, - Some(semaphore), - Some(fence), - ) { - Ok(res) => match res { - OutOfDate::Ok(index) => index, - OutOfDate::OutOfDate => return VK_ERROR_OUT_OF_DATE_KHR, - OutOfDate::TimeOut => return VK_TIMEOUT, - }, - Err(err) => { - write_log(format!("Failed acquiring next image: {:?}", err)); - return VK_ERROR_DEVICE_LOST; - } + if !OVERLAY.has_queue() { + let arc_device = OVERLAY.device(); + OVERLAY.add_queue(Queue::new( + arc_device, + *p_queue, + queue_family_index, + queue_index, + )); } } - - VK_SUCCESS } pub fn write_log(msg: impl ToString) { @@ -420,7 +394,7 @@ pub fn get_vk_func(s: &str) -> Option { "vkCreateSwapchainKHR" => Some(Functions::CreateSwapchain(create_swapchain)), "vkQueueSubmit" => Some(Functions::QueueSubmit(submit_queue)), "vkGetDeviceQueue" => Some(Functions::GetDeviceQueue(get_device_queue)), - // "vkAcquireNextImageKHR" => Some(Functions::AcquireNextImageKHR(acquire_next_image)), + _ => None, } } diff --git a/src/overlay/mod.rs b/src/overlay/mod.rs index 4c33604..a8c9b1b 100644 --- a/src/overlay/mod.rs +++ b/src/overlay/mod.rs @@ -1,18 +1,22 @@ -use self::rendering::Rendering; +use crate::write_log; + +use self::{rendering::Rendering, rfactor_data::RFactorData}; mod pipeline; mod rendering; +mod rfactor_data; use anyhow::Result; use std::sync::{Arc, Mutex}; use vulkan_rs::prelude::*; -#[derive(Default)] pub struct Overlay { instance: Option>, device: Option>, - queues: Vec>>, - renderings: Vec, + queue: Option>>, + rendering: Option, + + rfactor_data: RFactorData, } impl Overlay { @@ -20,8 +24,10 @@ impl Overlay { Self { instance: None, device: None, - queues: Vec::new(), - renderings: Vec::new(), + queue: None, + rendering: None, + + rfactor_data: RFactorData::default(), } } @@ -41,44 +47,48 @@ impl Overlay { self.device.as_ref().unwrap().clone() } + pub fn has_queue(&self) -> bool { + self.queue.is_some() + } + pub fn add_queue(&mut self, queue: Arc>) { - self.queues.push(queue); + self.queue = Some(queue); } - pub fn queue(&self, queue: VkQueue) -> Arc> { - match self - .queues - .iter() - .find(|q| q.lock().unwrap().vk_handle() == queue) - { - Some(q) => q.clone(), - None => panic!(), - } + pub fn queue(&self) -> Arc> { + self.queue.as_ref().unwrap().clone() } - pub fn swapchain(&self, swapchain: VkSwapchainKHR) -> &Arc { - match self - .renderings - .iter() - .find(|r| r.swapchain().vk_handle() == swapchain) - { - Some(s) => s.swapchain(), - None => panic!(), - } + pub fn swapchain(&self) -> &Arc { + self.rendering.as_ref().unwrap().swapchain() } - pub fn add_rendering(&mut self, swapchain: Arc) -> Result<()> { - // self.renderings - // .push(Rendering::new(self.device(), self.queue(), swapchain)?); + pub fn create_rendering(&mut self, swapchain: Arc) -> Result<()> { + write_log("-> create rendering: start"); + + self.rendering = None; + + write_log("-> create rendering: old cleared"); + + self.rendering = Some(Rendering::new(self.device(), self.queue(), swapchain)?); + + write_log("-> create rendering: new created"); + + write_log("-> create rendering: end"); Ok(()) } - pub fn render(&mut self, queue: VkQueue) -> Result { - // for rendering in self.renderings { - // rendering.render() - // } + pub fn render(&mut self) -> Result { + self.rfactor_data.update()?; - todo!() + let device = self.device(); + let queue = self.queue(); + let swapchain = self.swapchain().clone(); + + self.rendering + .as_mut() + .unwrap() + .render(device, queue, swapchain, &self.rfactor_data) } } diff --git a/src/overlay/pipeline.rs b/src/overlay/pipeline.rs index 3030bc3..82a0ed2 100644 --- a/src/overlay/pipeline.rs +++ b/src/overlay/pipeline.rs @@ -47,6 +47,7 @@ impl SingleColorPipeline { .set_fragment_shader(fragment_shader.clone()) .input_assembly(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false) .default_depth_stencil(false, false) + .default_color_blend(vec![VkPipelineColorBlendAttachmentState::default()]) .default_rasterization(VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE) .default_multisample(VK_SAMPLE_COUNT_1_BIT) .build(device, &pipeline_layout, &renderpass, 0)?; diff --git a/src/overlay/rendering.rs b/src/overlay/rendering.rs index cf635ee..f833453 100644 --- a/src/overlay/rendering.rs +++ b/src/overlay/rendering.rs @@ -3,13 +3,15 @@ use vulkan_rs::prelude::*; use std::sync::{Arc, Mutex}; -use super::pipeline::SingleColorPipeline; +use super::{pipeline::SingleColorPipeline, rfactor_data::RFactorData}; +use crate::write_log; pub struct Rendering { swapchain: Arc, pipeline: SingleColorPipeline, render_target: RenderTarget, images: Vec>, + submit_info: SubmitInfo, } impl Rendering { @@ -18,7 +20,20 @@ impl Rendering { queue: Arc>, swapchain: Arc, ) -> Result { - let images = swapchain.wrap_images(&swapchain.vk_images()?, &queue)?; + write_log("-> Rendering ctor: begin"); + let vk_images = swapchain.vk_images()?; + write_log(format!( + "-> Rendering ctor: vk images ({})", + vk_images.len() + )); + let images = match swapchain.wrap_images(&vk_images, &queue) { + Ok(images) => images, + Err(err) => { + write_log(format!("-> Rendering ctor: failed wrapper: {:?}", err)); + return Err(err); + } + }; + write_log("-> Rendering ctor: wrapped images"); let render_target = RenderTarget::builder() .add_sub_pass( @@ -28,11 +43,14 @@ impl Rendering { ) .build(&device)?; + write_log("-> Rendering ctor: created render_target"); + Ok(Self { swapchain, pipeline: SingleColorPipeline::new(device, render_target.render_pass())?, render_target, images, + submit_info: SubmitInfo::default(), }) } @@ -40,7 +58,61 @@ impl Rendering { &self.swapchain } - pub fn render(&mut self) -> Result { - todo!() + pub fn render( + &mut self, + device: Arc, + queue: Arc>, + swapchain: Arc, + rfactor_data: &RFactorData, + ) -> Result { + write_log(" ================== vulkan layer enter rendering =================="); + + let image_index = self.swapchain.current_index(); + + let viewport = [VkViewport { + x: 0.0, + y: 0.0, + width: swapchain.width() as f32, + height: swapchain.height() as f32, + minDepth: 0.0, + maxDepth: 1.0, + }]; + + let scissor = [VkRect2D { + offset: VkOffset2D { x: 0, y: 0 }, + extent: VkExtent2D { + width: swapchain.width(), + height: swapchain.height(), + }, + }]; + + let command_buffer = CommandBuffer::new_primary().build(device, queue)?; + + write_log(" ================== vulkan layer created command buffer =================="); + + { + let mut recorder = command_buffer.begin(VkCommandBufferBeginInfo::new( + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + ))?; + + write_log(" ================== vulkan layer begin command buffer =================="); + + self.render_target + .begin(&recorder, VK_SUBPASS_CONTENTS_INLINE, image_index as usize); + + recorder.bind_pipeline(self.pipeline.pipeline())?; + recorder.set_scissor(&scissor); + recorder.set_viewport(&viewport); + + // // recorder.bind_vertex_buffer(); + + self.render_target.end(&recorder); + } + + self.submit_info = SubmitInfo::default() + .add_wait_stage(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT) + .add_command_buffer(command_buffer); + + Ok(self.submit_info.as_vk_submit()) } } diff --git a/src/overlay/rfactor_data.rs b/src/overlay/rfactor_data.rs new file mode 100644 index 0000000..c46c244 --- /dev/null +++ b/src/overlay/rfactor_data.rs @@ -0,0 +1,15 @@ +use anyhow::Result; + +pub struct RFactorData { + // TODO +} + +impl RFactorData { + pub const fn default() -> Self { + Self {} + } + + pub fn update(&mut self) -> Result<()> { + Ok(()) + } +}