13#if defined(WITH_GHOST_X11)
14# if defined(WITH_OPENGL_BACKEND)
20#if defined(WITH_GHOST_WAYLAND)
21# if defined(WITH_OPENGL_BACKEND)
32#ifdef WITH_VULKAN_BACKEND
42#if defined(WITH_OPENGL_BACKEND)
44 const std::vector<int64_t> &gpu_binding_formats,
const std::vector<int64_t> &runtime_formats)
46 if (gpu_binding_formats.empty()) {
50 auto res = std::find_first_of(gpu_binding_formats.begin(),
51 gpu_binding_formats.end(),
52 runtime_formats.begin(),
53 runtime_formats.end());
54 if (res == gpu_binding_formats.end()) {
63 ~GHOST_XrGraphicsBindingOpenGL()
66 glDeleteFramebuffers(1, &fbo_);
73 std::string *r_requirement_info)
const override
75 int gl_major_version, gl_minor_version;
77 GHOST_ContextWGL &ctx_gl =
static_cast<GHOST_ContextWGL &
>(ghost_ctx);
78 gl_major_version = ctx_gl.context_major_version_;
79 gl_minor_version = ctx_gl.context_minor_version_;
80# elif defined(WITH_GHOST_X11) || defined(WITH_GHOST_WAYLAND)
81 if (
dynamic_cast<GHOST_ContextEGL *
>(&ghost_ctx)) {
82 GHOST_ContextEGL &ctx_gl =
static_cast<GHOST_ContextEGL &
>(ghost_ctx);
83 gl_major_version = ctx_gl.context_major_version_;
84 gl_minor_version = ctx_gl.context_minor_version_;
86# if defined(WITH_GHOST_X11)
88 GHOST_ContextGLX &ctx_gl =
static_cast<GHOST_ContextGLX &
>(ghost_ctx);
89 gl_major_version = ctx_gl.context_major_version_;
90 gl_minor_version = ctx_gl.context_minor_version_;
94 static PFN_xrGetOpenGLGraphicsRequirementsKHR s_xrGetOpenGLGraphicsRequirementsKHR_fn =
97 XrGraphicsRequirementsOpenGLKHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR};
98 const XrVersion gl_version = XR_MAKE_VERSION(gl_major_version, gl_minor_version, 0);
106 s_xrGetOpenGLGraphicsRequirementsKHR_fn =
nullptr;
108 if (!s_xrGetOpenGLGraphicsRequirementsKHR_fn &&
110 xrGetInstanceProcAddr(instance,
111 "xrGetOpenGLGraphicsRequirementsKHR",
112 (PFN_xrVoidFunction *)&s_xrGetOpenGLGraphicsRequirementsKHR_fn)))
114 s_xrGetOpenGLGraphicsRequirementsKHR_fn =
nullptr;
118 s_xrGetOpenGLGraphicsRequirementsKHR_fn(instance, system_id, &gpu_requirements);
120 if (r_requirement_info) {
121 std::ostringstream strstream;
122 strstream <<
"Min OpenGL version "
123 << XR_VERSION_MAJOR(gpu_requirements.minApiVersionSupported) <<
"."
124 << XR_VERSION_MINOR(gpu_requirements.minApiVersionSupported) << std::endl;
125 strstream <<
"Max OpenGL version "
126 << XR_VERSION_MAJOR(gpu_requirements.maxApiVersionSupported) <<
"."
127 << XR_VERSION_MINOR(gpu_requirements.maxApiVersionSupported) << std::endl;
129 *r_requirement_info = strstream.str();
132 return (gl_version >= gpu_requirements.minApiVersionSupported) &&
133 (gl_version <= gpu_requirements.maxApiVersionSupported);
138 XrSystemId )
override
140# if defined(WITH_GHOST_X11) || defined(WITH_GHOST_WAYLAND)
144 const bool is_ctx_egl =
dynamic_cast<GHOST_ContextEGL *
>(&ghost_ctx) !=
nullptr;
146 GHOST_ContextEGL &ctx_egl =
static_cast<GHOST_ContextEGL &
>(ghost_ctx);
147 const bool is_wayland = (
148# if defined(WITH_GHOST_WAYLAND)
149 dynamic_cast<const GHOST_SystemWayland *const
>(ctx_egl.system_) !=
nullptr
156# if defined(WITH_GHOST_WAYLAND)
158 oxr_binding.wl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR;
159 oxr_binding.wl.display = (
wl_display *)ctx_egl.native_display_;
161 GHOST_ASSERT(
false,
"Unexpected State: logical error, unreachable!");
165# if defined(WITH_GHOST_X11)
167 oxr_binding.egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX;
168# if XR_CURRENT_API_VERSION >= XR_MAKE_VERSION(1, 0, 29)
169 oxr_binding.egl.getProcAddress =
reinterpret_cast<PFN_xrEglGetProcAddressMNDX
>(
172 oxr_binding.egl.getProcAddress =
reinterpret_cast<PFNEGLGETPROCADDRESSPROC
>(
175 oxr_binding.egl.display = ctx_egl.
getDisplay();
176 oxr_binding.egl.config = ctx_egl.
getConfig();
177 oxr_binding.egl.context = ctx_egl.
getContext();
179 GHOST_ASSERT(
false,
"Unexpected State: built with only WAYLAND and no System found!");
184# if defined(WITH_GHOST_X11)
185 GHOST_ContextGLX &ctx_glx =
static_cast<GHOST_ContextGLX &
>(ghost_ctx);
186 XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.display_, ctx_glx.fbconfig_);
188 oxr_binding.glx.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
189 oxr_binding.glx.xDisplay = ctx_glx.display_;
190 oxr_binding.glx.glxFBConfig = ctx_glx.fbconfig_;
191 oxr_binding.glx.glxDrawable = ctx_glx.window_;
192 oxr_binding.glx.glxContext = ctx_glx.context_;
193 oxr_binding.glx.visualid = visual_info->visualid;
197 GHOST_ASSERT(
false,
"Unexpected State: built without X11 and no EGL context is available!");
201 GHOST_ContextWGL &ctx_wgl =
static_cast<GHOST_ContextWGL &
>(ghost_ctx);
203 oxr_binding.wgl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR;
204 oxr_binding.wgl.hDC = ctx_wgl.h_DC_;
205 oxr_binding.wgl.hGLRC = ctx_wgl.h_GLRC_;
209 glGenFramebuffers(1, &fbo_);
213 GHOST_TXrSwapchainFormat &r_format,
214 bool &r_is_srgb_format)
const override
216 std::vector<int64_t> gpu_binding_formats = {
236 r_format = GHOST_kXrSwapchainFormatRGB10_A2;
239 r_format = GHOST_kXrSwapchainFormatRGBA16;
242 r_format = GHOST_kXrSwapchainFormatRGBA16F;
245 case GL_SRGB8_ALPHA8:
246 r_format = GHOST_kXrSwapchainFormatRGBA8;
249 r_is_srgb_format = (*
result == GL_SRGB8_ALPHA8);
252 r_format = GHOST_kXrSwapchainFormatRGBA8;
253 r_is_srgb_format =
false;
261 std::vector<XrSwapchainImageOpenGLKHR> ogl_images(image_count);
262 std::vector<XrSwapchainImageBaseHeader *> base_images;
266 for (XrSwapchainImageOpenGLKHR &image : ogl_images) {
267 image.type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR;
268 base_images.push_back(
reinterpret_cast<XrSwapchainImageBaseHeader *
>(&image));
272 image_cache_.push_back(std::move(ogl_images));
279 const GHOST_XrDrawViewInfo &draw_info)
override
281 XrSwapchainImageOpenGLKHR &ogl_swapchain_image =
reinterpret_cast<XrSwapchainImageOpenGLKHR &
>(
284 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_);
286 glFramebufferTexture2D(
287 GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ogl_swapchain_image.image, 0);
289 glBlitFramebuffer(draw_info.ofsx,
291 draw_info.ofsx + draw_info.width,
292 draw_info.ofsy + draw_info.height,
295 draw_info.ofsx + draw_info.width,
296 draw_info.ofsy + draw_info.height,
300 glBindFramebuffer(GL_FRAMEBUFFER, 0);
310 std::list<std::vector<XrSwapchainImageOpenGLKHR>> image_cache_;
319#ifdef WITH_OPENGL_BACKEND
320 case GHOST_kXrGraphicsOpenGL:
321 return std::make_unique<GHOST_XrGraphicsBindingOpenGL>();
323#ifdef WITH_VULKAN_BACKEND
324 case GHOST_kXrGraphicsVulkan:
325 return std::make_unique<GHOST_XrGraphicsBindingVulkan>(context);
328# ifdef WITH_OPENGL_BACKEND
329 case GHOST_kXrGraphicsOpenGLD3D11:
330 return std::make_unique<GHOST_XrGraphicsBindingOpenGLD3D>(context);
332# ifdef WITH_VULKAN_BACKEND
333 case GHOST_kXrGraphicsVulkanD3D11:
334 return std::make_unique<GHOST_XrGraphicsBindingVulkanD3D>(context);
GHOST C-API function and type declarations.
#define GHOST_ASSERT(x, info)
static std::optional< int64_t > choose_swapchain_format_from_candidates(const std::vector< int64_t > &gpu_binding_formats, const std::vector< int64_t > &runtime_formats)
std::unique_ptr< GHOST_IXrGraphicsBinding > GHOST_XrGraphicsBindingCreateFromType(GHOST_TXrGraphicsBinding type, GHOST_Context &context)
EGLConfig getConfig() const
EGLDisplay getDisplay() const
EGLContext getContext() const
virtual bool isUpsideDown() const
virtual bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const =0
virtual std::vector< XrSwapchainImageBaseHeader * > createSwapchainImages(uint32_t image_count)=0
virtual void submitToSwapchainEnd()=0
virtual bool checkVersionRequirements(class GHOST_Context &ghost_ctx, XrInstance instance, XrSystemId system_id, std::string *r_requirement_info) const =0
virtual std::optional< int64_t > chooseSwapchainFormat(const std::vector< int64_t > &runtime_formats, GHOST_TXrSwapchainFormat &r_format, bool &r_is_rgb_format) const =0
virtual void submitToSwapchainBegin()=0
virtual void initFromGhostContext(class GHOST_Context &ghost_ctx, XrInstance instance, XrSystemId system_id)=0
virtual void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image, const GHOST_XrDrawViewInfo &draw_info)=0