6
6
//! largely decouple its Vulkan and OpenXR components and handle errors gracefully.
7
7
8
8
use std:: {
9
+ ffi:: { CStr , CString } ,
9
10
io:: Cursor ,
10
11
sync:: {
11
12
atomic:: { AtomicBool , Ordering } ,
@@ -22,7 +23,8 @@ use ash::{
22
23
use openxr as xr;
23
24
24
25
#[ allow( clippy:: field_reassign_with_default) ] // False positive, might be fixed 1.51
25
- fn main ( ) {
26
+ #[ cfg_attr( target_os = "android" , ndk_glue:: main) ]
27
+ pub fn main ( ) {
26
28
// Handle interrupts gracefully
27
29
let running = Arc :: new ( AtomicBool :: new ( true ) ) ;
28
30
let r = running. clone ( ) ;
@@ -37,6 +39,9 @@ fn main() {
37
39
let entry = xr:: Entry :: load ( )
38
40
. expect ( "couldn't find the OpenXR loader; try enabling the \" static\" feature" ) ;
39
41
42
+ #[ cfg( target_os = "android" ) ]
43
+ entry. initialize_android_loader ( ) . unwrap ( ) ;
44
+
40
45
// OpenXR will fail to initialize if we ask for an extension that OpenXR can't provide! So we
41
46
// need to check all our extensions before initializing OpenXR with them. Note that even if the
42
47
// extension is present, it's still possible you may not be able to use it. For example: the
@@ -47,11 +52,19 @@ fn main() {
47
52
// If a required extension isn't present, you want to ditch out here! It's possible something
48
53
// like your rendering API might not be provided by the active runtime. APIs like OpenGL don't
49
54
// have universal support.
50
- assert ! ( available_extensions. khr_vulkan_enable2) ;
55
+ assert ! ( available_extensions. khr_vulkan_enable || available_extensions . khr_vulkan_enable2) ;
51
56
52
57
// Initialize OpenXR with the extensions we've found!
53
58
let mut enabled_extensions = xr:: ExtensionSet :: default ( ) ;
54
- enabled_extensions. khr_vulkan_enable2 = true ;
59
+ if available_extensions. khr_vulkan_enable2 {
60
+ enabled_extensions. khr_vulkan_enable2 = true ;
61
+ } else {
62
+ enabled_extensions. khr_vulkan_enable = true ;
63
+ }
64
+ #[ cfg( target_os = "android" ) ]
65
+ {
66
+ enabled_extensions. khr_android_create_instance = true ;
67
+ }
55
68
let xr_instance = entry
56
69
. create_instance (
57
70
& xr:: ApplicationInfo {
@@ -90,6 +103,7 @@ fn main() {
90
103
let reqs = xr_instance
91
104
. graphics_requirements :: < xr:: Vulkan > ( system)
92
105
. unwrap ( ) ;
106
+
93
107
if vk_target_version_xr < reqs. min_api_version_supported
94
108
|| vk_target_version_xr. major ( ) > reqs. max_api_version_supported . major ( )
95
109
{
@@ -108,20 +122,46 @@ fn main() {
108
122
. api_version ( vk_target_version) ;
109
123
110
124
unsafe {
111
- let vk_instance = xr_instance
112
- . create_vulkan_instance (
113
- system,
114
- std:: mem:: transmute ( vk_entry. static_fn ( ) . get_instance_proc_addr ) ,
115
- & vk:: InstanceCreateInfo :: builder ( ) . application_info ( & vk_app_info) as * const _
116
- as * const _ ,
125
+ let vk_instance = if enabled_extensions. khr_vulkan_enable2 {
126
+ let vk_instance = xr_instance
127
+ . create_vulkan_instance (
128
+ system,
129
+ std:: mem:: transmute ( vk_entry. static_fn ( ) . get_instance_proc_addr ) ,
130
+ & vk:: InstanceCreateInfo :: builder ( ) . application_info ( & vk_app_info) as * const _
131
+ as * const _ ,
132
+ )
133
+ . expect ( "XR error creating Vulkan instance" )
134
+ . map_err ( vk:: Result :: from_raw)
135
+ . expect ( "Vulkan error creating Vulkan instance" ) ;
136
+ ash:: Instance :: load (
137
+ vk_entry. static_fn ( ) ,
138
+ vk:: Instance :: from_raw ( vk_instance as _ ) ,
117
139
)
118
- . expect ( "XR error creating Vulkan instance" )
119
- . map_err ( vk:: Result :: from_raw)
120
- . expect ( "Vulkan error creating Vulkan instance" ) ;
121
- let vk_instance = ash:: Instance :: load (
122
- vk_entry. static_fn ( ) ,
123
- vk:: Instance :: from_raw ( vk_instance as _ ) ,
124
- ) ;
140
+ } else {
141
+ let vk_instance_exts = xr_instance
142
+ . vulkan_legacy_instance_extensions ( system)
143
+ . unwrap ( )
144
+ . split ( ' ' )
145
+ . map ( |x| CString :: new ( x) . unwrap ( ) )
146
+ . collect :: < Vec < _ > > ( ) ;
147
+ println ! (
148
+ "Required Vulkan instance extensions: {:?}" ,
149
+ vk_instance_exts
150
+ ) ;
151
+ let vk_instance_ext_ptrs = vk_instance_exts
152
+ . iter ( )
153
+ . map ( |x| x. as_ptr ( ) )
154
+ . collect :: < Vec < _ > > ( ) ;
155
+
156
+ vk_entry
157
+ . create_instance (
158
+ & vk:: InstanceCreateInfo :: builder ( )
159
+ . application_info ( & vk_app_info)
160
+ . enabled_extension_names ( & vk_instance_ext_ptrs) ,
161
+ None ,
162
+ )
163
+ . expect ( "Vulkan error creating Vulkan instance" )
164
+ } ;
125
165
126
166
let vk_physical_device = vk:: PhysicalDevice :: from_raw (
127
167
xr_instance
@@ -148,26 +188,72 @@ fn main() {
148
188
} )
149
189
. expect ( "Vulkan device has no graphics queue" ) ;
150
190
151
- let vk_device = xr_instance
152
- . create_vulkan_device (
153
- system,
154
- std:: mem:: transmute ( vk_entry. static_fn ( ) . get_instance_proc_addr ) ,
155
- vk_physical_device. as_raw ( ) as _ ,
156
- & vk:: DeviceCreateInfo :: builder ( )
157
- . queue_create_infos ( & [ vk:: DeviceQueueCreateInfo :: builder ( )
158
- . queue_family_index ( queue_family_index)
159
- . queue_priorities ( & [ 1.0 ] )
160
- . build ( ) ] )
161
- . push_next ( & mut vk:: PhysicalDeviceMultiviewFeatures {
162
- multiview : vk:: TRUE ,
163
- ..Default :: default ( )
164
- } ) as * const _ as * const _ ,
165
- )
166
- . expect ( "XR error creating Vulkan device" )
167
- . map_err ( vk:: Result :: from_raw)
168
- . expect ( "Vulkan error creating Vulkan device" ) ;
169
- let vk_device =
170
- ash:: Device :: load ( vk_instance. fp_v1_0 ( ) , vk:: Device :: from_raw ( vk_device as _ ) ) ;
191
+ let vk_device = if enabled_extensions. khr_vulkan_enable2 {
192
+ let vk_device = xr_instance
193
+ . create_vulkan_device (
194
+ system,
195
+ std:: mem:: transmute ( vk_entry. static_fn ( ) . get_instance_proc_addr ) ,
196
+ vk_physical_device. as_raw ( ) as _ ,
197
+ & vk:: DeviceCreateInfo :: builder ( )
198
+ . queue_create_infos ( & [ vk:: DeviceQueueCreateInfo :: builder ( )
199
+ . queue_family_index ( queue_family_index)
200
+ . queue_priorities ( & [ 1.0 ] )
201
+ . build ( ) ] )
202
+ . push_next ( & mut vk:: PhysicalDeviceMultiviewFeatures {
203
+ multiview : vk:: TRUE ,
204
+ ..Default :: default ( )
205
+ } ) as * const _ as * const _ ,
206
+ )
207
+ . expect ( "XR error creating Vulkan device" )
208
+ . map_err ( vk:: Result :: from_raw)
209
+ . expect ( "Vulkan error creating Vulkan device" ) ;
210
+
211
+ ash:: Device :: load ( vk_instance. fp_v1_0 ( ) , vk:: Device :: from_raw ( vk_device as _ ) )
212
+ } else {
213
+ let vk_device_exts = xr_instance
214
+ . vulkan_legacy_device_extensions ( system)
215
+ . unwrap ( )
216
+ . split ( ' ' )
217
+ . map ( |x| CString :: new ( x) . unwrap ( ) )
218
+ . collect :: < Vec < _ > > ( ) ;
219
+ println ! ( "Required Vulkan device extensions: {:?}" , vk_device_exts) ;
220
+ let vk_device_ext_ptrs = vk_device_exts
221
+ . iter ( )
222
+ . map ( |x| x. as_ptr ( ) )
223
+ . collect :: < Vec < _ > > ( ) ;
224
+
225
+ // Check that we have the required Vulkan device extensions.
226
+ let device_extensions = vk_instance
227
+ . enumerate_device_extension_properties ( vk_physical_device)
228
+ . unwrap ( ) ;
229
+ for ext in & vk_device_exts {
230
+ if !device_extensions. iter ( ) . any ( |inst_ext| {
231
+ CStr :: from_ptr ( inst_ext. extension_name . as_ptr ( ) ) == ext. as_c_str ( )
232
+ } ) {
233
+ panic ! (
234
+ "OpenXR runtime requires missing Vulkan device extension {:?}" ,
235
+ ext
236
+ ) ;
237
+ }
238
+ }
239
+
240
+ vk_instance
241
+ . create_device (
242
+ vk_physical_device,
243
+ & vk:: DeviceCreateInfo :: builder ( )
244
+ . queue_create_infos ( & [ vk:: DeviceQueueCreateInfo :: builder ( )
245
+ . queue_family_index ( queue_family_index)
246
+ . queue_priorities ( & [ 1.0 ] )
247
+ . build ( ) ] )
248
+ . enabled_extension_names ( & vk_device_ext_ptrs)
249
+ . push_next ( & mut vk:: PhysicalDeviceVulkan11Features {
250
+ multiview : vk:: TRUE ,
251
+ ..Default :: default ( )
252
+ } ) ,
253
+ None ,
254
+ )
255
+ . expect ( "Vulkan error creating Vulkan device" )
256
+ } ;
171
257
172
258
let queue = vk_device. get_device_queue ( queue_family_index, 0 ) ;
173
259
@@ -762,7 +848,7 @@ fn main() {
762
848
println ! ( "exiting cleanly" ) ;
763
849
}
764
850
765
- pub const COLOR_FORMAT : vk:: Format = vk:: Format :: B8G8R8A8_SRGB ;
851
+ pub const COLOR_FORMAT : vk:: Format = vk:: Format :: R8G8B8A8_SRGB ;
766
852
pub const VIEW_COUNT : u32 = 2 ;
767
853
const VIEW_TYPE : xr:: ViewConfigurationType = xr:: ViewConfigurationType :: PRIMARY_STEREO ;
768
854
0 commit comments