use dynamic rendering for swapchains
This commit is contained in:
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user