1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <wrl.h>
6
7 #include "base/stl_util.h"
8 #include "device/vr/openxr/openxr_util.h"
9 #include "device/vr/openxr/test/openxr_negotiate.h"
10 #include "device/vr/openxr/test/openxr_test_helper.h"
11
12 namespace {
13 // Global test helper that communicates with the test and contains the mock
14 // OpenXR runtime state/properties. A reference to this is returned as the
15 // instance handle through xrCreateInstance.
16 OpenXrTestHelper g_test_helper;
17 } // namespace
18
19 // Extension methods
20
21 // Mock implementations of openxr runtime.dll APIs.
22 // Please add new APIs in alphabetical order.
23
xrAcquireSwapchainImage(XrSwapchain swapchain,const XrSwapchainImageAcquireInfo * acquire_info,uint32_t * index)24 XrResult xrAcquireSwapchainImage(
25 XrSwapchain swapchain,
26 const XrSwapchainImageAcquireInfo* acquire_info,
27 uint32_t* index) {
28 DVLOG(2) << __FUNCTION__;
29 RETURN_IF_XR_FAILED(g_test_helper.ValidateSwapchain(swapchain));
30 RETURN_IF(acquire_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
31 "XrSwapchainImageAcquireInfo is nullptr");
32 RETURN_IF(acquire_info->type != XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO,
33 XR_ERROR_VALIDATION_FAILURE,
34 "xrAcquireSwapchainImage type invalid");
35 RETURN_IF(acquire_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
36 "xrAcquireSwapchainImage next not nullptr");
37
38 RETURN_IF(index == nullptr, XR_ERROR_VALIDATION_FAILURE,
39 "xrAcquireSwapchainImage index is nullptr");
40 *index = g_test_helper.NextSwapchainImageIndex();
41
42 return XR_SUCCESS;
43 }
44
xrAttachSessionActionSets(XrSession session,const XrSessionActionSetsAttachInfo * attach_info)45 XrResult xrAttachSessionActionSets(
46 XrSession session,
47 const XrSessionActionSetsAttachInfo* attach_info) {
48 DVLOG(2) << __FUNCTION__;
49 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
50 RETURN_IF(attach_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
51 "XrSessionActionSetsAttachInfo is nullptr");
52 RETURN_IF_XR_FAILED(g_test_helper.AttachActionSets(*attach_info));
53
54 return XR_SUCCESS;
55 }
56
xrBeginFrame(XrSession session,const XrFrameBeginInfo * frame_begin_info)57 XrResult xrBeginFrame(XrSession session,
58 const XrFrameBeginInfo* frame_begin_info) {
59 DVLOG(2) << __FUNCTION__;
60 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
61 RETURN_IF(frame_begin_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
62 "XrFrameBeginInfo is nullptr");
63 RETURN_IF(frame_begin_info->type != XR_TYPE_FRAME_BEGIN_INFO,
64 XR_ERROR_VALIDATION_FAILURE, "XrFrameBeginInfo type invalid");
65 RETURN_IF(frame_begin_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
66 "XrFrameBeginInfo next is not nullptr");
67 return g_test_helper.BeginFrame();
68 }
69
xrBeginSession(XrSession session,const XrSessionBeginInfo * begin_info)70 XrResult xrBeginSession(XrSession session,
71 const XrSessionBeginInfo* begin_info) {
72 DVLOG(2) << __FUNCTION__;
73 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
74 RETURN_IF(begin_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
75 "XrSessionBeginInfo is nullptr");
76 RETURN_IF(begin_info->type != XR_TYPE_SESSION_BEGIN_INFO,
77 XR_ERROR_VALIDATION_FAILURE, "XrSessionBeginInfo type invalid");
78 RETURN_IF(begin_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
79 "XrSessionBeginInfo next is not nullptr");
80 RETURN_IF(begin_info->primaryViewConfigurationType !=
81 OpenXrTestHelper::kViewConfigurationType,
82 XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED,
83 "XrSessionBeginInfo primaryViewConfigurationType invalid");
84
85 RETURN_IF_XR_FAILED(g_test_helper.BeginSession());
86
87 return XR_SUCCESS;
88 }
89
xrCreateAction(XrActionSet action_set,const XrActionCreateInfo * create_info,XrAction * action)90 XrResult xrCreateAction(XrActionSet action_set,
91 const XrActionCreateInfo* create_info,
92 XrAction* action) {
93 DVLOG(2) << __FUNCTION__;
94 RETURN_IF(create_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
95 "XrActionCreateInfo is nullptr");
96 RETURN_IF_XR_FAILED(
97 g_test_helper.CreateAction(action_set, *create_info, action));
98
99 return XR_SUCCESS;
100 }
101
xrCreateActionSet(XrInstance instance,const XrActionSetCreateInfo * create_info,XrActionSet * action_set)102 XrResult xrCreateActionSet(XrInstance instance,
103 const XrActionSetCreateInfo* create_info,
104 XrActionSet* action_set) {
105 DVLOG(2) << __FUNCTION__;
106 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
107 RETURN_IF(create_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
108 "XrActionSetCreateInfo is nullptr");
109 RETURN_IF_XR_FAILED(g_test_helper.ValidateActionSetCreateInfo(*create_info));
110 RETURN_IF(action_set == nullptr, XR_ERROR_VALIDATION_FAILURE,
111 "XrActionSet is nullptr");
112 *action_set = g_test_helper.CreateActionSet(*create_info);
113
114 return XR_SUCCESS;
115 }
116
xrCreateActionSpace(XrSession session,const XrActionSpaceCreateInfo * create_info,XrSpace * space)117 XrResult xrCreateActionSpace(XrSession session,
118 const XrActionSpaceCreateInfo* create_info,
119 XrSpace* space) {
120 DVLOG(2) << __FUNCTION__;
121 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
122 RETURN_IF(create_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
123 "XrActionSpaceCreateInfo is nullptr");
124 RETURN_IF(space == nullptr, XR_ERROR_VALIDATION_FAILURE,
125 "XrSpace is nullptr");
126 RETURN_IF_XR_FAILED(g_test_helper.CreateActionSpace(*create_info, space));
127
128 return XR_SUCCESS;
129 }
130
xrCreateInstance(const XrInstanceCreateInfo * create_info,XrInstance * instance)131 XrResult xrCreateInstance(const XrInstanceCreateInfo* create_info,
132 XrInstance* instance) {
133 DVLOG(2) << __FUNCTION__;
134
135 RETURN_IF(create_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
136 "XrInstanceCreateInfo is nullptr");
137 RETURN_IF(create_info->applicationInfo.apiVersion != XR_CURRENT_API_VERSION,
138 XR_ERROR_API_VERSION_UNSUPPORTED, "apiVersion unsupported");
139
140 RETURN_IF(create_info->type != XR_TYPE_INSTANCE_CREATE_INFO,
141 XR_ERROR_VALIDATION_FAILURE, "XrInstanceCreateInfo type invalid");
142
143 RETURN_IF(create_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
144 "XrInstanceCreateInfo next is not nullptr");
145
146 RETURN_IF(create_info->createFlags != 0, XR_ERROR_VALIDATION_FAILURE,
147 "XrInstanceCreateInfo createFlags is not 0");
148
149 RETURN_IF(
150 create_info->enabledApiLayerCount != 0 ||
151 create_info->enabledApiLayerNames != nullptr,
152 XR_ERROR_VALIDATION_FAILURE,
153 "XrInstanceCreateInfo ApiLayer is not supported by this version of test");
154
155 for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
156 bool valid_extension = false;
157 for (size_t j = 0; j < OpenXrTestHelper::kNumExtensionsSupported; j++) {
158 if (strcmp(create_info->enabledExtensionNames[i],
159 OpenXrTestHelper::kExtensions[j]) == 0) {
160 valid_extension = true;
161 break;
162 }
163 }
164
165 RETURN_IF_FALSE(valid_extension, XR_ERROR_VALIDATION_FAILURE,
166 "enabledExtensionNames contains invalid extensions");
167 }
168
169 RETURN_IF(instance == nullptr, XR_ERROR_VALIDATION_FAILURE,
170 "XrInstance is nullptr");
171 *instance = g_test_helper.CreateInstance();
172
173 return XR_SUCCESS;
174 }
175
xrCreateReferenceSpace(XrSession session,const XrReferenceSpaceCreateInfo * create_info,XrSpace * space)176 XrResult xrCreateReferenceSpace(XrSession session,
177 const XrReferenceSpaceCreateInfo* create_info,
178 XrSpace* space) {
179 DVLOG(2) << __FUNCTION__;
180 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
181 RETURN_IF(create_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
182 "XrReferenceSpaceCreateInfo is nullptr");
183 RETURN_IF(create_info->type != XR_TYPE_REFERENCE_SPACE_CREATE_INFO,
184 XR_ERROR_VALIDATION_FAILURE,
185 "XrReferenceSpaceCreateInfo type invalid");
186 RETURN_IF(create_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
187 "XrReferenceSpaceCreateInfo next is not nullptr");
188 RETURN_IF(
189 create_info->referenceSpaceType != XR_REFERENCE_SPACE_TYPE_LOCAL &&
190 create_info->referenceSpaceType != XR_REFERENCE_SPACE_TYPE_VIEW &&
191 create_info->referenceSpaceType != XR_REFERENCE_SPACE_TYPE_STAGE &&
192 create_info->referenceSpaceType !=
193 XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT,
194 XR_ERROR_REFERENCE_SPACE_UNSUPPORTED,
195 "XrReferenceSpaceCreateInfo referenceSpaceType invalid");
196 RETURN_IF_XR_FAILED(g_test_helper.ValidateXrPosefIsIdentity(
197 create_info->poseInReferenceSpace));
198 RETURN_IF(space == nullptr, XR_ERROR_VALIDATION_FAILURE,
199 "XrSpace is nullptr");
200 *space = g_test_helper.CreateReferenceSpace(create_info->referenceSpaceType);
201
202 return XR_SUCCESS;
203 }
204
xrCreateSession(XrInstance instance,const XrSessionCreateInfo * create_info,XrSession * session)205 XrResult xrCreateSession(XrInstance instance,
206 const XrSessionCreateInfo* create_info,
207 XrSession* session) {
208 DVLOG(2) << __FUNCTION__;
209 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
210 RETURN_IF(create_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
211 "XrSessionCreateInfo is nullptr");
212 RETURN_IF(create_info->type != XR_TYPE_SESSION_CREATE_INFO,
213 XR_ERROR_VALIDATION_FAILURE, "XrSessionCreateInfo type invalid");
214 RETURN_IF(create_info->createFlags != 0, XR_ERROR_VALIDATION_FAILURE,
215 "XrSessionCreateInfo createFlags is not 0");
216 RETURN_IF_XR_FAILED(g_test_helper.ValidateSystemId(create_info->systemId));
217
218 const XrGraphicsBindingD3D11KHR* binding =
219 static_cast<const XrGraphicsBindingD3D11KHR*>(create_info->next);
220 RETURN_IF(binding->type != XR_TYPE_GRAPHICS_BINDING_D3D11_KHR,
221 XR_ERROR_VALIDATION_FAILURE,
222 "XrGraphicsBindingD3D11KHR type invalid");
223 RETURN_IF(binding->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
224 "XrGraphicsBindingD3D11KHR next is not nullptr");
225 RETURN_IF(binding->device == nullptr, XR_ERROR_VALIDATION_FAILURE,
226 "D3D11Device is nullptr");
227
228 g_test_helper.SetD3DDevice(binding->device);
229 RETURN_IF(session == nullptr, XR_ERROR_VALIDATION_FAILURE,
230 "XrSession is nullptr");
231 RETURN_IF_XR_FAILED(g_test_helper.GetSession(session));
232
233 return XR_SUCCESS;
234 }
235
xrCreateSwapchain(XrSession session,const XrSwapchainCreateInfo * create_info,XrSwapchain * swapchain)236 XrResult xrCreateSwapchain(XrSession session,
237 const XrSwapchainCreateInfo* create_info,
238 XrSwapchain* swapchain) {
239 DVLOG(2) << __FUNCTION__;
240 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
241 RETURN_IF(create_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
242 "XrSwapchainCreateInfo is nullptr");
243 RETURN_IF(create_info->type != XR_TYPE_SWAPCHAIN_CREATE_INFO,
244 XR_ERROR_VALIDATION_FAILURE, "XrSwapchainCreateInfo type invalid");
245 RETURN_IF(create_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
246 "XrSwapchainCreateInfo next is not nullptr");
247 RETURN_IF(create_info->createFlags != 0, XR_ERROR_VALIDATION_FAILURE,
248 "XrSwapchainCreateInfo createFlags is not 0");
249 RETURN_IF(create_info->usageFlags != XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT,
250 XR_ERROR_VALIDATION_FAILURE,
251 "XrSwapchainCreateInfo usageFlags is not "
252 "XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT");
253 RETURN_IF(create_info->format != DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
254 XR_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED,
255 "XrSwapchainCreateInfo format unsupported");
256 RETURN_IF(create_info->sampleCount != OpenXrTestHelper::kSwapCount,
257 XR_ERROR_VALIDATION_FAILURE,
258 "XrSwapchainCreateInfo sampleCount invalid");
259 RETURN_IF(create_info->width != OpenXrTestHelper::kDimension * 2,
260 XR_ERROR_VALIDATION_FAILURE,
261 "XrSwapchainCreateInfo width is not dimension * 2");
262 RETURN_IF(create_info->height != OpenXrTestHelper::kDimension,
263 XR_ERROR_VALIDATION_FAILURE,
264 "XrSwapchainCreateInfo height is not dimension");
265 RETURN_IF(create_info->faceCount != 1, XR_ERROR_VALIDATION_FAILURE,
266 "XrSwapchainCreateInfo faceCount is not 1");
267 RETURN_IF(create_info->arraySize != 1, XR_ERROR_VALIDATION_FAILURE,
268 "XrSwapchainCreateInfo arraySize invalid");
269 RETURN_IF(create_info->mipCount != 1, XR_ERROR_VALIDATION_FAILURE,
270 "XrSwapchainCreateInfo mipCount is not 1");
271
272 RETURN_IF(swapchain == nullptr, XR_ERROR_VALIDATION_FAILURE,
273 "XrSwapchain is nullptr");
274 *swapchain = g_test_helper.GetSwapchain();
275
276 return XR_SUCCESS;
277 }
278
xrDestroyActionSet(XrActionSet action_set)279 XrResult xrDestroyActionSet(XrActionSet action_set) {
280 DVLOG(2) << __FUNCTION__;
281 RETURN_IF_XR_FAILED(g_test_helper.ValidateActionSet(action_set));
282 return XR_SUCCESS;
283 }
284
xrDestroyInstance(XrInstance instance)285 XrResult xrDestroyInstance(XrInstance instance) {
286 DVLOG(2) << __FUNCTION__;
287 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
288 g_test_helper.Reset();
289 return XR_SUCCESS;
290 }
291
xrDestroySession(XrSession session)292 XrResult xrDestroySession(XrSession session) {
293 DVLOG(2) << __FUNCTION__;
294 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
295 return XR_SUCCESS;
296 }
297
xrDestroySpace(XrSpace space)298 XrResult xrDestroySpace(XrSpace space) {
299 DVLOG(2) << __FUNCTION__;
300 RETURN_IF_XR_FAILED(g_test_helper.ValidateSpace(space));
301
302 return XR_SUCCESS;
303 }
304
xrEndFrame(XrSession session,const XrFrameEndInfo * frame_end_info)305 XrResult xrEndFrame(XrSession session, const XrFrameEndInfo* frame_end_info) {
306 DVLOG(2) << __FUNCTION__;
307 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
308 RETURN_IF(frame_end_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
309 "XrFrameEndInfo is nullptr");
310 RETURN_IF(frame_end_info->type != XR_TYPE_FRAME_END_INFO,
311 XR_ERROR_VALIDATION_FAILURE, "XrFrameEndInfo type invalid");
312 RETURN_IF(frame_end_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
313 "XrFrameEndInfo next is not nullptr");
314 RETURN_IF_XR_FAILED(
315 g_test_helper.ValidatePredictedDisplayTime(frame_end_info->displayTime));
316 RETURN_IF(frame_end_info->environmentBlendMode !=
317 OpenXrTestHelper::kEnvironmentBlendMode,
318 XR_ERROR_VALIDATION_FAILURE,
319 "XrFrameEndInfo environmentBlendMode invalid");
320 RETURN_IF(frame_end_info->layerCount != 1, XR_ERROR_VALIDATION_FAILURE,
321 "XrFrameEndInfo layerCount invalid");
322 RETURN_IF(frame_end_info->layers == nullptr, XR_ERROR_LAYER_INVALID,
323 "XrFrameEndInfo has nullptr layers");
324
325 for (uint32_t i = 0; i < frame_end_info->layerCount; i++) {
326 const XrCompositionLayerProjection* multi_projection_layer_ptr =
327 reinterpret_cast<const XrCompositionLayerProjection*>(
328 frame_end_info->layers[i]);
329 RETURN_IF_XR_FAILED(g_test_helper.ValidateXrCompositionLayerProjection(
330 *multi_projection_layer_ptr));
331 }
332
333 RETURN_IF_XR_FAILED(g_test_helper.EndFrame());
334 g_test_helper.OnPresentedFrame();
335 return XR_SUCCESS;
336 }
337
xrEndSession(XrSession session)338 XrResult xrEndSession(XrSession session) {
339 DVLOG(2) << __FUNCTION__;
340 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
341 RETURN_IF_XR_FAILED(g_test_helper.EndSession());
342
343 return XR_SUCCESS;
344 }
345
xrEnumerateEnvironmentBlendModes(XrInstance instance,XrSystemId system_id,XrViewConfigurationType view_configuration_type,uint32_t environment_blend_mode_capacity_input,uint32_t * environment_blend_mode_count_output,XrEnvironmentBlendMode * environment_blend_modes)346 XrResult xrEnumerateEnvironmentBlendModes(
347 XrInstance instance,
348 XrSystemId system_id,
349 XrViewConfigurationType view_configuration_type,
350 uint32_t environment_blend_mode_capacity_input,
351 uint32_t* environment_blend_mode_count_output,
352 XrEnvironmentBlendMode* environment_blend_modes) {
353 DVLOG(2) << __FUNCTION__;
354 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
355 RETURN_IF_XR_FAILED(g_test_helper.ValidateSystemId(system_id));
356 RETURN_IF(view_configuration_type != OpenXrTestHelper::kViewConfigurationType,
357 XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED,
358 "xrEnumerateEnvironmentBlendModes viewConfigurationType invalid");
359
360 RETURN_IF(environment_blend_mode_count_output == nullptr,
361 XR_ERROR_VALIDATION_FAILURE,
362 "environment_blend_mode_count_output is nullptr");
363 *environment_blend_mode_count_output = 1;
364 if (environment_blend_mode_capacity_input == 0) {
365 return XR_SUCCESS;
366 }
367
368 RETURN_IF(environment_blend_mode_capacity_input != 1,
369 XR_ERROR_VALIDATION_FAILURE,
370 "environment_blend_mode_capacity_input is neither 0 or 1");
371 RETURN_IF(environment_blend_modes == nullptr, XR_ERROR_VALIDATION_FAILURE,
372 "XrEnvironmentBlendMode is nullptr");
373 *environment_blend_modes = OpenXrTestHelper::kEnvironmentBlendMode;
374
375 return XR_SUCCESS;
376 }
377
378 // Even thought xrEnumerateInstanceExtensionProperties is not directly called
379 // in our implementation, it is used inside loader so this function mock is
380 // needed
xrEnumerateInstanceExtensionProperties(const char * layer_name,uint32_t property_capacity_input,uint32_t * property_count_output,XrExtensionProperties * properties)381 XrResult xrEnumerateInstanceExtensionProperties(
382 const char* layer_name,
383 uint32_t property_capacity_input,
384 uint32_t* property_count_output,
385 XrExtensionProperties* properties) {
386 DVLOG(2) << __FUNCTION__;
387
388 RETURN_IF(
389 property_capacity_input < OpenXrTestHelper::kNumExtensionsSupported &&
390 property_capacity_input != 0,
391 XR_ERROR_SIZE_INSUFFICIENT, "XrExtensionProperties array is too small");
392
393 RETURN_IF(property_count_output == nullptr, XR_ERROR_VALIDATION_FAILURE,
394 "property_count_output is nullptr");
395 *property_count_output = OpenXrTestHelper::kNumExtensionsSupported;
396 if (property_capacity_input == 0) {
397 return XR_SUCCESS;
398 }
399
400 RETURN_IF(
401 property_capacity_input != OpenXrTestHelper::kNumExtensionsSupported,
402 XR_ERROR_VALIDATION_FAILURE,
403 "property_capacity_input is neither 0 or kNumExtensionsSupported");
404 RETURN_IF(properties == nullptr, XR_ERROR_VALIDATION_FAILURE,
405 "XrExtensionProperties is nullptr");
406 for (uint32_t i = 0; i < OpenXrTestHelper::kNumExtensionsSupported; i++) {
407 properties[i].type = XR_TYPE_EXTENSION_PROPERTIES;
408 errno_t error = strcpy_s(properties[i].extensionName,
409 base::size(properties[i].extensionName),
410 OpenXrTestHelper::kExtensions[i]);
411 DCHECK(error == 0);
412 properties[i].extensionVersion = 1;
413 }
414
415 return XR_SUCCESS;
416 }
417
xrEnumerateViewConfigurationViews(XrInstance instance,XrSystemId system_id,XrViewConfigurationType view_configuration_type,uint32_t view_capacity_input,uint32_t * view_count_output,XrViewConfigurationView * views)418 XrResult xrEnumerateViewConfigurationViews(
419 XrInstance instance,
420 XrSystemId system_id,
421 XrViewConfigurationType view_configuration_type,
422 uint32_t view_capacity_input,
423 uint32_t* view_count_output,
424 XrViewConfigurationView* views) {
425 DVLOG(2) << __FUNCTION__;
426 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
427 RETURN_IF_XR_FAILED(g_test_helper.ValidateSystemId(system_id));
428 RETURN_IF(view_configuration_type != OpenXrTestHelper::kViewConfigurationType,
429 XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED,
430 "xrEnumerateViewConfigurationViews viewConfigurationType invalid");
431 RETURN_IF(view_count_output == nullptr, XR_ERROR_VALIDATION_FAILURE,
432 "view_count_output is nullptr");
433 *view_count_output = OpenXrTestHelper::kNumViews;
434 if (view_capacity_input == 0) {
435 return XR_SUCCESS;
436 }
437
438 RETURN_IF(view_capacity_input != OpenXrTestHelper::kNumViews,
439 XR_ERROR_VALIDATION_FAILURE,
440 "view_capacity_input is neither 0 or kNumViews");
441 RETURN_IF(views == nullptr, XR_ERROR_VALIDATION_FAILURE,
442 "XrViewConfigurationView is nullptr");
443 views[0] = OpenXrTestHelper::kViewConfigurationViews[0];
444 views[1] = OpenXrTestHelper::kViewConfigurationViews[1];
445
446 return XR_SUCCESS;
447 }
448
xrEnumerateSwapchainImages(XrSwapchain swapchain,uint32_t image_capacity_input,uint32_t * image_count_output,XrSwapchainImageBaseHeader * images)449 XrResult xrEnumerateSwapchainImages(XrSwapchain swapchain,
450 uint32_t image_capacity_input,
451 uint32_t* image_count_output,
452 XrSwapchainImageBaseHeader* images) {
453 DVLOG(2) << __FUNCTION__;
454 RETURN_IF_XR_FAILED(g_test_helper.ValidateSwapchain(swapchain));
455 RETURN_IF(image_capacity_input != OpenXrTestHelper::kMinSwapchainBuffering &&
456 image_capacity_input != 0,
457 XR_ERROR_SIZE_INSUFFICIENT,
458 "xrEnumerateSwapchainImages does not equal length returned by "
459 "xrCreateSwapchain");
460
461 RETURN_IF(image_count_output == nullptr, XR_ERROR_VALIDATION_FAILURE,
462 "image_capacity_input is nullptr");
463 *image_count_output = OpenXrTestHelper::kMinSwapchainBuffering;
464 if (image_capacity_input == 0) {
465 return XR_SUCCESS;
466 }
467
468 RETURN_IF(image_capacity_input != OpenXrTestHelper::kMinSwapchainBuffering,
469 XR_ERROR_VALIDATION_FAILURE,
470 "image_capacity_input is neither 0 or kMinSwapchainBuffering");
471 RETURN_IF(images == nullptr, XR_ERROR_VALIDATION_FAILURE,
472 "XrSwapchainImageBaseHeader is nullptr");
473 const std::vector<Microsoft::WRL::ComPtr<ID3D11Texture2D>>& textures =
474 g_test_helper.GetSwapchainTextures();
475 DCHECK(textures.size() == image_capacity_input);
476
477 for (uint32_t i = 0; i < image_capacity_input; i++) {
478 XrSwapchainImageD3D11KHR& image =
479 reinterpret_cast<XrSwapchainImageD3D11KHR*>(images)[i];
480
481 RETURN_IF(image.type != XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR,
482 XR_ERROR_VALIDATION_FAILURE,
483 "XrSwapchainImageD3D11KHR type invalid");
484 RETURN_IF(image.next != nullptr, XR_ERROR_VALIDATION_FAILURE,
485 "XrSwapchainImageD3D11KHR next is not nullptr");
486
487 image.texture = textures[i].Get();
488 }
489
490 return XR_SUCCESS;
491 }
492
xrGetD3D11GraphicsRequirementsKHR(XrInstance instance,XrSystemId system_id,XrGraphicsRequirementsD3D11KHR * graphics_requirements)493 XrResult xrGetD3D11GraphicsRequirementsKHR(
494 XrInstance instance,
495 XrSystemId system_id,
496 XrGraphicsRequirementsD3D11KHR* graphics_requirements) {
497 DVLOG(2) << __FUNCTION__;
498 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
499 RETURN_IF_XR_FAILED(g_test_helper.ValidateSystemId(system_id));
500 RETURN_IF(graphics_requirements == nullptr, XR_ERROR_VALIDATION_FAILURE,
501 "XrGraphicsRequirementsD3D11KHR is nullptr");
502 RETURN_IF(
503 graphics_requirements->type != XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR,
504 XR_ERROR_VALIDATION_FAILURE,
505 "XrGraphicsRequirementsD3D11KHR type invalid");
506 RETURN_IF(graphics_requirements->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
507 "XrGraphicsRequirementsD3D11KHR next is not nullptr");
508
509 Microsoft::WRL::ComPtr<IDXGIFactory1> dxgi_factory;
510 Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
511 HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgi_factory));
512 DCHECK(SUCCEEDED(hr));
513 if (SUCCEEDED(dxgi_factory->EnumAdapters(0, &adapter))) {
514 DXGI_ADAPTER_DESC desc;
515 adapter->GetDesc(&desc);
516 graphics_requirements->adapterLuid = desc.AdapterLuid;
517
518 // Require D3D11.1 to support shared NT handles.
519 graphics_requirements->minFeatureLevel = D3D_FEATURE_LEVEL_11_1;
520
521 return XR_SUCCESS;
522 }
523
524 RETURN_IF_FALSE(false, XR_ERROR_VALIDATION_FAILURE,
525 "Unable to create query DXGI Adapter");
526 }
527
xrGetActionStateFloat(XrSession session,const XrActionStateGetInfo * get_info,XrActionStateFloat * state)528 XrResult xrGetActionStateFloat(XrSession session,
529 const XrActionStateGetInfo* get_info,
530 XrActionStateFloat* state) {
531 DVLOG(2) << __FUNCTION__;
532 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
533 RETURN_IF(get_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
534 "XrActionStateGetInfo is nullptr");
535 RETURN_IF(get_info->type != XR_TYPE_ACTION_STATE_GET_INFO,
536 XR_ERROR_VALIDATION_FAILURE,
537 "xrGetActionStateFloat has wrong type");
538 RETURN_IF(get_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
539 "xrGetActionStateFloat next is not nullptr");
540 RETURN_IF_XR_FAILED(g_test_helper.ValidateAction(get_info->action));
541 RETURN_IF(get_info->subactionPath != XR_NULL_PATH,
542 XR_ERROR_VALIDATION_FAILURE,
543 "xrGetActionStateFloat has subactionPath != nullptr which is not "
544 "supported by current version of test.");
545 RETURN_IF_XR_FAILED(
546 g_test_helper.GetActionStateFloat(get_info->action, state));
547
548 return XR_SUCCESS;
549 }
550
xrGetActionStateBoolean(XrSession session,const XrActionStateGetInfo * get_info,XrActionStateBoolean * state)551 XrResult xrGetActionStateBoolean(XrSession session,
552 const XrActionStateGetInfo* get_info,
553 XrActionStateBoolean* state) {
554 DVLOG(2) << __FUNCTION__;
555 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
556 RETURN_IF(get_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
557 "XrActionStateGetInfo is nullptr");
558 RETURN_IF(get_info->type != XR_TYPE_ACTION_STATE_GET_INFO,
559 XR_ERROR_VALIDATION_FAILURE,
560 "xrGetActionStateBoolean get_info has wrong type");
561 RETURN_IF(get_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
562 "xrGetActionStateBoolean next is not nullptr");
563 RETURN_IF_XR_FAILED(g_test_helper.ValidateAction(get_info->action));
564 RETURN_IF(get_info->subactionPath != XR_NULL_PATH,
565 XR_ERROR_VALIDATION_FAILURE,
566 "xrGetActionStateBoolean has subactionPath != nullptr which is not "
567 "supported by current version of test.");
568 RETURN_IF_XR_FAILED(
569 g_test_helper.GetActionStateBoolean(get_info->action, state));
570
571 return XR_SUCCESS;
572 }
573
xrGetActionStateVector2f(XrSession session,const XrActionStateGetInfo * get_info,XrActionStateVector2f * state)574 XrResult xrGetActionStateVector2f(XrSession session,
575 const XrActionStateGetInfo* get_info,
576 XrActionStateVector2f* state) {
577 DVLOG(2) << __FUNCTION__;
578 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
579 RETURN_IF(get_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
580 "XrActionStateGetInfo is nullptr");
581 RETURN_IF(get_info->type != XR_TYPE_ACTION_STATE_GET_INFO,
582 XR_ERROR_VALIDATION_FAILURE,
583 "xrGetActionStateVector2f get_info has wrong type");
584 RETURN_IF(get_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
585 "xrGetActionStateVector2f next is not nullptr");
586 RETURN_IF_XR_FAILED(g_test_helper.ValidateAction(get_info->action));
587 RETURN_IF(
588 get_info->subactionPath != XR_NULL_PATH, XR_ERROR_VALIDATION_FAILURE,
589 "xrGetActionStateVector2f has subactionPath != nullptr which is not "
590 "supported by current version of test.");
591 RETURN_IF_XR_FAILED(
592 g_test_helper.GetActionStateVector2f(get_info->action, state));
593
594 return XR_SUCCESS;
595 }
596
xrGetActionStatePose(XrSession session,const XrActionStateGetInfo * get_info,XrActionStatePose * state)597 XrResult xrGetActionStatePose(XrSession session,
598 const XrActionStateGetInfo* get_info,
599 XrActionStatePose* state) {
600 DVLOG(2) << __FUNCTION__;
601 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
602 RETURN_IF(get_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
603 "XrActionStateGetInfo is nullptr");
604 RETURN_IF(get_info->type != XR_TYPE_ACTION_STATE_GET_INFO,
605 XR_ERROR_VALIDATION_FAILURE,
606 "xrGetActionStatePose get_info has wrong type");
607 RETURN_IF(get_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
608 "xrGetActionStatePose next is not nullptr");
609 RETURN_IF_XR_FAILED(g_test_helper.ValidateAction(get_info->action));
610 RETURN_IF(get_info->subactionPath != XR_NULL_PATH,
611 XR_ERROR_VALIDATION_FAILURE,
612 "xrGetActionStatePose has subactionPath != nullptr which is not "
613 "supported by current version of test.");
614 RETURN_IF_XR_FAILED(
615 g_test_helper.GetActionStatePose(get_info->action, state));
616
617 return XR_SUCCESS;
618 }
619
xrGetCurrentInteractionProfile(XrSession session,XrPath top_level_user_path,XrInteractionProfileState * interaction_profile)620 XrResult xrGetCurrentInteractionProfile(
621 XrSession session,
622 XrPath top_level_user_path,
623 XrInteractionProfileState* interaction_profile) {
624 DVLOG(1) << __FUNCTION__;
625 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
626 RETURN_IF(
627 g_test_helper.AttachedActionSetsSize() == 0,
628 XR_ERROR_ACTIONSET_NOT_ATTACHED,
629 "xrGetCurrentInteractionProfile action sets have not been attached yet");
630 RETURN_IF_XR_FAILED(g_test_helper.ValidatePath(top_level_user_path));
631 RETURN_IF(interaction_profile == nullptr, XR_ERROR_VALIDATION_FAILURE,
632 "XrInteractionProfileState is nullptr");
633 RETURN_IF(interaction_profile->type != XR_TYPE_INTERACTION_PROFILE_STATE,
634 XR_ERROR_VALIDATION_FAILURE,
635 "xrGetCurrentInteractionProfile type is not "
636 "XR_TYPE_INTERACTION_PROFILE_STATE");
637 RETURN_IF(interaction_profile->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
638 "xrGetCurrentInteractionProfile next is not "
639 "nullptr");
640 interaction_profile->interactionProfile =
641 g_test_helper.GetCurrentInteractionProfile();
642 return XR_SUCCESS;
643 }
644
xrGetReferenceSpaceBoundsRect(XrSession session,XrReferenceSpaceType refernece_space_type,XrExtent2Df * bounds)645 XrResult xrGetReferenceSpaceBoundsRect(
646 XrSession session,
647 XrReferenceSpaceType refernece_space_type,
648 XrExtent2Df* bounds) {
649 DVLOG(2) << __FUNCTION__;
650 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
651 RETURN_IF(refernece_space_type != XR_REFERENCE_SPACE_TYPE_STAGE,
652 XR_ERROR_REFERENCE_SPACE_UNSUPPORTED,
653 "xrGetReferenceSpaceBoundsRect type is not stage");
654 RETURN_IF(bounds == nullptr, XR_ERROR_VALIDATION_FAILURE,
655 "XrExtent2Df is nullptr");
656 bounds->width = 0;
657 bounds->height = 0;
658 return XR_SUCCESS;
659 }
660
xrGetSystem(XrInstance instance,const XrSystemGetInfo * get_info,XrSystemId * system_id)661 XrResult xrGetSystem(XrInstance instance,
662 const XrSystemGetInfo* get_info,
663 XrSystemId* system_id) {
664 DVLOG(2) << __FUNCTION__;
665 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
666 RETURN_IF(get_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
667 "XrSystemGetInfo is nullptr");
668 RETURN_IF(get_info->type != XR_TYPE_SYSTEM_GET_INFO,
669 XR_ERROR_VALIDATION_FAILURE, "XrSystemGetInfo type invalid");
670 RETURN_IF(get_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
671 "XrSystemGetInfo next is not nullptr");
672 RETURN_IF(get_info->formFactor != XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY,
673 XR_ERROR_VALIDATION_FAILURE, "XrSystemGetInfo formFactor invalid");
674
675 RETURN_IF(system_id == nullptr, XR_ERROR_VALIDATION_FAILURE,
676 "XrSystemId is nullptr");
677 *system_id = g_test_helper.GetSystemId();
678
679 return XR_SUCCESS;
680 }
681
xrLocateSpace(XrSpace space,XrSpace base_space,XrTime time,XrSpaceLocation * location)682 XrResult xrLocateSpace(XrSpace space,
683 XrSpace base_space,
684 XrTime time,
685 XrSpaceLocation* location) {
686 DVLOG(2) << __FUNCTION__;
687 RETURN_IF_XR_FAILED(g_test_helper.ValidateSpace(space));
688 RETURN_IF_XR_FAILED(g_test_helper.ValidateSpace(base_space));
689 RETURN_IF_XR_FAILED(g_test_helper.ValidatePredictedDisplayTime(time));
690
691 RETURN_IF(location == nullptr, XR_ERROR_VALIDATION_FAILURE,
692 "XrSpaceLocation is nullptr");
693 g_test_helper.LocateSpace(space, &(location->pose));
694
695 location->locationFlags = XR_SPACE_LOCATION_ORIENTATION_VALID_BIT |
696 XR_SPACE_LOCATION_POSITION_VALID_BIT |
697 XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT |
698 XR_SPACE_LOCATION_POSITION_TRACKED_BIT;
699
700 return XR_SUCCESS;
701 }
702
xrLocateViews(XrSession session,const XrViewLocateInfo * view_locate_info,XrViewState * view_state,uint32_t view_capacity_input,uint32_t * view_count_output,XrView * views)703 XrResult xrLocateViews(XrSession session,
704 const XrViewLocateInfo* view_locate_info,
705 XrViewState* view_state,
706 uint32_t view_capacity_input,
707 uint32_t* view_count_output,
708 XrView* views) {
709 DVLOG(2) << __FUNCTION__;
710 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
711 RETURN_IF(view_locate_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
712 "XrViewLocateInfo is nullptr");
713 RETURN_IF(view_locate_info->type != XR_TYPE_VIEW_LOCATE_INFO,
714 XR_ERROR_VALIDATION_FAILURE,
715 "xrLocateViews view_locate_info type invalid");
716 RETURN_IF(view_locate_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
717 "XrViewLocateInfo next is not nullptr");
718 RETURN_IF(view_locate_info->viewConfigurationType !=
719 OpenXrTestHelper::kViewConfigurationType,
720 XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED,
721 "XrViewLocateInfo viewConfigurationType invalid");
722 RETURN_IF_XR_FAILED(g_test_helper.ValidatePredictedDisplayTime(
723 view_locate_info->displayTime));
724 RETURN_IF_XR_FAILED(g_test_helper.ValidateSpace(view_locate_info->space));
725 RETURN_IF(view_state == nullptr, XR_ERROR_VALIDATION_FAILURE,
726 "XrViewState is nullptr");
727 RETURN_IF(view_count_output == nullptr, XR_ERROR_VALIDATION_FAILURE,
728 "view_count_output is nullptr");
729 *view_count_output = OpenXrTestHelper::kViewCount;
730 if (view_capacity_input == 0) {
731 return XR_SUCCESS;
732 }
733
734 RETURN_IF(view_capacity_input != OpenXrTestHelper::kViewCount,
735 XR_ERROR_VALIDATION_FAILURE,
736 "view_capacity_input is neither 0 or OpenXrTestHelper::kViewCount");
737 RETURN_IF_XR_FAILED(g_test_helper.ValidateViews(view_capacity_input, views));
738 RETURN_IF_FALSE(g_test_helper.UpdateViewFOV(views, view_capacity_input),
739 XR_ERROR_VALIDATION_FAILURE,
740 "xrLocateViews UpdateViewFOV failed");
741 view_state->viewStateFlags =
742 XR_VIEW_STATE_POSITION_VALID_BIT | XR_VIEW_STATE_ORIENTATION_VALID_BIT;
743
744 return XR_SUCCESS;
745 }
746
xrPollEvent(XrInstance instance,XrEventDataBuffer * event_data)747 XrResult xrPollEvent(XrInstance instance, XrEventDataBuffer* event_data) {
748 DVLOG(2) << __FUNCTION__;
749 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
750
751 return g_test_helper.PollEvent(event_data);
752 }
753
xrReleaseSwapchainImage(XrSwapchain swapchain,const XrSwapchainImageReleaseInfo * release_info)754 XrResult xrReleaseSwapchainImage(
755 XrSwapchain swapchain,
756 const XrSwapchainImageReleaseInfo* release_info) {
757 DVLOG(2) << __FUNCTION__;
758 RETURN_IF_XR_FAILED(g_test_helper.ValidateSwapchain(swapchain));
759 RETURN_IF(release_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
760 "XrSwapchainImageReleaseInfo is nullptr");
761 RETURN_IF(release_info->type != XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO,
762 XR_ERROR_VALIDATION_FAILURE,
763 "XrSwapchainImageReleaseInfo type invalid");
764 RETURN_IF(release_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
765 "XrSwapchainImageReleaseInfo next is not nullptr");
766
767 return XR_SUCCESS;
768 }
769
xrSuggestInteractionProfileBindings(XrInstance instance,const XrInteractionProfileSuggestedBinding * suggested_bindings)770 XrResult xrSuggestInteractionProfileBindings(
771 XrInstance instance,
772 const XrInteractionProfileSuggestedBinding* suggested_bindings) {
773 DVLOG(2) << __FUNCTION__;
774 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
775 RETURN_IF(suggested_bindings == nullptr, XR_ERROR_VALIDATION_FAILURE,
776 "XrInteractionProfileSuggestedBinding is nullptr");
777 RETURN_IF(
778 suggested_bindings->type != XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING,
779 XR_ERROR_VALIDATION_FAILURE,
780 "xrSetInteractionProfileSuggestedBindings type invalid");
781 RETURN_IF(suggested_bindings->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
782 "xrSetInteractionProfileSuggestedBindings next is not nullptr");
783 RETURN_IF_XR_FAILED(
784 g_test_helper.ValidatePath(suggested_bindings->interactionProfile));
785 std::string interaction_profile =
786 g_test_helper.PathToString(suggested_bindings->interactionProfile);
787
788 RETURN_IF(suggested_bindings->suggestedBindings == nullptr,
789 XR_ERROR_VALIDATION_FAILURE,
790 "XrInteractionProfileSuggestedBinding has nullptr "
791 "XrActionSuggestedBinding");
792 RETURN_IF(g_test_helper.AttachedActionSetsSize() != 0,
793 XR_ERROR_ACTIONSETS_ALREADY_ATTACHED,
794 "xrSuggestInteractionProfileBindings called after "
795 "xrAttachSessionActionSets");
796 for (uint32_t i = 0; i < suggested_bindings->countSuggestedBindings; i++) {
797 XrActionSuggestedBinding suggestedBinding =
798 suggested_bindings->suggestedBindings[i];
799 RETURN_IF_XR_FAILED(g_test_helper.BindActionAndPath(
800 suggested_bindings->interactionProfile, suggestedBinding));
801 }
802
803 return XR_SUCCESS;
804 }
805
xrStringToPath(XrInstance instance,const char * path_string,XrPath * path)806 XrResult xrStringToPath(XrInstance instance,
807 const char* path_string,
808 XrPath* path) {
809 DVLOG(2) << __FUNCTION__;
810 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
811 RETURN_IF(path == nullptr, XR_ERROR_VALIDATION_FAILURE, "path is nullptr");
812 *path = g_test_helper.GetPath(path_string);
813
814 return XR_SUCCESS;
815 }
816
xrPathToString(XrInstance instance,XrPath path,uint32_t buffer_capacity_input,uint32_t * buffer_count_output,char * buffer)817 XrResult xrPathToString(XrInstance instance,
818 XrPath path,
819 uint32_t buffer_capacity_input,
820 uint32_t* buffer_count_output,
821 char* buffer) {
822 DVLOG(2) << __FUNCTION__;
823 RETURN_IF_XR_FAILED(g_test_helper.ValidateInstance(instance));
824 RETURN_IF_XR_FAILED(g_test_helper.ValidatePath(path));
825
826 std::string path_string = g_test_helper.PathToString(path);
827 RETURN_IF(buffer_count_output == nullptr, XR_ERROR_VALIDATION_FAILURE,
828 "buffer_count_output is nullptr");
829 // OpenXR spec counts terminating '\0'
830 *buffer_count_output = path_string.size() + 1;
831 if (buffer_capacity_input == 0) {
832 return XR_SUCCESS;
833 }
834
835 RETURN_IF(
836 buffer_capacity_input <= path_string.size(), XR_ERROR_SIZE_INSUFFICIENT,
837 "xrPathToString inputsize is not large enough to hold the output string");
838 errno_t error = strcpy_s(buffer, *buffer_count_output, path_string.data());
839 DCHECK(error == 0);
840
841 return XR_SUCCESS;
842 }
843
xrSyncActions(XrSession session,const XrActionsSyncInfo * sync_info)844 XrResult xrSyncActions(XrSession session, const XrActionsSyncInfo* sync_info) {
845 DVLOG(2) << __FUNCTION__;
846 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
847 RETURN_IF_FALSE(g_test_helper.UpdateData(), XR_ERROR_VALIDATION_FAILURE,
848 "xrSyncActionData can't receive data from test");
849 RETURN_IF(sync_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
850 "XrActionsSyncInfo is nullptr");
851 RETURN_IF(sync_info->type != XR_TYPE_ACTIONS_SYNC_INFO,
852 XR_ERROR_VALIDATION_FAILURE, "XrActionsSyncInfo type invalid");
853 RETURN_IF(sync_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
854 "XrActionsSyncInfo next is not nullptr");
855 RETURN_IF(sync_info->activeActionSets == nullptr, XR_ERROR_VALIDATION_FAILURE,
856 "XrActionsSyncInfo activeActionSets is nullptr");
857
858 for (uint32_t i = 0; i < sync_info->countActiveActionSets; i++) {
859 RETURN_IF(
860 sync_info->activeActionSets[i].subactionPath != XR_NULL_PATH,
861 XR_ERROR_VALIDATION_FAILURE,
862 "xrSyncActionData does not support use of subactionPath for test yet");
863 RETURN_IF_XR_FAILED(
864 g_test_helper.SyncActionData(sync_info->activeActionSets[i].actionSet));
865 }
866
867 return XR_SUCCESS;
868 }
869
xrWaitFrame(XrSession session,const XrFrameWaitInfo * frame_wait_info,XrFrameState * frame_state)870 XrResult xrWaitFrame(XrSession session,
871 const XrFrameWaitInfo* frame_wait_info,
872 XrFrameState* frame_state) {
873 DVLOG(2) << __FUNCTION__;
874 RETURN_IF_XR_FAILED(g_test_helper.ValidateSession(session));
875 RETURN_IF(frame_wait_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
876 "XrFrameWaitInfo is nullptr");
877 RETURN_IF(frame_wait_info->type != XR_TYPE_FRAME_WAIT_INFO,
878 XR_ERROR_VALIDATION_FAILURE, "frame_wait_info type invalid");
879 RETURN_IF(frame_wait_info->next != nullptr, XR_ERROR_VALIDATION_FAILURE,
880 "XrFrameWaitInfo next is not nullptr");
881 RETURN_IF(frame_state == nullptr, XR_ERROR_VALIDATION_FAILURE,
882 "XrFrameState is nullptr");
883 RETURN_IF(frame_state->type != XR_TYPE_FRAME_STATE,
884 XR_ERROR_VALIDATION_FAILURE, "XR_TYPE_FRAME_STATE type invalid");
885
886 frame_state->predictedDisplayTime = g_test_helper.NextPredictedDisplayTime();
887
888 return XR_SUCCESS;
889 }
890
xrWaitSwapchainImage(XrSwapchain swapchain,const XrSwapchainImageWaitInfo * wait_info)891 XrResult xrWaitSwapchainImage(XrSwapchain swapchain,
892 const XrSwapchainImageWaitInfo* wait_info) {
893 DVLOG(2) << __FUNCTION__;
894 RETURN_IF_XR_FAILED(g_test_helper.ValidateSwapchain(swapchain));
895 RETURN_IF(wait_info == nullptr, XR_ERROR_VALIDATION_FAILURE,
896 "XrSwapchainImageWaitInfo is nullptr");
897 RETURN_IF(wait_info->type != XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO,
898 XR_ERROR_VALIDATION_FAILURE, "xrWaitSwapchainImage type invalid");
899 RETURN_IF(wait_info->type != XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO,
900 XR_ERROR_VALIDATION_FAILURE,
901 "xrWaitSwapchainImage next is nullptr");
902 RETURN_IF(wait_info->timeout != XR_INFINITE_DURATION,
903 XR_ERROR_VALIDATION_FAILURE,
904 "xrWaitSwapchainImage timeout not XR_INFINITE_DURATION");
905
906 return XR_SUCCESS;
907 }
908
909 // Getter for extension methods. Casts the correct function dynamically based on
910 // the method name provided.
911 // Please add new OpenXR APIs below in alphabetical order.
xrGetInstanceProcAddr(XrInstance instance,const char * name,PFN_xrVoidFunction * function)912 XrResult XRAPI_PTR xrGetInstanceProcAddr(XrInstance instance,
913 const char* name,
914 PFN_xrVoidFunction* function) {
915 if (strcmp(name, "xrAcquireSwapchainImage") == 0) {
916 *function = reinterpret_cast<PFN_xrVoidFunction>(xrAcquireSwapchainImage);
917 } else if (strcmp(name, "xrAttachSessionActionSets") == 0) {
918 *function = reinterpret_cast<PFN_xrVoidFunction>(xrAttachSessionActionSets);
919 } else if (strcmp(name, "xrBeginFrame") == 0) {
920 *function = reinterpret_cast<PFN_xrVoidFunction>(xrBeginFrame);
921 } else if (strcmp(name, "xrBeginSession") == 0) {
922 *function = reinterpret_cast<PFN_xrVoidFunction>(xrBeginSession);
923 } else if (strcmp(name, "xrCreateAction") == 0) {
924 *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateAction);
925 } else if (strcmp(name, "xrCreateActionSet") == 0) {
926 *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateActionSet);
927 } else if (strcmp(name, "xrCreateActionSpace") == 0) {
928 *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateActionSpace);
929 } else if (strcmp(name, "xrCreateInstance") == 0) {
930 *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateInstance);
931 } else if (strcmp(name, "xrCreateReferenceSpace") == 0) {
932 *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateReferenceSpace);
933 } else if (strcmp(name, "xrCreateSession") == 0) {
934 *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateSession);
935 } else if (strcmp(name, "xrCreateSwapchain") == 0) {
936 *function = reinterpret_cast<PFN_xrVoidFunction>(xrCreateSwapchain);
937 } else if (strcmp(name, "xrDestroyActionSet") == 0) {
938 *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroyActionSet);
939 } else if (strcmp(name, "xrDestroyInstance") == 0) {
940 *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroyInstance);
941 } else if (strcmp(name, "xrDestroySpace") == 0) {
942 *function = reinterpret_cast<PFN_xrVoidFunction>(xrDestroySpace);
943 } else if (strcmp(name, "xrEndFrame") == 0) {
944 *function = reinterpret_cast<PFN_xrVoidFunction>(xrEndFrame);
945 } else if (strcmp(name, "xrEndSession") == 0) {
946 *function = reinterpret_cast<PFN_xrVoidFunction>(xrEndSession);
947 } else if (strcmp(name, "xrEnumerateEnvironmentBlendModes") == 0) {
948 *function =
949 reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateEnvironmentBlendModes);
950 } else if (strcmp(name, "xrEnumerateInstanceExtensionProperties") == 0) {
951 *function = reinterpret_cast<PFN_xrVoidFunction>(
952 xrEnumerateInstanceExtensionProperties);
953 } else if (strcmp(name, "xrEnumerateSwapchainImages") == 0) {
954 *function =
955 reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateSwapchainImages);
956 } else if (strcmp(name, "xrEnumerateViewConfigurationViews") == 0) {
957 *function =
958 reinterpret_cast<PFN_xrVoidFunction>(xrEnumerateViewConfigurationViews);
959 } else if (strcmp(name, "xrGetD3D11GraphicsRequirementsKHR") == 0) {
960 *function =
961 reinterpret_cast<PFN_xrVoidFunction>(xrGetD3D11GraphicsRequirementsKHR);
962 } else if (strcmp(name, "xrGetActionStateFloat") == 0) {
963 *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateFloat);
964 } else if (strcmp(name, "xrGetActionStateBoolean") == 0) {
965 *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateBoolean);
966 } else if (strcmp(name, "xrGetActionStateVector2f") == 0) {
967 *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStateVector2f);
968 } else if (strcmp(name, "xrGetActionStatePose") == 0) {
969 *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetActionStatePose);
970 } else if (strcmp(name, "xrGetCurrentInteractionProfile") == 0) {
971 *function =
972 reinterpret_cast<PFN_xrVoidFunction>(xrGetCurrentInteractionProfile);
973 } else if (strcmp(name, "xrGetReferenceSpaceBoundsRect") == 0) {
974 *function =
975 reinterpret_cast<PFN_xrVoidFunction>(xrGetReferenceSpaceBoundsRect);
976 } else if (strcmp(name, "xrGetSystem") == 0) {
977 *function = reinterpret_cast<PFN_xrVoidFunction>(xrGetSystem);
978 } else if (strcmp(name, "xrLocateSpace") == 0) {
979 *function = reinterpret_cast<PFN_xrVoidFunction>(xrLocateSpace);
980 } else if (strcmp(name, "xrLocateViews") == 0) {
981 *function = reinterpret_cast<PFN_xrVoidFunction>(xrLocateViews);
982 } else if (strcmp(name, "xrPollEvent") == 0) {
983 *function = reinterpret_cast<PFN_xrVoidFunction>(xrPollEvent);
984 } else if (strcmp(name, "xrReleaseSwapchainImage") == 0) {
985 *function = reinterpret_cast<PFN_xrVoidFunction>(xrReleaseSwapchainImage);
986 } else if (strcmp(name, "xrSuggestInteractionProfileBindings") == 0) {
987 *function = reinterpret_cast<PFN_xrVoidFunction>(
988 xrSuggestInteractionProfileBindings);
989 } else if (strcmp(name, "xrStringToPath") == 0) {
990 *function = reinterpret_cast<PFN_xrVoidFunction>(xrStringToPath);
991 } else if (strcmp(name, "xrPathToString") == 0) {
992 *function = reinterpret_cast<PFN_xrVoidFunction>(xrPathToString);
993 } else if (strcmp(name, "xrSyncActions") == 0) {
994 *function = reinterpret_cast<PFN_xrVoidFunction>(xrSyncActions);
995 } else if (strcmp(name, "xrWaitFrame") == 0) {
996 *function = reinterpret_cast<PFN_xrVoidFunction>(xrWaitFrame);
997 } else if (strcmp(name, "xrWaitSwapchainImage") == 0) {
998 *function = reinterpret_cast<PFN_xrVoidFunction>(xrWaitSwapchainImage);
999 } else {
1000 return XR_ERROR_FUNCTION_UNSUPPORTED;
1001 }
1002
1003 return XR_SUCCESS;
1004 }