···646646 XrBodyJointLocationsFB *locations);
647647#endif
648648649649+650650+/*
651651+ *
652652+ * oxr_api_xdev.c
653653+ *
654654+ */
655655+656656+#ifdef OXR_HAVE_MNDX_xdev_space
657657+//! OpenXR API function @ep{xrCreateXDevListMNDX}
658658+XRAPI_ATTR XrResult XRAPI_CALL
659659+oxr_xrCreateXDevListMNDX(XrSession session, const XrCreateXDevListInfoMNDX *info, XrXDevListMNDX *xdevList);
660660+661661+//! OpenXR API function @ep{xrGetXDevListGenerationNumberMNDX}
662662+XRAPI_ATTR XrResult XRAPI_CALL
663663+oxr_xrGetXDevListGenerationNumberMNDX(XrXDevListMNDX session, uint64_t *outGeneration);
664664+665665+//! OpenXR API function @ep{xrEnumerateXDevsMNDX}
666666+XRAPI_ATTR XrResult XRAPI_CALL
667667+oxr_xrEnumerateXDevsMNDX(XrXDevListMNDX xdevList,
668668+ uint32_t xdevCapacityInput,
669669+ uint32_t *xdevCountOutput,
670670+ XrXDevIdMNDX *xdevs);
671671+672672+//! OpenXR API function @ep{xrGetXDevProperty}
673673+XRAPI_ATTR XrResult XRAPI_CALL
674674+oxr_xrGetXDevPropertiesMNDX(XrXDevListMNDX xdevList, const XrGetXDevInfoMNDX *info, XrXDevPropertiesMNDX *properties);
675675+676676+//! OpenXR API function @ep{xrDestroyXDevListMNDX}
677677+XRAPI_ATTR XrResult XRAPI_CALL
678678+oxr_xrDestroyXDevListMNDX(XrXDevListMNDX xdevList);
679679+680680+//! OpenXR API function @ep{xrCreateXDevSpace}
681681+XRAPI_ATTR XrResult XRAPI_CALL
682682+oxr_xrCreateXDevSpaceMNDX(XrSession session, const XrCreateXDevSpaceInfoMNDX *createInfo, XrSpace *space);
683683+#endif
684684+685685+649686/*!
650687 * @}
651688 */
+9
src/xrt/state_trackers/oxr/oxr_api_negotiate.c
···319319 ENTRY_IF_EXT(xrLocateBodyJointsFB, FB_body_tracking);
320320#endif
321321322322+#ifdef OXR_HAVE_MNDX_xdev_space
323323+ ENTRY_IF_EXT(xrCreateXDevListMNDX, MNDX_xdev_space);
324324+ ENTRY_IF_EXT(xrGetXDevListGenerationNumberMNDX, MNDX_xdev_space);
325325+ ENTRY_IF_EXT(xrEnumerateXDevsMNDX, MNDX_xdev_space);
326326+ ENTRY_IF_EXT(xrGetXDevPropertiesMNDX, MNDX_xdev_space);
327327+ ENTRY_IF_EXT(xrDestroyXDevListMNDX, MNDX_xdev_space);
328328+ ENTRY_IF_EXT(xrCreateXDevSpaceMNDX, MNDX_xdev_space);
329329+#endif // OXR_HAVE_MNDX_xdev_space
330330+322331 /*
323332 * Not logging here because there's no need to loudly advertise
324333 * which extensions the loader knows about (it calls this on
···222222223223224224 /*
225225+ * Misc
226226+ */
227227+228228+#ifdef OXR_HAVE_MNDX_xdev_space
229229+ // By default xdev_space is implemented in the state tracker and does not need explicit system support.
230230+ sys->supports_xdev_space = true;
231231+#endif
232232+233233+ /*
225234 * Done.
226235 */
227236···423432 body_tracking_fb_props->supportsBodyTracking = oxr_system_get_body_tracking_fb_support(log, sys->inst);
424433 }
425434#endif // OXR_HAVE_FB_body_tracking
435435+436436+437437+#ifdef OXR_HAVE_MNDX_xdev_space
438438+ XrSystemXDevSpacePropertiesMNDX *xdev_space_props = NULL;
439439+ if (sys->inst->extensions.MNDX_xdev_space) {
440440+ xdev_space_props = OXR_GET_OUTPUT_FROM_CHAIN(properties, XR_TYPE_SYSTEM_XDEV_SPACE_PROPERTIES_MNDX,
441441+ XrSystemXDevSpacePropertiesMNDX);
442442+ }
443443+444444+ if (xdev_space_props) {
445445+ xdev_space_props->supportsXDevSpace = sys->supports_xdev_space;
446446+ }
447447+#endif // OXR_HAVE_MNDX_xdev_space
426448427449 return XR_SUCCESS;
428450}
+150-2
src/xrt/state_trackers/oxr/oxr_xdev.c
···11-// Copyright 2019-2020, Collabora, Ltd.
11+// Copyright 2019-2024, Collabora, Ltd.
22// SPDX-License-Identifier: BSL-1.0
33/*!
44 * @file
···1616#include "util/u_misc.h"
17171818#include "oxr_objects.h"
1919+#include "oxr_logger.h"
2020+#include "oxr_handle.h"
2121+#include "xrt/xrt_defines.h"
19222020-#include <assert.h>
2323+#include <stdio.h>
2424+#include <inttypes.h>
212522262727+/*
2828+ *
2929+ * Helper functions.
3030+ *
3131+ */
3232+3333+#ifdef OXR_HAVE_MNDX_xdev_space
3434+static enum xrt_input_name
3535+find_suitable_pose_name(struct xrt_device *xdev)
3636+{
3737+ //! @todo More complete set of poses / a system to enumerate all canonical device poses.
3838+ for (uint32_t i = 0; i < xdev->input_count; i++) {
3939+ enum xrt_input_name name = xdev->inputs[i].name;
4040+ switch (name) {
4141+ case XRT_INPUT_GENERIC_HEAD_POSE: return name;
4242+ case XRT_INPUT_GENERIC_TRACKER_POSE: return name;
4343+ case XRT_INPUT_INDEX_GRIP_POSE: return name;
4444+ default: break;
4545+ }
4646+ }
4747+4848+ return 0;
4949+}
5050+#endif
5151+5252+5353+/*
5454+ *
5555+ * 'Exported' functions.
5656+ *
5757+ */
5858+2359void
2460oxr_xdev_destroy(struct xrt_device **xdev_ptr)
2561{
···9713398134 *out_value = value;
99135}
136136+137137+138138+/*
139139+ *
140140+ * XDev List
141141+ *
142142+ */
143143+144144+#ifdef OXR_HAVE_MNDX_xdev_space
145145+146146+static XrResult
147147+oxr_xdev_list_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
148148+{
149149+ struct oxr_xdev_list *xdl = (struct oxr_xdev_list *)hb;
150150+151151+ free(xdl);
152152+153153+ return XR_SUCCESS;
154154+}
155155+156156+XrResult
157157+oxr_xdev_list_create(struct oxr_logger *log,
158158+ struct oxr_session *sess,
159159+ const XrCreateXDevListInfoMNDX *createInfo,
160160+ struct oxr_xdev_list **out_xdl)
161161+{
162162+ struct xrt_system_devices *xsysd = sess->sys->xsysd;
163163+ uint32_t count = xsysd->xdev_count;
164164+165165+ struct oxr_xdev_list *xdl = NULL;
166166+ OXR_ALLOCATE_HANDLE_OR_RETURN(log, xdl, OXR_XR_DEBUG_XDEVLIST, oxr_xdev_list_destroy, &sess->handle);
167167+168168+ /**
169169+ * @todo Should ids be explicitly unique per xdev list? Currently an id queried from xdev list 1 may or may not
170170+ * refer to the same xdev as an id queried from xdev list 2, which is error prone for app developers.
171171+ *
172172+ * On the other hand, it may be desirable to keep an id for an xdev fixed for the life time of the xdev. See
173173+ * also XR_ML_marker_understanding (This is NOT what the xdev_space code does now, this is only an example what
174174+ * other extensions do. xdev_space solves this with the xdev list generation_id): "Assuming the same set of
175175+ * markers are in view across several snapshots, the runtime should return the same set of atoms. An application
176176+ * can use the list of atoms as a simple test for if a particular marker has gone in or out of view."
177177+ */
178178+179179+ // The value of the assigned XrXDevIdMNDX atom.
180180+ // Just to make them not start at 0 or 1.
181181+ uint64_t id_gen = 42;
182182+183183+ for (uint32_t i = 0; i < count; i++) {
184184+ struct xrt_device *xdev = xsysd->xdevs[i];
185185+ enum xrt_input_name name = find_suitable_pose_name(xdev);
186186+187187+ xdl->ids[i] = id_gen++;
188188+ xdl->xdevs[i] = xdev;
189189+ xdl->names[i] = name;
190190+ }
191191+192192+ xdl->device_count = count;
193193+ xdl->sess = sess;
194194+195195+ //! @todo Always the first generation, Monado doesn't have hotplug (yet).
196196+ xdl->generation_number = 1;
197197+198198+ *out_xdl = xdl;
199199+200200+ return XR_SUCCESS;
201201+}
202202+203203+XrResult
204204+oxr_xdev_list_get_properties(struct oxr_logger *log,
205205+ struct oxr_xdev_list *xdl,
206206+ uint32_t index,
207207+ XrXDevPropertiesMNDX *properties)
208208+{
209209+ if (index >= xdl->device_count) {
210210+ return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, "index %u > device_count %u", index, xdl->device_count);
211211+ }
212212+213213+ struct xrt_device *xdev = xdl->xdevs[index];
214214+ bool can_create_space = xdl->names[index] != 0;
215215+216216+ snprintf(properties->name, ARRAY_SIZE(properties->name), "%s", xdev->str);
217217+ snprintf(properties->serial, ARRAY_SIZE(properties->serial), "%s", xdev->serial);
218218+ properties->canCreateSpace = can_create_space;
219219+220220+ return XR_SUCCESS;
221221+}
222222+223223+XrResult
224224+oxr_xdev_list_space_create(struct oxr_logger *log,
225225+ struct oxr_xdev_list *xdl,
226226+ const XrCreateXDevSpaceInfoMNDX *createInfo,
227227+ uint32_t index,
228228+ struct oxr_space **out_space)
229229+{
230230+ if (index >= xdl->device_count) {
231231+ return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
232232+ "(createInfo->id == %" PRIu64 ") index %u > device_count %u", createInfo->id, index,
233233+ xdl->device_count);
234234+ }
235235+ if (xdl->names[index] == 0) {
236236+ return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
237237+ "(createInfo->id == %" PRIu64 ") have no pose to create a space for", createInfo->id);
238238+ }
239239+240240+ const struct xrt_pose *pose = (const struct xrt_pose *)&createInfo->offset;
241241+ struct xrt_device *xdev = xdl->xdevs[index];
242242+ enum xrt_input_name name = xdl->names[index];
243243+244244+ return oxr_space_xdev_pose_create(log, xdl->sess, xdev, name, pose, out_space);
245245+}
246246+247247+#endif // OXR_HAVE_MNDX_xdev_space