use dynamic rendering for swapchains

This commit is contained in:
galister
2024-02-01 00:21:28 +01:00
parent a0c2ed0282
commit 49fb3ce424
2 changed files with 55 additions and 58 deletions

View File

@@ -3,13 +3,13 @@ use std::sync::Arc;
use ash::vk; use ash::vk;
use openxr as xr; use openxr as xr;
use smallvec::SmallVec;
use vulkano::{ use vulkano::{
image::{sampler::Filter, view::ImageView, ImageCreateInfo, ImageUsage}, image::{sampler::Filter, sys::RawImage, view::ImageView, ImageCreateInfo, ImageUsage},
render_pass::{Framebuffer, FramebufferCreateInfo},
Handle, Handle,
}; };
use crate::graphics::{WlxCommandBuffer, WlxGraphics, WlxPipeline, WlxPipelineLegacy}; use crate::graphics::{WlxCommandBuffer, WlxGraphics, WlxPipeline, WlxPipelineDynamic};
use super::XrState; use super::XrState;
@@ -34,7 +34,14 @@ pub(super) fn create_swapchain_render_data(
}) })
.unwrap(); .unwrap();
let sips: Vec<SwapchainImagePipeline> = swapchain let shaders = graphics.shared_shaders.read().unwrap();
let pipeline = graphics.create_pipeline_dynamic(
shaders.get("vert_common").unwrap().clone(),
shaders.get("frag_srgb").unwrap().clone(),
graphics.native_format,
);
let images = swapchain
.enumerate_images() .enumerate_images()
.unwrap() .unwrap()
.into_iter() .into_iter()
@@ -42,13 +49,13 @@ pub(super) fn create_swapchain_render_data(
let vk_image = vk::Image::from_raw(handle); let vk_image = vk::Image::from_raw(handle);
// thanks @yshui // thanks @yshui
let raw_image = unsafe { let raw_image = unsafe {
vulkano::image::sys::RawImage::from_handle( RawImage::from_handle(
graphics.device.clone(), graphics.device.clone(),
vk_image, vk_image,
ImageCreateInfo { ImageCreateInfo {
format: graphics.native_format, format: graphics.native_format,
extent, extent,
usage: ImageUsage::COLOR_ATTACHMENT | ImageUsage::TRANSFER_DST, usage: ImageUsage::COLOR_ATTACHMENT,
..Default::default() ..Default::default()
}, },
) )
@@ -56,55 +63,23 @@ pub(super) fn create_swapchain_render_data(
}; };
// SAFETY: OpenXR guarantees that the image is a swapchain image, thus has memory backing it. // SAFETY: OpenXR guarantees that the image is a swapchain image, thus has memory backing it.
let image = Arc::new(unsafe { raw_image.assume_bound() }); let image = Arc::new(unsafe { raw_image.assume_bound() });
let view = ImageView::new_default(image).unwrap(); ImageView::new_default(image).unwrap()
// HACK: maybe not create one pipeline per image?
let shaders = graphics.shared_shaders.read().unwrap();
let pipeline = graphics.create_pipeline(
view.clone(),
shaders.get("vert_common").unwrap().clone(),
shaders.get("frag_srgb").unwrap().clone(),
graphics.native_format,
);
let buffer = Framebuffer::new(
pipeline.data.render_pass.clone(),
FramebufferCreateInfo {
attachments: vec![view.clone()],
extent: [view.image().extent()[0] as _, view.image().extent()[1] as _],
layers: 1,
..Default::default()
},
)
.unwrap();
SwapchainImagePipeline {
buffer,
view,
pipeline,
}
}) })
.collect(); .collect();
SwapchainRenderData { SwapchainRenderData {
swapchain, swapchain,
images: sips, pipeline,
images,
extent, extent,
} }
} }
pub(super) struct SwapchainRenderData { pub(super) struct SwapchainRenderData {
pub(super) swapchain: xr::Swapchain<xr::Vulkan>, pub(super) swapchain: xr::Swapchain<xr::Vulkan>,
pub(super) pipeline: Arc<WlxPipeline<WlxPipelineDynamic>>,
pub(super) extent: [u32; 3], pub(super) extent: [u32; 3],
pub(super) images: Vec<SwapchainImagePipeline>, pub(super) images: SmallVec<[Arc<ImageView>; 4]>,
}
pub(super) struct SwapchainImagePipeline {
pub(super) view: Arc<ImageView>,
pub(super) buffer: Arc<Framebuffer>,
pub(super) pipeline: Arc<WlxPipeline<WlxPipelineLegacy>>,
} }
impl SwapchainRenderData { impl SwapchainRenderData {
@@ -116,22 +91,21 @@ impl SwapchainRenderData {
let idx = self.swapchain.acquire_image().unwrap() as usize; let idx = self.swapchain.acquire_image().unwrap() as usize;
self.swapchain.wait_image(xr::Duration::INFINITE).unwrap(); self.swapchain.wait_image(xr::Duration::INFINITE).unwrap();
let image = &mut self.images[idx]; let render_target = &mut self.images[idx];
let pipeline = image.pipeline.clone(); command_buffer.begin_rendering(render_target.clone());
command_buffer.begin_render_pass(&pipeline);
let target_extent = image.pipeline.data.view.image().extent(); let target_extent = view.image().extent();
let set = image let set = self
.pipeline .pipeline
.uniform_sampler(0, view.clone(), Filter::Linear); .uniform_sampler(0, view.clone(), Filter::Linear);
let pass = image.pipeline.create_pass( let pass = self.pipeline.create_pass(
[target_extent[0] as _, target_extent[1] as _], [target_extent[0] as _, target_extent[1] as _],
command_buffer.graphics.quad_verts.clone(), command_buffer.graphics.quad_verts.clone(),
command_buffer.graphics.quad_indices.clone(), command_buffer.graphics.quad_indices.clone(),
vec![set], vec![set],
); );
command_buffer.run_ref(&pass); command_buffer.run_ref(&pass);
command_buffer.end_render_pass(); command_buffer.end_rendering();
self.swapchain.release_image().unwrap(); self.swapchain.release_image().unwrap();

View File

@@ -2,7 +2,10 @@ use std::{
collections::HashMap, collections::HashMap,
error::Error, error::Error,
io::Cursor, io::Cursor,
os::fd::{FromRawFd, IntoRawFd}, os::{
fd::{FromRawFd, IntoRawFd},
raw::c_void,
},
slice::Iter, slice::Iter,
sync::{Arc, RwLock}, sync::{Arc, RwLock},
}; };
@@ -119,6 +122,9 @@ impl WlxGraphics {
pub fn new_openxr(xr_instance: openxr::Instance, system: openxr::SystemId) -> Arc<Self> { pub fn new_openxr(xr_instance: openxr::Instance, system: openxr::SystemId) -> Arc<Self> {
use std::ffi::{self, c_char, CString}; use std::ffi::{self, c_char, CString};
use ash::vk::{
PhysicalDeviceDynamicRenderingFeatures, PhysicalDeviceDynamicRenderingFeaturesBuilder,
};
use vulkano::Handle; use vulkano::Handle;
let vk_target_version = vk::make_api_version(0, 1, 3, 0); // Vulkan 1.1 guarantees multiview support let vk_target_version = vk::make_api_version(0, 1, 3, 0); // Vulkan 1.1 guarantees multiview support
@@ -204,19 +210,35 @@ impl WlxGraphics {
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let features = Features {
dynamic_rendering: true,
..Default::default()
};
let queue_create_info = vk::DeviceQueueCreateInfo::builder()
.queue_family_index(queue_family_index)
.queue_priorities(&[1.0])
.build();
let mut device_create_info = vk::DeviceCreateInfo::builder()
.queue_create_infos(&[queue_create_info])
.enabled_extension_names(&device_extensions_raw)
.build();
let mut dynamic_rendering = PhysicalDeviceDynamicRenderingFeatures::builder()
.dynamic_rendering(true)
.build();
dynamic_rendering.p_next = device_create_info.p_next as _;
device_create_info.p_next = (&mut dynamic_rendering) as *const _ as *const c_void;
let (device, mut queues) = unsafe { let (device, mut queues) = unsafe {
let vk_device = xr_instance let vk_device = xr_instance
.create_vulkan_device( .create_vulkan_device(
system, system,
std::mem::transmute(vk_entry.static_fn().get_instance_proc_addr), std::mem::transmute(vk_entry.static_fn().get_instance_proc_addr),
physical_device.handle().as_raw() as _, physical_device.handle().as_raw() as _,
&vk::DeviceCreateInfo::builder() (&device_create_info) as *const _ as *const _,
.queue_create_infos(&[vk::DeviceQueueCreateInfo::builder()
.queue_family_index(queue_family_index)
.queue_priorities(&[1.0])
.build()])
.enabled_extension_names(&device_extensions_raw)
as *const _ as *const _,
) )
.expect("XR error creating Vulkan device") .expect("XR error creating Vulkan device")
.map_err(vk::Result::from_raw) .map_err(vk::Result::from_raw)
@@ -231,6 +253,7 @@ impl WlxGraphics {
..Default::default() ..Default::default()
}], }],
enabled_extensions: device_extensions, enabled_extensions: device_extensions,
enabled_features: features,
..Default::default() ..Default::default()
}, },
) )