13#if defined(WITH_GHOST_X11)
18#if defined(WITH_GHOST_WAYLAND)
34 const std::vector<int64_t> &gpu_binding_formats,
const std::vector<int64_t> &runtime_formats)
36 if (gpu_binding_formats.empty()) {
40 auto res = std::find_first_of(gpu_binding_formats.begin(),
41 gpu_binding_formats.end(),
42 runtime_formats.begin(),
43 runtime_formats.end());
44 if (res == gpu_binding_formats.end()) {
56 glDeleteFramebuffers(1, &m_fbo);
63 std::string *r_requirement_info)
const override
65 int gl_major_version, gl_minor_version;
68 gl_major_version = ctx_gl.m_contextMajorVersion;
69 gl_minor_version = ctx_gl.m_contextMinorVersion;
70#elif defined(WITH_GHOST_X11) || defined(WITH_GHOST_WAYLAND)
73 gl_major_version = ctx_gl.m_contextMajorVersion;
74 gl_minor_version = ctx_gl.m_contextMinorVersion;
76# if defined(WITH_GHOST_X11)
79 gl_major_version = ctx_gl.m_contextMajorVersion;
80 gl_minor_version = ctx_gl.m_contextMinorVersion;
84 static PFN_xrGetOpenGLGraphicsRequirementsKHR s_xrGetOpenGLGraphicsRequirementsKHR_fn =
87 XrGraphicsRequirementsOpenGLKHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR};
88 const XrVersion gl_version = XR_MAKE_VERSION(gl_major_version, gl_minor_version, 0);
96 s_xrGetOpenGLGraphicsRequirementsKHR_fn =
nullptr;
98 if (!s_xrGetOpenGLGraphicsRequirementsKHR_fn &&
101 "xrGetOpenGLGraphicsRequirementsKHR",
102 (PFN_xrVoidFunction *)&s_xrGetOpenGLGraphicsRequirementsKHR_fn)))
104 s_xrGetOpenGLGraphicsRequirementsKHR_fn =
nullptr;
108 s_xrGetOpenGLGraphicsRequirementsKHR_fn(
instance, system_id, &gpu_requirements);
110 if (r_requirement_info) {
111 std::ostringstream strstream;
112 strstream <<
"Min OpenGL version "
113 << XR_VERSION_MAJOR(gpu_requirements.minApiVersionSupported) <<
"."
114 << XR_VERSION_MINOR(gpu_requirements.minApiVersionSupported) << std::endl;
115 strstream <<
"Max OpenGL version "
116 << XR_VERSION_MAJOR(gpu_requirements.maxApiVersionSupported) <<
"."
117 << XR_VERSION_MINOR(gpu_requirements.maxApiVersionSupported) << std::endl;
119 *r_requirement_info = strstream.str();
122 return (gl_version >= gpu_requirements.minApiVersionSupported) &&
123 (gl_version <= gpu_requirements.maxApiVersionSupported);
128#if defined(WITH_GHOST_X11) || defined(WITH_GHOST_WAYLAND)
132 const bool is_ctx_egl =
dynamic_cast<GHOST_ContextEGL *
>(&ghost_ctx) !=
nullptr;
135 const bool is_wayland = (
136# if defined(WITH_GHOST_WAYLAND)
144# if defined(WITH_GHOST_WAYLAND)
146 oxr_binding.wl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR;
149 GHOST_ASSERT(
false,
"Unexpected State: logical error, unreachable!");
153# if defined(WITH_GHOST_X11)
155 oxr_binding.egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX;
156# if XR_CURRENT_API_VERSION >= XR_MAKE_VERSION(1, 0, 29)
157 oxr_binding.egl.getProcAddress =
reinterpret_cast<PFN_xrEglGetProcAddressMNDX
>(
160 oxr_binding.egl.getProcAddress =
reinterpret_cast<PFNEGLGETPROCADDRESSPROC
>(
167 GHOST_ASSERT(
false,
"Unexpected State: built with only WAYLAND and no System found!");
172# if defined(WITH_GHOST_X11)
174 XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.m_display, ctx_glx.m_fbconfig);
176 oxr_binding.glx.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
185 GHOST_ASSERT(
false,
"Unexpected State: built without X11 and no EGL context is available!");
191 oxr_binding.wgl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR;
197 glGenFramebuffers(1, &m_fbo);
201 GHOST_TXrSwapchainFormat &r_format,
202 bool &r_is_srgb_format)
const override
204 std::vector<int64_t> gpu_binding_formats = {
224 r_format = GHOST_kXrSwapchainFormatRGB10_A2;
227 r_format = GHOST_kXrSwapchainFormatRGBA16;
230 r_format = GHOST_kXrSwapchainFormatRGBA16F;
233 case GL_SRGB8_ALPHA8:
234 r_format = GHOST_kXrSwapchainFormatRGBA8;
237 r_is_srgb_format = (*
result == GL_SRGB8_ALPHA8);
240 r_format = GHOST_kXrSwapchainFormatRGBA8;
241 r_is_srgb_format =
false;
249 std::vector<XrSwapchainImageOpenGLKHR> ogl_images(image_count);
250 std::vector<XrSwapchainImageBaseHeader *> base_images;
254 for (XrSwapchainImageOpenGLKHR &
image : ogl_images) {
255 image.type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR;
256 base_images.push_back(
reinterpret_cast<XrSwapchainImageBaseHeader *
>(&
image));
260 m_image_cache.push_back(std::move(ogl_images));
266 const GHOST_XrDrawViewInfo &draw_info)
override
268 XrSwapchainImageOpenGLKHR &ogl_swapchain_image =
reinterpret_cast<XrSwapchainImageOpenGLKHR &
>(
271 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
273 glFramebufferTexture2D(
274 GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ogl_swapchain_image.image, 0);
276 glBlitFramebuffer(draw_info.ofsx,
278 draw_info.ofsx + draw_info.width,
279 draw_info.ofsy + draw_info.height,
282 draw_info.ofsx + draw_info.width,
283 draw_info.ofsy + draw_info.height,
287 glBindFramebuffer(GL_FRAMEBUFFER, 0);
296 std::list<std::vector<XrSwapchainImageOpenGLKHR>> m_image_cache;
301static void ghost_format_to_dx_format(GHOST_TXrSwapchainFormat ghost_format,
302 bool expects_srgb_buffer,
303 DXGI_FORMAT &r_dx_format)
305 r_dx_format = DXGI_FORMAT_UNKNOWN;
307 switch (ghost_format) {
308 case GHOST_kXrSwapchainFormatRGBA8:
309 r_dx_format = expects_srgb_buffer ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB :
310 DXGI_FORMAT_R8G8B8A8_UNORM;
312 case GHOST_kXrSwapchainFormatRGBA16:
313 r_dx_format = DXGI_FORMAT_R16G16B16A16_UNORM;
315 case GHOST_kXrSwapchainFormatRGBA16F:
316 r_dx_format = DXGI_FORMAT_R16G16B16A16_FLOAT;
318 case GHOST_kXrSwapchainFormatRGB10_A2:
319 r_dx_format = DXGI_FORMAT_R10G10B10A2_UNORM;
323 if (r_dx_format == DXGI_FORMAT_UNKNOWN) {
330 GHOST_XrGraphicsBindingD3D(GHOST_Context &ghost_ctx)
331 : GHOST_IXrGraphicsBinding(), m_ghost_wgl_ctx(static_cast<GHOST_ContextWGL &>(ghost_ctx))
335 ~GHOST_XrGraphicsBindingD3D()
337 if (m_shared_resource) {
338 m_ghost_d3d_ctx->disposeSharedOpenGLResource(m_shared_resource);
340 if (m_ghost_d3d_ctx) {
348 XrSystemId system_id,
349 std::string *r_requirement_info)
const override
351 static PFN_xrGetD3D11GraphicsRequirementsKHR s_xrGetD3D11GraphicsRequirementsKHR_fn =
nullptr;
353 XrGraphicsRequirementsD3D11KHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR};
361 s_xrGetD3D11GraphicsRequirementsKHR_fn =
nullptr;
363 if (!s_xrGetD3D11GraphicsRequirementsKHR_fn &&
366 "xrGetD3D11GraphicsRequirementsKHR",
367 (PFN_xrVoidFunction *)&s_xrGetD3D11GraphicsRequirementsKHR_fn)))
369 s_xrGetD3D11GraphicsRequirementsKHR_fn =
nullptr;
373 s_xrGetD3D11GraphicsRequirementsKHR_fn(
instance, system_id, &gpu_requirements);
375 if (r_requirement_info) {
376 std::ostringstream strstream;
377 strstream <<
"Minimum DirectX 11 Feature Level " << gpu_requirements.minFeatureLevel
380 *r_requirement_info = strstream.str();
383 return m_ghost_d3d_ctx->m_device->GetFeatureLevel() >= gpu_requirements.minFeatureLevel;
390 oxr_binding.d3d11.type = XR_TYPE_GRAPHICS_BINDING_D3D11_KHR;
391 oxr_binding.d3d11.device = m_ghost_d3d_ctx->m_device;
395 GHOST_TXrSwapchainFormat &r_format,
396 bool &r_is_srgb_format)
const override
398 std::vector<int64_t> gpu_binding_formats = {
401 DXGI_FORMAT_R10G10B10A2_UNORM,
402 DXGI_FORMAT_R16G16B16A16_UNORM,
404 DXGI_FORMAT_R16G16B16A16_FLOAT,
406 DXGI_FORMAT_R10G10B10A2_UNORM,
407 DXGI_FORMAT_R16G16B16A16_UNORM,
409 DXGI_FORMAT_R8G8B8A8_UNORM,
410 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
417 case DXGI_FORMAT_R10G10B10A2_UNORM:
418 r_format = GHOST_kXrSwapchainFormatRGB10_A2;
420 case DXGI_FORMAT_R16G16B16A16_UNORM:
421 r_format = GHOST_kXrSwapchainFormatRGBA16;
423 case DXGI_FORMAT_R16G16B16A16_FLOAT:
424 r_format = GHOST_kXrSwapchainFormatRGBA16F;
426 case DXGI_FORMAT_R8G8B8A8_UNORM:
427 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
428 r_format = GHOST_kXrSwapchainFormatRGBA8;
431 r_is_srgb_format = (*
result == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
434 r_format = GHOST_kXrSwapchainFormatRGBA8;
435 r_is_srgb_format =
false;
443 std::vector<XrSwapchainImageD3D11KHR> d3d_images(image_count);
444 std::vector<XrSwapchainImageBaseHeader *> base_images;
448 for (XrSwapchainImageD3D11KHR &
image : d3d_images) {
449 image.type = XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR;
450 base_images.push_back(
reinterpret_cast<XrSwapchainImageBaseHeader *
>(&
image));
454 m_image_cache.push_back(std::move(d3d_images));
460 const GHOST_XrDrawViewInfo &draw_info)
override
462 XrSwapchainImageD3D11KHR &d3d_swapchain_image =
reinterpret_cast<XrSwapchainImageD3D11KHR &
>(
472 ID3D11RenderTargetView *rtv;
473 CD3D11_RENDER_TARGET_VIEW_DESC rtv_desc(D3D11_RTV_DIMENSION_TEXTURE2D,
474 DXGI_FORMAT_R8G8B8A8_UNORM);
476 m_ghost_ctx->m_device->CreateRenderTargetView(d3d_swapchain_image.texture, &rtv_desc, &rtv);
477 if (!m_shared_resource) {
479 ghost_format_to_dx_format(draw_info.swapchain_format, draw_info.expects_srgb_buffer,
format);
480 m_shared_resource = m_ghost_ctx->createSharedOpenGLResource(
481 draw_info.width, draw_info.height,
format, rtv);
483 m_ghost_ctx->blitFromOpenGLContext(m_shared_resource, draw_info.width, draw_info.height);
485 if (!m_shared_resource) {
487 ghost_format_to_dx_format(draw_info.swapchain_format, draw_info.expects_srgb_buffer,
format);
488 m_shared_resource = m_ghost_d3d_ctx->createSharedOpenGLResource(
489 draw_info.width, draw_info.height,
format);
491 m_ghost_d3d_ctx->blitFromOpenGLContext(m_shared_resource, draw_info.width, draw_info.height);
493 m_ghost_d3d_ctx->m_device_ctx->OMSetRenderTargets(0,
nullptr,
nullptr);
494 m_ghost_d3d_ctx->m_device_ctx->CopyResource(
495 d3d_swapchain_image.texture, m_ghost_d3d_ctx->getSharedTexture2D(m_shared_resource));
501 return m_ghost_d3d_ctx->isUpsideDown();
506 GHOST_ContextWGL &m_ghost_wgl_ctx;
508 GHOST_ContextD3D *m_ghost_d3d_ctx =
nullptr;
510 GHOST_SharedOpenGLResource *m_shared_resource =
nullptr;
512 std::list<std::vector<XrSwapchainImageD3D11KHR>> m_image_cache;
520 case GHOST_kXrGraphicsOpenGL:
521 return std::make_unique<GHOST_XrGraphicsBindingOpenGL>();
523 case GHOST_kXrGraphicsD3D11:
524 return std::make_unique<GHOST_XrGraphicsBindingD3D>(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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object instance
EGLConfig getConfig() const
EGLDisplay getDisplay() const
EGLContext getContext() const
virtual bool isUpsideDown() const
GHOST_IXrGraphicsBinding()=default
virtual bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const =0
virtual std::vector< XrSwapchainImageBaseHeader * > createSwapchainImages(uint32_t image_count)=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 initFromGhostContext(class GHOST_Context &ghost_ctx)=0
union GHOST_IXrGraphicsBinding::@032107113146203207234320050047375011224045132242 oxr_binding
virtual void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image, const GHOST_XrDrawViewInfo &draw_info)=0
static GHOST_ContextD3D * createOffscreenContextD3D()
static GHOST_TSuccess disposeContextD3D(GHOST_ContextD3D *context)
~GHOST_XrGraphicsBindingOpenGL()
bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const override
std::optional< int64_t > chooseSwapchainFormat(const std::vector< int64_t > &runtime_formats, GHOST_TXrSwapchainFormat &r_format, bool &r_is_srgb_format) const override
void initFromGhostContext(GHOST_Context &ghost_ctx) override
bool checkVersionRequirements(GHOST_Context &ghost_ctx, XrInstance instance, XrSystemId system_id, std::string *r_requirement_info) const override
std::vector< XrSwapchainImageBaseHeader * > createSwapchainImages(uint32_t image_count) override
void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image, const GHOST_XrDrawViewInfo &draw_info) override
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)