Implement working empty renderer

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

View file

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

View file

@ -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<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 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,6 +367,7 @@ extern "system" fn get_device_queue(
get_device_queue(device, queue_family_index, queue_index, p_queue);
unsafe {
if !OVERLAY.has_queue() {
let arc_device = OVERLAY.device();
OVERLAY.add_queue(Queue::new(
arc_device,
@ -371,38 +376,7 @@ extern "system" fn get_device_queue(
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) {
@ -420,7 +394,7 @@ pub fn get_vk_func(s: &str) -> Option<Functions> {
"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,
}
}

View file

@ -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<Arc<Instance>>,
device: Option<Arc<Device>>,
queues: Vec<Arc<Mutex<Queue>>>,
renderings: Vec<Rendering>,
queue: Option<Arc<Mutex<Queue>>>,
rendering: Option<Rendering>,
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<Mutex<Queue>>) {
self.queues.push(queue);
self.queue = Some(queue);
}
pub fn queue(&self, queue: VkQueue) -> Arc<Mutex<Queue>> {
match self
.queues
.iter()
.find(|q| q.lock().unwrap().vk_handle() == queue)
{
Some(q) => q.clone(),
None => panic!(),
}
pub fn queue(&self) -> Arc<Mutex<Queue>> {
self.queue.as_ref().unwrap().clone()
}
pub fn swapchain(&self, swapchain: VkSwapchainKHR) -> &Arc<Swapchain> {
match self
.renderings
.iter()
.find(|r| r.swapchain().vk_handle() == swapchain)
{
Some(s) => s.swapchain(),
None => panic!(),
}
pub fn swapchain(&self) -> &Arc<Swapchain> {
self.rendering.as_ref().unwrap().swapchain()
}
pub fn add_rendering(&mut self, swapchain: Arc<Swapchain>) -> Result<()> {
// self.renderings
// .push(Rendering::new(self.device(), self.queue(), swapchain)?);
pub fn create_rendering(&mut self, swapchain: Arc<Swapchain>) -> 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<VkSubmitInfo> {
// for rendering in self.renderings {
// rendering.render()
// }
pub fn render(&mut self) -> Result<VkSubmitInfo> {
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)
}
}

View file

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

View file

@ -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<Swapchain>,
pipeline: SingleColorPipeline,
render_target: RenderTarget,
images: Vec<Arc<Image>>,
submit_info: SubmitInfo,
}
impl Rendering {
@ -18,7 +20,20 @@ impl Rendering {
queue: Arc<Mutex<Queue>>,
swapchain: Arc<Swapchain>,
) -> 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()
.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<VkSubmitInfo> {
todo!()
pub fn render(
&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(())
}
}