st/oxr: Implement XR_KHR_visibility_mask

This commit is contained in:
Simon Zeni 2023-11-06 16:09:08 -05:00 committed by Jakob Bornecrantz
parent c1ce722d6d
commit 96be7675ed
7 changed files with 123 additions and 6 deletions

View file

@ -49,6 +49,7 @@ EXTENSIONS = (
['XR_KHR_opengl_enable', 'XR_USE_GRAPHICS_API_OPENGL'],
['XR_KHR_opengl_es_enable', 'XR_USE_GRAPHICS_API_OPENGL_ES'],
['XR_KHR_swapchain_usage_input_attachment_bit'],
['XR_KHR_visibility_mask'],
['XR_KHR_vulkan_enable', 'XR_USE_GRAPHICS_API_VULKAN'],
['XR_KHR_vulkan_enable2', 'XR_USE_GRAPHICS_API_VULKAN'],
['XR_KHR_win32_convert_performance_counter_time', 'XR_USE_PLATFORM_WIN32'],

View file

@ -264,6 +264,10 @@ handle_non_null(struct oxr_instance *inst, struct oxr_logger *log, const char *n
ENTRY_IF_EXT(xrGetOpenGLESGraphicsRequirementsKHR, KHR_opengl_es_enable);
#endif // OXR_HAVE_KHR_opengl_es_enable
#ifdef OXR_HAVE_KHR_visibility_mask
ENTRY_IF_EXT(xrGetVisibilityMaskKHR, KHR_visibility_mask);
#endif // OXR_HAVE_KHR_visibility_mask
#ifdef OXR_HAVE_KHR_vulkan_enable
ENTRY_IF_EXT(xrGetVulkanInstanceExtensionsKHR, KHR_vulkan_enable);
ENTRY_IF_EXT(xrGetVulkanDeviceExtensionsKHR, KHR_vulkan_enable);

View file

@ -258,7 +258,6 @@ oxr_xrLocateViews(XrSession session,
*/
#ifdef XR_KHR_visibility_mask
XRAPI_ATTR XrResult XRAPI_CALL
oxr_xrGetVisibilityMaskKHR(XrSession session,
XrViewConfigurationType viewConfigurationType,
@ -268,16 +267,45 @@ oxr_xrGetVisibilityMaskKHR(XrSession session,
{
OXR_TRACE_MARKER();
struct oxr_session *sess;
struct oxr_session *sess = NULL;
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrGetVisibilityMaskKHR");
OXR_VERIFY_SESSION_NOT_LOST(&log, sess);
return oxr_error(&log, XR_ERROR_HANDLE_INVALID, "Not implemented");
OXR_VERIFY_EXTENSION(&log, sess->sys->inst, KHR_visibility_mask);
visibilityMask->vertexCountOutput = 0;
visibilityMask->indexCountOutput = 0;
OXR_VERIFY_VIEW_CONFIG_TYPE(&log, sess->sys->inst, viewConfigurationType);
if (viewConfigurationType != sess->sys->view_config_type) {
return oxr_error(&log, XR_ERROR_VIEW_CONFIGURATION_TYPE_UNSUPPORTED,
"(viewConfigurationType == 0x%08x) unsupported view configuration type",
viewConfigurationType);
}
OXR_VERIFY_VIEW_INDEX(&log, viewIndex);
if (visibilityMaskType != XR_VISIBILITY_MASK_TYPE_HIDDEN_TRIANGLE_MESH_KHR &&
visibilityMaskType != XR_VISIBILITY_MASK_TYPE_VISIBLE_TRIANGLE_MESH_KHR &&
visibilityMaskType != XR_VISIBILITY_MASK_TYPE_LINE_LOOP_KHR) {
return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE, "(visibilityMaskType == %d) is invalid",
visibilityMaskType);
}
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, visibilityMask, XR_TYPE_VISIBILITY_MASK_KHR);
if (visibilityMask->vertexCapacityInput != 0) {
OXR_VERIFY_ARG_NOT_NULL(&log, visibilityMask->vertices);
}
if (visibilityMask->indexCapacityInput != 0) {
OXR_VERIFY_ARG_NOT_NULL(&log, visibilityMask->indices);
}
return oxr_session_get_visibility_mask(&log, sess, visibilityMaskType, visibilityMask);
}
#endif
#endif // OXR_HAVE_KHR_visibility_mask
/*
*

View file

@ -201,6 +201,17 @@
#endif
/*
* XR_KHR_visibility_mask
*/
#if defined(XR_KHR_visibility_mask)
#define OXR_HAVE_KHR_visibility_mask
#define OXR_EXTENSION_SUPPORT_KHR_visibility_mask(_) _(KHR_visibility_mask, KHR_VISIBILITY_MASK)
#else
#define OXR_EXTENSION_SUPPORT_KHR_visibility_mask(_)
#endif
/*
* XR_KHR_vulkan_enable
*/
@ -534,6 +545,7 @@
OXR_EXTENSION_SUPPORT_KHR_opengl_enable(_) \
OXR_EXTENSION_SUPPORT_KHR_opengl_es_enable(_) \
OXR_EXTENSION_SUPPORT_KHR_swapchain_usage_input_attachment_bit(_) \
OXR_EXTENSION_SUPPORT_KHR_visibility_mask(_) \
OXR_EXTENSION_SUPPORT_KHR_vulkan_enable(_) \
OXR_EXTENSION_SUPPORT_KHR_vulkan_enable2(_) \
OXR_EXTENSION_SUPPORT_KHR_win32_convert_performance_counter_time(_) \

View file

@ -68,6 +68,10 @@ oxr_instance_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
u_hashset_destroy(&inst->action_sets.name_store);
u_hashset_destroy(&inst->action_sets.loc_store);
// Free the mask here, no system destroy yet.
free(inst->system.visibility_mask);
inst->system.visibility_mask = NULL;
xrt_space_overseer_destroy(&inst->system.xso);
os_mutex_destroy(&inst->system.sync_actions_mutex);
xrt_system_devices_destroy(&inst->system.xsysd);

View file

@ -761,6 +761,14 @@ oxr_session_android_thread_settings(struct oxr_logger *log,
uint32_t threadId);
#endif // OXR_HAVE_KHR_android_thread_settings
#ifdef OXR_HAVE_KHR_visibility_mask
XrResult
oxr_session_get_visibility_mask(struct oxr_logger *log,
struct oxr_session *session,
XrVisibilityMaskTypeKHR visibilityMaskType,
XrVisibilityMaskKHR *visibilityMask);
#endif // OXR_HAVE_KHR_visibility_mask
/*
*
* oxr_space.c
@ -1283,6 +1291,8 @@ struct oxr_system
struct xrt_system_roles dynamic_roles_cache;
struct os_mutex sync_actions_mutex;
struct xrt_visibility_mask *visibility_mask;
#ifdef XR_USE_GRAPHICS_API_VULKAN
//! The instance/device we create when vulkan_enable2 is used
VkInstance vulkan_enable2_instance;

View file

@ -1159,3 +1159,61 @@ oxr_session_android_thread_settings(struct oxr_logger *log,
return XR_SUCCESS;
}
#endif // OXR_HAVE_KHR_android_thread_settings
#ifdef OXR_HAVE_KHR_visibility_mask
static enum xrt_visibility_mask_type
convert_mask_type(XrVisibilityMaskTypeKHR type)
{
switch (type) {
case XR_VISIBILITY_MASK_TYPE_HIDDEN_TRIANGLE_MESH_KHR: return XRT_VISIBILITY_MASK_TYPE_HIDDEN_TRIANGLE_MESH;
case XR_VISIBILITY_MASK_TYPE_VISIBLE_TRIANGLE_MESH_KHR: return XRT_VISIBILITY_MASK_TYPE_VISIBLE_TRIANGLE_MESH;
case XR_VISIBILITY_MASK_TYPE_LINE_LOOP_KHR: return XRT_VISIBILITY_MASK_TYPE_LINE_LOOP;
default: return (enum xrt_visibility_mask_type)0;
}
}
XrResult
oxr_session_get_visibility_mask(struct oxr_logger *log,
struct oxr_session *sess,
XrVisibilityMaskTypeKHR visibilityMaskType,
XrVisibilityMaskKHR *visibilityMask)
{
struct oxr_system *sys = sess->sys;
struct xrt_device *xdev = GET_XDEV_BY_ROLE(sess->sys, head);
enum xrt_visibility_mask_type type = convert_mask_type(visibilityMaskType);
if (sys->visibility_mask && sys->visibility_mask->type != type) {
free(sys->visibility_mask);
sys->visibility_mask = NULL;
}
if (sys->visibility_mask == NULL) {
xdev->get_visibility_mask(xdev, type, &sys->visibility_mask);
}
struct xrt_visibility_mask *mask = sys->visibility_mask;
visibilityMask->vertexCountOutput = mask->vertex_count;
visibilityMask->indexCountOutput = mask->index_count;
if (visibilityMask->vertexCapacityInput == 0 || visibilityMask->indexCapacityInput == 0) {
return XR_SUCCESS;
}
if (visibilityMask->vertexCapacityInput < mask->vertex_count) {
return oxr_error(log, XR_ERROR_SIZE_INSUFFICIENT, "vertexCapacityInput is %u, need %u",
visibilityMask->vertexCapacityInput, mask->vertex_count);
} else if (visibilityMask->indexCapacityInput < mask->index_count) {
return oxr_error(log, XR_ERROR_SIZE_INSUFFICIENT, "indexCapacityInput is %u, need %u",
visibilityMask->indexCapacityInput, mask->index_count);
}
memcpy(visibilityMask->vertices, xrt_visibility_mask_get_vertices(mask),
sizeof(struct xrt_vec2) * mask->vertex_count);
memcpy(visibilityMask->indices, xrt_visibility_mask_get_indices(mask), sizeof(uint32_t) * mask->index_count);
return XR_SUCCESS;
}
#endif // OXR_HAVE_KHR_visibility_mask