openxr/graphics/
vulkan.rs

1use std::ptr;
2
3use sys::platform::*;
4
5use crate::sys::Handle as _;
6use crate::*;
7
8/// The Vulkan graphics API
9///
10/// See [`XR_KHR_vulkan_enable2`] for safety details.
11///
12/// [`XR_KHR_vulkan_enable2`]: https://www.khronos.org/registry/OpenXR/specs/1.1/html/xrspec.html#XR_KHR_vulkan_enable2
13pub enum Vulkan {}
14
15impl Graphics for Vulkan {
16    type Requirements = Requirements;
17    type Format = VkFormat;
18    type SessionCreateInfo = SessionCreateInfo;
19    type SwapchainImage = VkImage;
20
21    fn raise_format(x: i64) -> Self::Format {
22        x as _
23    }
24    fn lower_format(x: Self::Format) -> i64 {
25        x as _
26    }
27
28    fn requirements(instance: &Instance, system: SystemId) -> Result<Requirements> {
29        let out = unsafe {
30            let mut x = sys::GraphicsRequirementsVulkanKHR::out(ptr::null_mut());
31            let fp = if instance.exts().khr_vulkan_enable2.is_some() {
32                instance.vulkan().get_vulkan_graphics_requirements2
33            } else {
34                instance.vulkan_legacy().get_vulkan_graphics_requirements
35            };
36            cvt(fp(instance.as_raw(), system, x.as_mut_ptr()))?;
37            x.assume_init()
38        };
39        Ok(Requirements {
40            min_api_version_supported: out.min_api_version_supported,
41            max_api_version_supported: out.max_api_version_supported,
42        })
43    }
44
45    unsafe fn create_session(
46        instance: &Instance,
47        system: SystemId,
48        info: &Self::SessionCreateInfo,
49    ) -> Result<sys::Session> {
50        unsafe {
51            let binding = sys::GraphicsBindingVulkanKHR {
52                ty: sys::GraphicsBindingVulkanKHR::TYPE,
53                next: ptr::null(),
54                instance: info.instance,
55                physical_device: info.physical_device,
56                device: info.device,
57                queue_family_index: info.queue_family_index,
58                queue_index: info.queue_index,
59            };
60            let info = sys::SessionCreateInfo {
61                ty: sys::SessionCreateInfo::TYPE,
62                next: &binding as *const _ as *const _,
63                create_flags: Default::default(),
64                system_id: system,
65            };
66            let mut out = sys::Session::NULL;
67            cvt((instance.fp().create_session)(
68                instance.as_raw(),
69                &info,
70                &mut out,
71            ))?;
72            Ok(out)
73        }
74    }
75
76    fn enumerate_swapchain_images(
77        swapchain: &Swapchain<Self>,
78    ) -> Result<Vec<Self::SwapchainImage>> {
79        let images = get_arr_init(
80            sys::SwapchainImageVulkanKHR {
81                ty: sys::SwapchainImageVulkanKHR::TYPE,
82                next: ptr::null_mut(),
83                image: 0,
84            },
85            |capacity, count, buf| unsafe {
86                (swapchain.instance().fp().enumerate_swapchain_images)(
87                    swapchain.as_raw(),
88                    capacity,
89                    count,
90                    buf as *mut _,
91                )
92            },
93        )?;
94        Ok(images.into_iter().map(|x| x.image as _).collect())
95    }
96}
97
98#[derive(Debug, Copy, Clone)]
99pub struct Requirements {
100    pub min_api_version_supported: Version,
101    pub max_api_version_supported: Version,
102}
103
104#[derive(Copy, Clone)]
105pub struct SessionCreateInfo {
106    pub instance: VkInstance,
107    pub physical_device: VkPhysicalDevice,
108    pub device: VkDevice,
109    pub queue_family_index: u32,
110    pub queue_index: u32,
111}