Implement working empty renderer

This commit is contained in:
hodasemi 2023-01-12 17:45:06 +01:00
parent ef720708aa
commit 03c4194d29
6 changed files with 156 additions and 86 deletions

View file

@ -28,7 +28,6 @@ pub enum Functions {
CreateSwapchain(PFN_vkCreateSwapchainKHR), CreateSwapchain(PFN_vkCreateSwapchainKHR),
QueueSubmit(PFN_vkQueueSubmit), QueueSubmit(PFN_vkQueueSubmit),
GetDeviceQueue(PFN_vkGetDeviceQueue), GetDeviceQueue(PFN_vkGetDeviceQueue),
AcquireNextImageKHR(PFN_vkAcquireNextImageKHR),
} }
impl Functions { impl Functions {
@ -44,7 +43,6 @@ impl Functions {
Functions::CreateSwapchain(func) => unsafe { mem::transmute(func) }, Functions::CreateSwapchain(func) => unsafe { mem::transmute(func) },
Functions::QueueSubmit(func) => unsafe { mem::transmute(func) }, Functions::QueueSubmit(func) => unsafe { mem::transmute(func) },
Functions::GetDeviceQueue(func) => unsafe { mem::transmute(func) }, Functions::GetDeviceQueue(func) => unsafe { mem::transmute(func) },
Functions::AcquireNextImageKHR(func) => unsafe { mem::transmute(func) },
} }
} }
} }

View file

@ -294,6 +294,9 @@ extern "system" fn create_swapchain(
create_swapchain(_device, create_info, _allocator, p_swapchain); create_swapchain(_device, create_info, _allocator, p_swapchain);
write_log("-> created swapchain vk handle");
// if unsafe { !OVERLAY.has_rendering() } {
let swapchain = let swapchain =
match unsafe { Swapchain::from_raw(OVERLAY.device(), &*create_info, *p_swapchain) } { match unsafe { Swapchain::from_raw(OVERLAY.device(), &*create_info, *p_swapchain) } {
Ok(swapchain) => swapchain, Ok(swapchain) => swapchain,
@ -303,9 +306,14 @@ extern "system" fn create_swapchain(
} }
}; };
// if let Err(err) = unsafe { OVERLAY.create_rendering(swapchain) } { write_log("-> created Arc<Swapchain>");
// write_log(format!("create overlay rendering struct failed: {:?}", err));
// return VK_ERROR_INITIALIZATION_FAILED; 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 VK_SUCCESS
@ -319,13 +327,9 @@ extern "system" fn submit_queue(
) -> VkResult { ) -> VkResult {
write_log(" ================== vulkan layer submit queue =================="); write_log(" ================== vulkan layer submit queue ==================");
unsafe {
return QUEUE_SUBMIT(queue, submit_count, submits, fence);
}
unsafe { unsafe {
let input_submit_info = slice::from_raw_parts(submits, submit_count as usize); 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, Ok(submit) => submit,
Err(err) => { Err(err) => {
write_log(format!("overlay rendering failed: {:?}", 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); get_device_queue(device, queue_family_index, queue_index, p_queue);
unsafe { unsafe {
let arc_device = OVERLAY.device(); if !OVERLAY.has_queue() {
OVERLAY.add_queue(Queue::new( let arc_device = OVERLAY.device();
arc_device, OVERLAY.add_queue(Queue::new(
*p_queue, arc_device,
queue_family_index, *p_queue,
queue_index, 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;
}
} }
} }
VK_SUCCESS
} }
pub fn write_log(msg: impl ToString) { pub fn write_log(msg: impl ToString) {
@ -420,7 +394,7 @@ pub fn get_vk_func(s: &str) -> Option<Functions> {
"vkCreateSwapchainKHR" => Some(Functions::CreateSwapchain(create_swapchain)), "vkCreateSwapchainKHR" => Some(Functions::CreateSwapchain(create_swapchain)),
"vkQueueSubmit" => Some(Functions::QueueSubmit(submit_queue)), "vkQueueSubmit" => Some(Functions::QueueSubmit(submit_queue)),
"vkGetDeviceQueue" => Some(Functions::GetDeviceQueue(get_device_queue)), "vkGetDeviceQueue" => Some(Functions::GetDeviceQueue(get_device_queue)),
// "vkAcquireNextImageKHR" => Some(Functions::AcquireNextImageKHR(acquire_next_image)),
_ => None, _ => None,
} }
} }

View file

@ -1,18 +1,22 @@
use self::rendering::Rendering; use crate::write_log;
use self::{rendering::Rendering, rfactor_data::RFactorData};
mod pipeline; mod pipeline;
mod rendering; mod rendering;
mod rfactor_data;
use anyhow::Result; use anyhow::Result;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use vulkan_rs::prelude::*; use vulkan_rs::prelude::*;
#[derive(Default)]
pub struct Overlay { pub struct Overlay {
instance: Option<Arc<Instance>>, instance: Option<Arc<Instance>>,
device: Option<Arc<Device>>, device: Option<Arc<Device>>,
queues: Vec<Arc<Mutex<Queue>>>, queue: Option<Arc<Mutex<Queue>>>,
renderings: Vec<Rendering>, rendering: Option<Rendering>,
rfactor_data: RFactorData,
} }
impl Overlay { impl Overlay {
@ -20,8 +24,10 @@ impl Overlay {
Self { Self {
instance: None, instance: None,
device: None, device: None,
queues: Vec::new(), queue: None,
renderings: Vec::new(), rendering: None,
rfactor_data: RFactorData::default(),
} }
} }
@ -41,44 +47,48 @@ impl Overlay {
self.device.as_ref().unwrap().clone() self.device.as_ref().unwrap().clone()
} }
pub fn has_queue(&self) -> bool {
self.queue.is_some()
}
pub fn add_queue(&mut self, queue: Arc<Mutex<Queue>>) { pub fn add_queue(&mut self, queue: Arc<Mutex<Queue>>) {
self.queues.push(queue); self.queue = Some(queue);
} }
pub fn queue(&self, queue: VkQueue) -> Arc<Mutex<Queue>> { pub fn queue(&self) -> Arc<Mutex<Queue>> {
match self self.queue.as_ref().unwrap().clone()
.queues
.iter()
.find(|q| q.lock().unwrap().vk_handle() == queue)
{
Some(q) => q.clone(),
None => panic!(),
}
} }
pub fn swapchain(&self, swapchain: VkSwapchainKHR) -> &Arc<Swapchain> { pub fn swapchain(&self) -> &Arc<Swapchain> {
match self self.rendering.as_ref().unwrap().swapchain()
.renderings
.iter()
.find(|r| r.swapchain().vk_handle() == swapchain)
{
Some(s) => s.swapchain(),
None => panic!(),
}
} }
pub fn add_rendering(&mut self, swapchain: Arc<Swapchain>) -> Result<()> { pub fn create_rendering(&mut self, swapchain: Arc<Swapchain>) -> Result<()> {
// self.renderings write_log("-> create rendering: start");
// .push(Rendering::new(self.device(), self.queue(), swapchain)?);
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(()) Ok(())
} }
pub fn render(&mut self, queue: VkQueue) -> Result<VkSubmitInfo> { pub fn render(&mut self) -> Result<VkSubmitInfo> {
// for rendering in self.renderings { self.rfactor_data.update()?;
// rendering.render()
// }
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)
} }
} }

View file

@ -47,6 +47,7 @@ impl SingleColorPipeline {
.set_fragment_shader(fragment_shader.clone()) .set_fragment_shader(fragment_shader.clone())
.input_assembly(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false) .input_assembly(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, false)
.default_depth_stencil(false, false) .default_depth_stencil(false, false)
.default_color_blend(vec![VkPipelineColorBlendAttachmentState::default()])
.default_rasterization(VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE) .default_rasterization(VK_CULL_MODE_NONE, VK_FRONT_FACE_COUNTER_CLOCKWISE)
.default_multisample(VK_SAMPLE_COUNT_1_BIT) .default_multisample(VK_SAMPLE_COUNT_1_BIT)
.build(device, &pipeline_layout, &renderpass, 0)?; .build(device, &pipeline_layout, &renderpass, 0)?;

View file

@ -3,13 +3,15 @@ use vulkan_rs::prelude::*;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use super::pipeline::SingleColorPipeline; use super::{pipeline::SingleColorPipeline, rfactor_data::RFactorData};
use crate::write_log;
pub struct Rendering { pub struct Rendering {
swapchain: Arc<Swapchain>, swapchain: Arc<Swapchain>,
pipeline: SingleColorPipeline, pipeline: SingleColorPipeline,
render_target: RenderTarget, render_target: RenderTarget,
images: Vec<Arc<Image>>, images: Vec<Arc<Image>>,
submit_info: SubmitInfo,
} }
impl Rendering { impl Rendering {
@ -18,7 +20,20 @@ impl Rendering {
queue: Arc<Mutex<Queue>>, queue: Arc<Mutex<Queue>>,
swapchain: Arc<Swapchain>, swapchain: Arc<Swapchain>,
) -> Result<Self> { ) -> Result<Self> {
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() let render_target = RenderTarget::builder()
.add_sub_pass( .add_sub_pass(
@ -28,11 +43,14 @@ impl Rendering {
) )
.build(&device)?; .build(&device)?;
write_log("-> Rendering ctor: created render_target");
Ok(Self { Ok(Self {
swapchain, swapchain,
pipeline: SingleColorPipeline::new(device, render_target.render_pass())?, pipeline: SingleColorPipeline::new(device, render_target.render_pass())?,
render_target, render_target,
images, images,
submit_info: SubmitInfo::default(),
}) })
} }
@ -40,7 +58,61 @@ impl Rendering {
&self.swapchain &self.swapchain
} }
pub fn render(&mut self) -> Result<VkSubmitInfo> { pub fn render(
todo!() &mut self,
device: Arc<Device>,
queue: Arc<Mutex<Queue>>,
swapchain: Arc<Swapchain>,
rfactor_data: &RFactorData,
) -> Result<VkSubmitInfo> {
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())
} }
} }

View file

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