Commit 4ccce71d authored by Drew DeVault's avatar Drew DeVault Committed by Simon Ser

Implement XR_KHR_egl_enable

This extension introduces a more robust way of creating an XrSession for
OpenGL. It also lays the groundwork for future OpenGL ES support.

https://github.com/KhronosGroup/OpenXR-Docs/pull/40Signed-off-by: Simon Ser's avatarSimon Ser <contact@emersion.fr>
Signed-off-by: Drew DeVault's avatarDrew DeVault <sir@cmpwn.com>
parent b5ee4f0d
Pipeline #74557 failed with stages
in 1 minute and 53 seconds
......@@ -2,12 +2,12 @@ variables:
UPSTREAM_REPO: monado/monado
DEBIAN_VERSION: buster
DEBIAN_TAG: '2019-09-26.0'
DEBIAN_TAG: '2019-10-29.1'
DEBIAN_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/debian/$DEBIAN_VERSION:$DEBIAN_TAG
DEBIAN_DEBS: 'build-essential git cmake meson ninja-build doxygen graphviz libeigen3-dev curl patch python3 pkg-config libx11-dev libxxf86vm-dev libxrandr-dev libxcb-randr0-dev libhidapi-dev libwayland-dev libvulkan-dev glslang-dev glslang-tools libglvnd-dev libgl1-mesa-dev ca-certificates libusb-1.0-0-dev libuvc-dev libavcodec-dev libopencv-dev libudev-dev clang-format-7 codespell libv4l-dev'
DEBIAN_DEBS: 'build-essential git cmake meson ninja-build doxygen graphviz libeigen3-dev curl patch python3 pkg-config libx11-dev libxxf86vm-dev libxrandr-dev libxcb-randr0-dev libhidapi-dev libwayland-dev libvulkan-dev glslang-dev glslang-tools libglvnd-dev libgl1-mesa-dev ca-certificates libusb-1.0-0-dev libuvc-dev libavcodec-dev libopencv-dev libudev-dev clang-format-7 codespell libv4l-dev libegl1-mesa-dev'
DEBIAN_EXEC: 'bash .gitlab-ci/build-openxr-openhmd.sh'
ARCH_TAG: '2019-09-26.0'
ARCH_TAG: '2019-10-29.0'
ARCH_PKGS: 'git gcc cmake meson ninja pkgconfig python3 diffutils patch doxygen graphviz eigen hidapi libxrandr mesa glslang vulkan-headers vulkan-icd-loader check glfw-x11 libusb opencv gtk3 ffmpeg v4l-utils'
ARCH_EXEC: 'bash .gitlab-ci/build-openxr-openhmd.sh'
ARCH_CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/archlinux/rolling:$ARCH_TAG
......
......@@ -35,6 +35,8 @@ add_project_arguments(cpp.get_supported_arguments([
glslangValidator = find_program('glslangValidator')
avcodec = dependency('libavcodec', required: false)
egl = dependency('egl')
egl = egl.partial_dependency(includes: true)
eigen3 = dependency('eigen3')
libjpeg = dependency('libjpeg', required: false)
libusb = dependency('libusb-1.0', required: false)
......
......@@ -14,6 +14,7 @@ EXTENSIONS = (
['XR_KHR_convert_timespec_time', 'XR_USE_TIMESPEC'],
['XR_KHR_opengl_enable', 'XR_USE_GRAPHICS_API_OPENGL'],
['XR_KHR_vulkan_enable', 'XR_USE_GRAPHICS_API_VULKAN'],
['XR_KHR_egl_enable', 'XR_USE_PLATFORM_EGL'],
['XR_MND_headless'],
)
......
......@@ -35,7 +35,7 @@ extern "C" {
((((major) & 0xffffULL) << 48) | (((minor) & 0xffffULL) << 32) | ((patch) & 0xffffffffULL))
// OpenXR current version number.
#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 1)
#define XR_CURRENT_API_VERSION XR_MAKE_VERSION(1, 0, 3)
#define XR_VERSION_MAJOR(version) (uint16_t)(((uint64_t)(version) >> 48)& 0xffffULL)
#define XR_VERSION_MINOR(version) (uint16_t)(((uint64_t)(version) >> 32) & 0xffffULL)
......@@ -280,6 +280,8 @@ typedef enum XrStructureType {
XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR = 1000031001,
XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT = 1000039000,
XR_TYPE_SPATIAL_ANCHOR_SPACE_CREATE_INFO_MSFT = 1000039001,
XR_TYPE_VIEW_CONFIGURATION_DEPTH_RANGE_EXT = 1000046000,
XR_TYPE_GRAPHICS_BINDING_EGL_KHR = 1000047004,
XR_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} XrStructureType;
......@@ -1585,6 +1587,25 @@ XRAPI_ATTR XrResult XRAPI_CALL xrDestroySpatialAnchorMSFT(
#define XR_MND_headless_SPEC_VERSION 1
#define XR_MND_HEADLESS_EXTENSION_NAME "XR_MND_headless"
#define XR_OCULUS_android_session_state_enable 1
#define XR_OCULUS_android_session_state_enable_SPEC_VERSION 1
#define XR_OCULUS_ANDROID_SESSION_STATE_ENABLE_EXTENSION_NAME "XR_OCULUS_android_session_state_enable"
#define XR_EXT_view_configuration_depth_range 1
#define XR_EXT_view_configuration_depth_range_SPEC_VERSION 1
#define XR_EXT_VIEW_CONFIGURATION_DEPTH_RANGE_EXTENSION_NAME "XR_EXT_view_configuration_depth_range"
typedef struct XrViewConfigurationDepthRangeEXT {
XrStructureType type;
void* XR_MAY_ALIAS next;
float recommendedNearZ;
float minNearZ;
float recommendedFarZ;
float maxFarZ;
} XrViewConfigurationDepthRangeEXT;
#ifdef __cplusplus
}
#endif
......
......@@ -376,6 +376,22 @@ XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToTimespecTimeKHR(
#endif
#endif /* XR_USE_TIMESPEC */
#ifdef XR_USE_PLATFORM_EGL
#define XR_KHR_egl_enable 1
#define XR_KHR_egl_enable_SPEC_VERSION 1
#define XR_KHR_EGL_ENABLE_EXTENSION_NAME "XR_KHR_egl_enable"
typedef struct XrGraphicsBindingEGLKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
PFNEGLGETPROCADDRESSPROC getProcAddress;
EGLDisplay display;
EGLConfig config;
EGLContext context;
} XrGraphicsBindingEGLKHR;
#endif /* XR_USE_PLATFORM_EGL */
#ifdef __cplusplus
}
#endif
......
......@@ -36,11 +36,7 @@ extern "C" {
* Function pointer type: typedef void (XRAPI_PTR *PFN_xrFunction)(void);
*/
#if defined(_WIN32)
#ifdef XRAPI_DLL_EXPORT
#define XRAPI_ATTR __declspec(dllexport)
#else
#define XRAPI_ATTR
#endif
// On Windows, functions use the stdcall convention
#define XRAPI_CALL __stdcall
#define XRAPI_PTR XRAPI_CALL
......
......@@ -183,6 +183,8 @@ XR_ENUM_STR(XrResult);
_(XR_TYPE_EVENT_DATA_VISIBILITY_MASK_CHANGED_KHR, 1000031001) \
_(XR_TYPE_SPATIAL_ANCHOR_CREATE_INFO_MSFT, 1000039000) \
_(XR_TYPE_SPATIAL_ANCHOR_SPACE_CREATE_INFO_MSFT, 1000039001) \
_(XR_TYPE_VIEW_CONFIGURATION_DEPTH_RANGE_EXT, 1000046000) \
_(XR_TYPE_GRAPHICS_BINDING_EGL_KHR, 1000047004) \
_(XR_STRUCTURE_TYPE_MAX_ENUM, 0x7FFFFFFF)
#define XR_LIST_ENUM_XrFormFactor(_) \
......@@ -963,6 +965,14 @@ XR_ENUM_STR(XrResult);
_(viewConfigurationType) \
_(viewIndex)
#define XR_LIST_STRUCT_XrGraphicsBindingEGLKHR(_) \
_(type) \
_(next) \
_(getProcAddress) \
_(display) \
_(config) \
_(context)
#define XR_LIST_STRUCT_XrEventDataPerfSettingsEXT(_) \
_(type) \
_(next) \
......@@ -1015,6 +1025,14 @@ XR_ENUM_STR(XrResult);
_(anchor) \
_(poseInAnchorSpace)
#define XR_LIST_STRUCT_XrViewConfigurationDepthRangeEXT(_) \
_(type) \
_(next) \
_(recommendedNearZ) \
_(minNearZ) \
_(recommendedFarZ) \
_(maxFarZ)
......
......@@ -27,6 +27,7 @@ set(GL_SOURCE_FILES
main/comp_distortion.c
main/comp_distortion.h
main/comp_documentation.h
main/comp_glue_egl.c
main/comp_glue_gl.c
main/comp_glue_vk.c
main/comp_glue_xlib.c
......
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Glue code to EGL client side glue code.
* @author Drew DeVault <sir@cmpwn.com>
* @author Simon Ser <contact@emersion.fr>
* @ingroup comp
*/
#define EGL_EGL_PROTOTYPES 0
#define EGL_NO_X11
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <stdio.h>
#include <stdlib.h>
#include "client/comp_gl_client.h"
#include "main/comp_client_interface.h"
#include "util/u_misc.h"
#include "xrt/xrt_gfx_egl.h"
// Not forward declared by mesa
typedef EGLBoolean EGLAPIENTRY (*PFNEGLMAKECURRENTPROC)(EGLDisplay dpy,
EGLSurface draw,
EGLSurface read,
EGLContext ctx);
static void
client_egl_compositor_destroy(struct xrt_compositor *xc)
{
struct client_gl_compositor *c = client_gl_compositor(xc);
// Pipe down call into fd compositor.
c->xcfd->base.destroy(&c->xcfd->base);
free(c);
}
struct xrt_compositor_gl *
xrt_gfx_provider_create_gl_egl(struct xrt_device *xdev,
struct time_state *timekeeping,
EGLDisplay *display,
EGLConfig *config,
EGLContext *context,
PFNEGLGETPROCADDRESSPROC getProcAddress)
{
PFNEGLMAKECURRENTPROC eglMakeCurrent =
(PFNEGLMAKECURRENTPROC)getProcAddress("eglMakeCurrent");
if (!eglMakeCurrent) {
/* TODO: sort out logging here */
fprintf(stderr, "getProcAddress(eglMakeCurrent) failed\n");
return NULL;
}
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context)) {
fprintf(stderr, "Failed to make EGL context current\n");
return NULL;
}
struct xrt_compositor_fd *xcfd =
comp_compositor_create(xdev, timekeeping, true);
if (xcfd == NULL) {
fprintf(stderr, "Failed to create compositor\n");
return NULL;
}
struct client_gl_compositor *c =
U_TYPED_CALLOC(struct client_gl_compositor);
if (!client_gl_compositor_init(c, xcfd, getProcAddress)) {
free(c);
fprintf(stderr, "Failed to initialize compositor\n");
return NULL;
}
c->base.base.destroy = client_egl_compositor_destroy;
return &c->base;
}
......@@ -3,6 +3,7 @@
subdir('shaders')
# TODO: Dependency resolution and subsequent configuration could be improved
compositor_deps = [aux, shaders, vulkan]
compositor_srcs = [
......@@ -21,6 +22,7 @@ compositor_srcs = [
'main/comp_distortion.c',
'main/comp_distortion.h',
'main/comp_documentation.h',
'main/comp_glue_egl.c',
'main/comp_glue_gl.c',
'main/comp_glue_vk.c',
'main/comp_glue_xlib.c',
......
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Header defining a XRT graphics provider.
* @author Drew DeVault <sir@cmpwn.com>
* @ingroup xrt_iface
*/
#pragma once
#include "xrt/xrt_device.h"
#include "xrt/xrt_compositor.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void *EGLDisplay;
typedef void *EGLConfig;
typedef void *EGLContext;
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
typedef __eglMustCastToProperFunctionPointerType (*PFNEGLGETPROCADDRESSPROC)(
const char *proc);
struct time_state;
/*!
* @ingroup xrt_iface
*/
struct xrt_compositor_gl *
xrt_gfx_provider_create_gl_egl(struct xrt_device *xdev,
struct time_state *timekeeping,
EGLDisplay *display,
EGLConfig *config,
EGLContext *context,
PFNEGLGETPROCADDRESSPROC getProcAddress);
#ifdef __cplusplus
}
#endif
......@@ -13,6 +13,7 @@
#define XR_USE_GRAPHICS_API_OPENGL
#define XR_USE_GRAPHICS_API_VULKAN
#define XR_USE_PLATFORM_XLIB
#define XR_USE_PLATFORM_EGL
#define XR_USE_TIMESPEC 1
#ifdef XR_USE_PLATFORM_XLIB
......@@ -22,6 +23,15 @@ typedef void *GLXDrawable;
typedef void *GLXContext;
#endif
#ifdef XR_USE_PLATFORM_EGL
typedef void *EGLDisplay;
typedef void *EGLContext;
typedef void *EGLConfig;
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
typedef __eglMustCastToProperFunctionPointerType (*PFNEGLGETPROCADDRESSPROC)(
const char *procname);
#endif
#ifdef XR_USE_TIMESPEC
#include <time.h>
#endif
......
......@@ -30,6 +30,7 @@ set(OXR_SOURCE_FILES
oxr_path.c
oxr_session.c
oxr_session_gl.c
oxr_session_egl.c
oxr_session_vk.c
oxr_space.c
oxr_swapchain.c
......
......@@ -26,6 +26,7 @@ lib_st_oxr = static_library(
'oxr_path.c',
'oxr_session.c',
'oxr_session_gl.c',
'oxr_session_egl.c',
'oxr_session_vk.c',
'oxr_space.c',
'oxr_swapchain.c',
......
......@@ -248,6 +248,10 @@ XrResult
oxr_verify_XrGraphicsBindingVulkanKHR(struct oxr_logger *,
const XrGraphicsBindingVulkanKHR *);
XrResult
oxr_verify_XrGraphicsBindingEGLKHR(struct oxr_logger *log,
const XrGraphicsBindingEGLKHR *next);
/*!
* @}
*/
......
......@@ -61,6 +61,18 @@
#endif
/*
* XR_KHR_egl_enable
*/
#if defined(XR_KHR_egl_enable) && defined(XR_USE_PLATFORM_EGL)
#define OXR_HAVE_KHR_egl_enable
#define OXR_EXTENSION_SUPPORT_KHR_egl_enable(_) \
_(KHR_egl_enable, KHR_EGL_ENABLE)
#else
#define OXR_EXTENSION_SUPPORT_KHR_egl_enable(_)
#endif
/*
* XR_MND_headless
*/
......@@ -92,8 +104,10 @@
*/
// clang-format off
#define OXR_EXTENSION_SUPPORT_GENERATE(_) \
OXR_EXTENSION_SUPPORT_EXT_debug_utils(_) \
OXR_EXTENSION_SUPPORT_KHR_convert_timespec_time(_) \
OXR_EXTENSION_SUPPORT_KHR_opengl_enable(_) \
OXR_EXTENSION_SUPPORT_KHR_vulkan_enable(_) \
OXR_EXTENSION_SUPPORT_KHR_egl_enable(_) \
OXR_EXTENSION_SUPPORT_MND_headless(_)
// clang-format on
......@@ -771,6 +771,23 @@ oxr_swapchain_vk_create(struct oxr_logger *,
#endif
/*
*
* EGL, located in various files.
*
*/
#ifdef XR_USE_PLATFORM_EGL
XrResult
oxr_session_populate_egl(struct oxr_logger *log,
struct oxr_system *sys,
XrGraphicsBindingEGLKHR const *next,
struct oxr_session *sess);
#endif
/*
*
* Structs
......
......@@ -631,6 +631,16 @@ oxr_session_create_impl(struct oxr_logger *log,
}
#endif
#ifdef XR_USE_PLATFORM_EGL
XrGraphicsBindingEGLKHR const *egl = OXR_GET_INPUT_FROM_CHAIN(
createInfo, XR_TYPE_GRAPHICS_BINDING_EGL_KHR,
XrGraphicsBindingEGLKHR);
if (egl != NULL) {
OXR_SESSION_ALLOCATE(log, sys, *out_session);
return oxr_session_populate_egl(log, sys, egl, *out_session);
}
#endif
/*
* Add any new graphics binding structs here - before the headless
* check. (order for non-headless checks not specified in standard.)
......
// Copyright 2018-2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Holds OpenGL-specific session functions.
* @author Drew DeVault <sir@cmpwn.com>
* @author Simon Ser <contact@emersion.fr>
* @ingroup oxr_main
* @ingroup comp_client
*/
#include <stdlib.h>
#include "util/u_misc.h"
#include "oxr_objects.h"
#include "oxr_logger.h"
#include "oxr_two_call.h"
#include "oxr_handle.h"
#ifdef XR_USE_PLATFORM_EGL
#define EGL_NO_X11 // libglvnd
#define MESA_EGL_NO_X11_HEADERS // mesa
#include <EGL/egl.h>
#include "xrt/xrt_gfx_egl.h"
// Not forward declared by mesa
typedef EGLBoolean(EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC)(EGLDisplay dpy,
EGLContext ctx,
EGLint attribute,
EGLint *value);
#endif
#ifdef XR_USE_PLATFORM_EGL
XrResult
oxr_session_populate_egl(struct oxr_logger *log,
struct oxr_system *sys,
XrGraphicsBindingEGLKHR const *next,
struct oxr_session *sess)
{
EGLint egl_client_type;
PFNEGLQUERYCONTEXTPROC eglQueryContext =
(PFNEGLQUERYCONTEXTPROC)next->getProcAddress("eglQueryContext");
if (!eglQueryContext) {
return oxr_error(log, XR_ERROR_INITIALIZATION_FAILED,
"getProcAddress(eglQueryContext) failed");
}
if (!eglQueryContext(next->display, next->context,
EGL_CONTEXT_CLIENT_TYPE, &egl_client_type)) {
return oxr_error(
log, XR_ERROR_INITIALIZATION_FAILED,
"eglQueryContext(EGL_CONTEXT_CLIENT_TYPE) failed");
}
if (egl_client_type != EGL_OPENGL_API) {
return oxr_error(log, XR_ERROR_INITIALIZATION_FAILED,
"unsupported EGL client type");
}
struct xrt_compositor_gl *xcgl = xrt_gfx_provider_create_gl_egl(
sys->head, sys->inst->timekeeping, next->display, next->config,
next->context, next->getProcAddress);
if (xcgl == NULL) {
return oxr_error(log, XR_ERROR_INITIALIZATION_FAILED,
" failed create a compositor");
}
sess->compositor = &xcgl->base;
sess->create_swapchain = oxr_swapchain_gl_create;
return XR_SUCCESS;
}
#endif
......@@ -12,13 +12,16 @@
#include "util/u_misc.h"
#include "xrt/xrt_gfx_xlib.h"
#include "oxr_objects.h"
#include "oxr_logger.h"
#include "oxr_two_call.h"
#include "oxr_handle.h"
#ifdef XR_USE_PLATFORM_XLIB
#include "xrt/xrt_gfx_xlib.h"
#endif
#ifdef XR_USE_PLATFORM_XLIB
XrResult
oxr_session_populate_gl_xlib(struct oxr_logger *log,
......@@ -40,3 +43,5 @@ oxr_session_populate_gl_xlib(struct oxr_logger *log,
return XR_SUCCESS;
}
#endif
......@@ -496,6 +496,16 @@ oxr_verify_XrSessionCreateInfo(struct oxr_logger *log,
}
#endif // OXR_HAVE_KHR_vulkan_enable
#if defined(OXR_HAVE_KHR_egl_enable) && defined(XR_USE_PLATFORM_EGL)
XrGraphicsBindingEGLKHR const *egl = OXR_GET_INPUT_FROM_CHAIN(
createInfo, XR_TYPE_GRAPHICS_BINDING_EGL_KHR,
XrGraphicsBindingEGLKHR);
if (egl != NULL) {
OXR_VERIFY_EXTENSION(log, inst, KHR_egl_enable);
return oxr_verify_XrGraphicsBindingEGLKHR(log, egl);
}
#endif // defined(OXR_HAVE_KHR_egl_enable) && defined(XR_USE_PLATFORM_EGL_KHR)
/*
* Add any new graphics binding structs here - before the headless
* check. (order for non-headless checks not specified in standard.)
......@@ -549,3 +559,20 @@ oxr_verify_XrGraphicsBindingVulkanKHR(struct oxr_logger *log,
}
#endif
#ifdef XR_USE_PLATFORM_EGL
XrResult
oxr_verify_XrGraphicsBindingEGLKHR(struct oxr_logger *log,
const XrGraphicsBindingEGLKHR *next)
{
if (next->type != XR_TYPE_GRAPHICS_BINDING_EGL_KHR) {
return oxr_error(log, XR_ERROR_VALIDATION_FAILURE,
" Graphics binding has invalid type");
}
return XR_SUCCESS;
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment