VR: Refactor DirectX context management

All DirectX management happens on Ghost level now, higher level code can
just assume everything is OpenGL (except of the upside-down drawing that
still needs to be done for DirectX). This is similar to how the
metal-layer is hidden outside of Ghost.

The Ghost-XR graphics binding for DirectX is responsible for managing
the DirectX compatibility now.
This commit is contained in:
Julian Eisel 2020-04-02 17:40:29 +02:00
parent 868d4526a8
commit 34465a7fb0
Notes: blender-bot 2023-02-14 08:06:33 +01:00
Referenced by commit 6eb409bb9c, Fix warnings caused by own earlier commit
20 changed files with 125 additions and 198 deletions

View File

@ -214,25 +214,6 @@ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemha
extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
GHOST_ContextHandle contexthandle);
#ifdef WIN32
/**
* Create a new offscreen context.
* Never explicitly delete the context, use disposeContext() instead.
* \param systemhandle The handle to the system
* \return A handle to the new context ( == NULL if creation failed).
*/
GHOST_ContextHandle GHOST_CreateDirectXContext(GHOST_SystemHandle systemhandle);
/**
* Dispose of a context.
* \param systemhandle The handle to the system
* \param contexthandle Handle to the context to be disposed.
* \return Indication of success.
*/
GHOST_TSuccess GHOST_DisposeDirectXContext(GHOST_SystemHandle systemhandle,
GHOST_ContextHandle contexthandle);
#endif
/**
* Returns the window user data.
* \param windowhandle The handle to the window
@ -1078,6 +1059,13 @@ void GHOST_XrSessionDrawViews(GHOST_XrContextHandle xr_context, void *customdata
*/
int GHOST_XrSessionIsRunning(const GHOST_XrContextHandle xr_context);
/**
* Check if \a xr_context has a session that requrires an upside-down framebuffer (compared to
* OpenGL). If true, the render result should be flipped vertically for correct output.
* \note: Only to be called after session start, may otherwise result in a false negative.
*/
int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_XrContextHandle xr_context);
/* events */
/**
* Invoke handling of all OpenXR events for \a xr_context. Should be called on every main-loop

View File

@ -60,11 +60,6 @@ class GHOST_IContext {
virtual GHOST_TSuccess swapBuffers() = 0;
/**
* Returns if the window is rendered upside down compared to OpenGL.
*/
virtual bool isUpsideDown() const = 0;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IContext")
#endif

View File

@ -266,12 +266,6 @@ class GHOST_ISystem {
*/
virtual GHOST_IContext *createOffscreenContext() = 0;
/**
* Overload to allow requesting a different context type. By default only OpenGL is supported.
* However by explicitly overloading this a system may add support for others.
*/
virtual GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type) = 0;
/**
* Dispose of a context.
* \param context Pointer to the context to be disposed.

View File

@ -37,6 +37,8 @@ class GHOST_IXrContext {
virtual void setGraphicsContextBindFuncs(GHOST_XrGraphicsContextBindFn bind_fn,
GHOST_XrGraphicsContextUnbindFn unbind_fn) = 0;
virtual void setDrawViewFunc(GHOST_XrDrawViewFn draw_view_fn) = 0;
virtual bool needsUpsideDownDrawing() const = 0;
};
#endif // __GHOST_IXRCONTEXT_H__

View File

@ -621,9 +621,8 @@ typedef void (*GHOST_XrErrorHandlerFn)(const struct GHOST_XrError *);
typedef void (*GHOST_XrSessionExitFn)(void *customdata);
typedef void *(*GHOST_XrGraphicsContextBindFn)(enum GHOST_TXrGraphicsBinding graphics_lib);
typedef void (*GHOST_XrGraphicsContextUnbindFn)(enum GHOST_TXrGraphicsBinding graphics_lib,
GHOST_ContextHandle graphics_context);
typedef void *(*GHOST_XrGraphicsContextBindFn)();
typedef void (*GHOST_XrGraphicsContextUnbindFn)(GHOST_ContextHandle graphics_context);
typedef void (*GHOST_XrDrawViewFn)(const struct GHOST_XrDrawViewInfo *draw_view, void *customdata);
/* An array of GHOST_TXrGraphicsBinding items defining the candidate bindings to use. The first

View File

@ -150,25 +150,6 @@ GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
return system->disposeContext(context);
}
#ifdef WIN32
GHOST_ContextHandle GHOST_CreateDirectXContext(GHOST_SystemHandle systemhandle)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
return (GHOST_ContextHandle)system->createOffscreenContext(GHOST_kDrawingContextTypeD3D);
}
GHOST_TSuccess GHOST_DisposeDirectXContext(GHOST_SystemHandle systemhandle,
GHOST_ContextHandle contexthandle)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
return system->disposeContext(context);
}
#endif
GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
const char *title,
GHOST_TInt32 left,
@ -716,13 +697,6 @@ unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contex
return context->getDefaultFramebuffer();
}
int GHOST_isUpsideDownContext(GHOST_ContextHandle contexthandle)
{
GHOST_IContext *context = (GHOST_IContext *)contexthandle;
return context->isUpsideDown();
}
unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
@ -991,4 +965,12 @@ void GHOST_XrDrawViewFunc(GHOST_XrContextHandle xr_contexthandle, GHOST_XrDrawVi
GHOST_XR_CAPI_CALL(xr_context->setDrawViewFunc(draw_view_fn), xr_context);
}
int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_XrContextHandle xr_contexthandle)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
GHOST_XR_CAPI_CALL_RET(xr_context->needsUpsideDownDrawing(), xr_context);
return 0; /* Only reached if exception is thrown. */
}
#endif

View File

@ -120,9 +120,9 @@ class GHOST_Context : public GHOST_IContext {
}
/**
* Returns if the window is rendered upside down compared to OpenGL.
* Returns if the context is rendered upside down compared to OpenGL.
*/
inline bool isUpsideDown() const
virtual inline bool isUpsideDown() const
{
return false;
}

View File

@ -61,6 +61,7 @@ class GHOST_IXrGraphicsBinding {
uint32_t image_count) = 0;
virtual void submitToSwapchainImage(XrSwapchainImageBaseHeader *swapchain_image,
const GHOST_XrDrawViewInfo *draw_info) = 0;
virtual bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const = 0;
protected:
/* Use GHOST_XrGraphicsBindingCreateFromType! */
@ -68,6 +69,6 @@ class GHOST_IXrGraphicsBinding {
};
std::unique_ptr<GHOST_IXrGraphicsBinding> GHOST_XrGraphicsBindingCreateFromType(
GHOST_TXrGraphicsBinding type);
GHOST_TXrGraphicsBinding type, GHOST_Context *ghost_ctx);
#endif /* __GHOST_IXRGRAPHICSBINDING_H__ */

View File

@ -122,16 +122,6 @@ GHOST_TSuccess GHOST_System::disposeWindow(GHOST_IWindow *window)
return success;
}
GHOST_IContext *GHOST_System::createOffscreenContext(GHOST_TDrawingContextType type)
{
switch (type) {
case GHOST_kDrawingContextTypeOpenGL:
return createOffscreenContext();
default:
return NULL;
}
}
bool GHOST_System::validWindow(GHOST_IWindow *window)
{
return m_windowManager->getWindowFound(window);

View File

@ -118,12 +118,6 @@ class GHOST_System : public GHOST_ISystem {
*/
virtual GHOST_IContext *createOffscreenContext() = 0;
/**
* Overload to allow requesting a different context type. By default only OpenGL is supported.
* However by explicitly overloading this a system may add support for others.
*/
GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type);
/**
* Returns whether a window is valid.
* \param window Pointer to the window to be checked.

View File

@ -411,9 +411,9 @@ GHOST_TSuccess GHOST_SystemWin32::disposeContext(GHOST_IContext *context)
* Never explicitly delete the window, use #disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
GHOST_IContext *GHOST_SystemWin32::createOffscreenContextD3D()
GHOST_ContextD3D *GHOST_SystemWin32::createOffscreenContextD3D()
{
GHOST_Context *context;
GHOST_ContextD3D *context;
HWND wnd = CreateWindowA("STATIC",
"Blender XR",
@ -435,16 +435,11 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContextD3D()
return context;
}
GHOST_IContext *GHOST_SystemWin32::createOffscreenContext(GHOST_TDrawingContextType type)
GHOST_TSuccess GHOST_SystemWin32::disposeContextD3D(GHOST_ContextD3D *context)
{
switch (type) {
case GHOST_kDrawingContextTypeOpenGL:
return createOffscreenContext();
case GHOST_kDrawingContextTypeD3D:
return createOffscreenContextD3D();
default:
return NULL;
}
delete context;
return GHOST_kSuccess;
}
bool GHOST_SystemWin32::processEvents(bool waitForEvent)

View File

@ -42,6 +42,7 @@ class GHOST_EventWheel;
class GHOST_EventWindow;
class GHOST_EventDragnDrop;
class GHOST_ContextD3D;
class GHOST_WindowWin32;
/**
@ -130,13 +131,6 @@ class GHOST_SystemWin32 : public GHOST_System {
*/
GHOST_IContext *createOffscreenContext();
/**
* Create a new offscreen context.
* Never explicitly delete the window, use disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type);
/**
* Dispose of a context.
* \param context Pointer to the context to be disposed.
@ -144,6 +138,23 @@ class GHOST_SystemWin32 : public GHOST_System {
*/
GHOST_TSuccess disposeContext(GHOST_IContext *context);
/**
* Create a new offscreen DirectX context.
* Never explicitly delete the context, use disposeContext() instead.
* This is for GHOST internal, Win32 specific use, so it can be called statically.
*
* \return The new context (or 0 if creation failed).
*/
static GHOST_ContextD3D *createOffscreenContextD3D();
/**
* Dispose of a DirectX context.
* This is for GHOST internal, Win32 specific use, so it can be called statically.
* \param context Pointer to the context to be disposed.
* \return Indication of success.
*/
static GHOST_TSuccess disposeContextD3D(GHOST_ContextD3D *context);
/***************************************************************************************
** Event management functionality
***************************************************************************************/
@ -255,13 +266,6 @@ class GHOST_SystemWin32 : public GHOST_System {
*/
GHOST_TSuccess exit();
/**
* Create a new offscreen DirectX context.
* Never explicitly delete the window, use disposeContext() instead.
* \return The new context (or 0 if creation failed).
*/
GHOST_IContext *createOffscreenContextD3D();
/**
* Converts raw WIN32 key codes from the wndproc to GHOST keys.
* \param vKey The virtual key from hardKey

View File

@ -512,6 +512,13 @@ void GHOST_XrContext::setDrawViewFunc(GHOST_XrDrawViewFn draw_view_fn)
m_custom_funcs.draw_view_fn = draw_view_fn;
}
bool GHOST_XrContext::needsUpsideDownDrawing() const
{
/* Must only be called after the session was started */
assert(m_session);
return m_session->needsUpsideDownDrawing();
}
/** \} */ /* Public Accessors and Mutators */
/* -------------------------------------------------------------------- */

View File

@ -78,6 +78,7 @@ class GHOST_XrContext : public GHOST_IXrContext {
void setGraphicsContextBindFuncs(GHOST_XrGraphicsContextBindFn bind_fn,
GHOST_XrGraphicsContextUnbindFn unbind_fn) override;
void setDrawViewFunc(GHOST_XrDrawViewFn draw_view_fn) override;
bool needsUpsideDownDrawing() const override;
void handleSessionStateChange(const XrEventDataSessionStateChanged *lifecycle);

View File

@ -27,6 +27,7 @@
#elif defined(WIN32)
# include "GHOST_ContextD3D.h"
# include "GHOST_ContextWGL.h"
# include "GHOST_SystemWin32.h"
#endif
#include "GHOST_C-api.h"
#include "GHOST_Xr_intern.h"
@ -180,6 +181,11 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const
{
return ghost_ctx.isUpsideDown();
}
private:
std::list<std::vector<XrSwapchainImageOpenGLKHR>> m_image_cache;
GLuint m_fbo = 0;
@ -188,19 +194,27 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
#ifdef WIN32
class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
public:
GHOST_XrGraphicsBindingD3D(GHOST_Context *ghost_ctx)
: GHOST_IXrGraphicsBinding(), m_ghost_wgl_ctx(*static_cast<GHOST_ContextWGL *>(ghost_ctx))
{
m_ghost_d3d_ctx = GHOST_SystemWin32::createOffscreenContextD3D();
}
~GHOST_XrGraphicsBindingD3D()
{
if (m_shared_resource) {
m_ghost_ctx->disposeSharedOpenGLResource(m_shared_resource);
m_ghost_d3d_ctx->disposeSharedOpenGLResource(m_shared_resource);
}
if (m_ghost_d3d_ctx) {
GHOST_SystemWin32::disposeContextD3D(m_ghost_d3d_ctx);
}
}
bool checkVersionRequirements(GHOST_Context *ghost_ctx,
XrInstance instance,
XrSystemId system_id,
std::string *r_requirement_info) const override
bool checkVersionRequirements(
GHOST_Context * /*ghost_ctx*/, /* Remember: This is the OpenGL context! */
XrInstance instance,
XrSystemId system_id,
std::string *r_requirement_info) const override
{
GHOST_ContextD3D *ctx_dx = static_cast<GHOST_ContextD3D *>(ghost_ctx);
static PFN_xrGetD3D11GraphicsRequirementsKHR s_xrGetD3D11GraphicsRequirementsKHR_fn = nullptr;
XrGraphicsRequirementsD3D11KHR gpu_requirements = {XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR};
@ -222,16 +236,15 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
*r_requirement_info = std::move(strstream.str());
}
return ctx_dx->m_device->GetFeatureLevel() >= gpu_requirements.minFeatureLevel;
return m_ghost_d3d_ctx->m_device->GetFeatureLevel() >= gpu_requirements.minFeatureLevel;
}
void initFromGhostContext(GHOST_Context *ghost_ctx) override
void initFromGhostContext(
GHOST_Context * /*ghost_ctx*/ /* Remember: This is the OpenGL context! */
) override
{
GHOST_ContextD3D *ctx_d3d = static_cast<GHOST_ContextD3D *>(ghost_ctx);
oxr_binding.d3d11.type = XR_TYPE_GRAPHICS_BINDING_D3D11_KHR;
oxr_binding.d3d11.device = ctx_d3d->m_device;
m_ghost_ctx = ctx_d3d;
oxr_binding.d3d11.device = m_ghost_d3d_ctx->m_device;
}
bool chooseSwapchainFormat(const std::vector<int64_t> &runtime_formats,
@ -284,33 +297,43 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding {
m_ghost_ctx->blitFromOpenGLContext(m_shared_resource, draw_info->width, draw_info->height);
# else
if (!m_shared_resource) {
m_shared_resource = m_ghost_ctx->createSharedOpenGLResource(draw_info->width,
draw_info->height);
m_shared_resource = m_ghost_d3d_ctx->createSharedOpenGLResource(draw_info->width,
draw_info->height);
}
m_ghost_ctx->blitFromOpenGLContext(m_shared_resource, draw_info->width, draw_info->height);
m_ghost_d3d_ctx->blitFromOpenGLContext(m_shared_resource, draw_info->width, draw_info->height);
m_ghost_ctx->m_device_ctx->OMSetRenderTargets(0, nullptr, nullptr);
m_ghost_ctx->m_device_ctx->CopyResource(d3d_swapchain_image->texture,
m_ghost_ctx->getSharedTexture2D(m_shared_resource));
m_ghost_d3d_ctx->m_device_ctx->OMSetRenderTargets(0, nullptr, nullptr);
m_ghost_d3d_ctx->m_device_ctx->CopyResource(
d3d_swapchain_image->texture, m_ghost_d3d_ctx->getSharedTexture2D(m_shared_resource));
# endif
}
bool needsUpsideDownDrawing(GHOST_Context &) const
{
return m_ghost_d3d_ctx->isUpsideDown();
}
private:
GHOST_ContextD3D *m_ghost_ctx;
GHOST_SharedOpenGLResource *m_shared_resource;
/** Primary OpenGL context for Blender to use for drawing. */
GHOST_ContextWGL &m_ghost_wgl_ctx;
/** Secondary DirectX 11 context to share with OpenGL context. */
GHOST_ContextD3D *m_ghost_d3d_ctx = nullptr;
/** Handle to shared resource object. */
GHOST_SharedOpenGLResource *m_shared_resource = nullptr;
std::list<std::vector<XrSwapchainImageD3D11KHR>> m_image_cache;
};
#endif // WIN32
std::unique_ptr<GHOST_IXrGraphicsBinding> GHOST_XrGraphicsBindingCreateFromType(
GHOST_TXrGraphicsBinding type)
GHOST_TXrGraphicsBinding type, GHOST_Context *context)
{
switch (type) {
case GHOST_kXrGraphicsOpenGL:
return std::unique_ptr<GHOST_XrGraphicsBindingOpenGL>(new GHOST_XrGraphicsBindingOpenGL());
#ifdef WIN32
case GHOST_kXrGraphicsD3D11:
return std::unique_ptr<GHOST_XrGraphicsBindingD3D>(new GHOST_XrGraphicsBindingD3D());
return std::unique_ptr<GHOST_XrGraphicsBindingD3D>(new GHOST_XrGraphicsBindingD3D(context));
#endif
default:
return nullptr;

View File

@ -172,7 +172,8 @@ void GHOST_XrSession::start(const GHOST_XrSessionBeginInfo *begin_info)
}
std::string requirement_str;
m_gpu_binding = GHOST_XrGraphicsBindingCreateFromType(m_context->getGraphicsBindingType());
m_gpu_binding = GHOST_XrGraphicsBindingCreateFromType(m_context->getGraphicsBindingType(),
m_gpu_ctx);
if (!m_gpu_binding->checkVersionRequirements(
m_gpu_ctx, m_context->getInstance(), m_oxr->system_id, &requirement_str)) {
std::ostringstream strstream;
@ -456,6 +457,11 @@ XrCompositionLayerProjection GHOST_XrSession::drawLayer(
return layer;
}
bool GHOST_XrSession::needsUpsideDownDrawing() const
{
return m_gpu_binding && m_gpu_binding->needsUpsideDownDrawing(*m_gpu_ctx);
}
/** \} */ /* Drawing */
/* -------------------------------------------------------------------- */
@ -495,16 +501,14 @@ void GHOST_XrSession::bindGraphicsContext()
{
const GHOST_XrCustomFuncs &custom_funcs = m_context->getCustomFuncs();
assert(custom_funcs.gpu_ctx_bind_fn);
m_gpu_ctx = static_cast<GHOST_Context *>(
custom_funcs.gpu_ctx_bind_fn(m_context->getGraphicsBindingType()));
m_gpu_ctx = static_cast<GHOST_Context *>(custom_funcs.gpu_ctx_bind_fn());
}
void GHOST_XrSession::unbindGraphicsContext()
{
const GHOST_XrCustomFuncs &custom_funcs = m_context->getCustomFuncs();
if (custom_funcs.gpu_ctx_unbind_fn) {
custom_funcs.gpu_ctx_unbind_fn(m_context->getGraphicsBindingType(),
(GHOST_ContextHandle)m_gpu_ctx);
custom_funcs.gpu_ctx_unbind_fn((GHOST_ContextHandle)m_gpu_ctx);
}
m_gpu_ctx = nullptr;
}

View File

@ -47,6 +47,7 @@ class GHOST_XrSession {
LifeExpectancy handleStateChangeEvent(const XrEventDataSessionStateChanged *lifecycle);
bool isRunning() const;
bool needsUpsideDownDrawing() const;
void unbindGraphicsContext(); /* Public so context can ensure it's unbound as needed. */

View File

@ -156,10 +156,6 @@ void *WM_opengl_context_create(void);
void WM_opengl_context_dispose(void *context);
void WM_opengl_context_activate(void *context);
void WM_opengl_context_release(void *context);
#ifdef WIN32
void *WM_directx_context_create(void);
void WM_directx_context_dispose(void *context);
#endif
struct wmWindow *WM_window_open(struct bContext *C, const struct rcti *rect);
struct wmWindow *WM_window_open_temp(struct bContext *C,

View File

@ -2458,24 +2458,3 @@ void WM_ghost_show_message_box(const char *title,
GHOST_ShowMessageBox(g_system, title, message, help_label, continue_label, link, dialog_options);
}
/** \} */
#ifdef WIN32
/* -------------------------------------------------------------------- */
/** \name Direct DirectX Context Management
* \{ */
void *WM_directx_context_create(void)
{
BLI_assert(GPU_framebuffer_active_get() == NULL);
return GHOST_CreateDirectXContext(g_system);
}
void WM_directx_context_dispose(void *context)
{
BLI_assert(GPU_framebuffer_active_get() == NULL);
GHOST_DisposeDirectXContext(g_system, context);
}
/** \} */
#endif

View File

@ -68,9 +68,9 @@
struct wmXrRuntimeData *wm_xr_runtime_data_create(void);
void wm_xr_runtime_data_free(struct wmXrRuntimeData **runtime);
void wm_xr_draw_view(const GHOST_XrDrawViewInfo *, void *);
void *wm_xr_session_gpu_binding_context_create(GHOST_TXrGraphicsBinding);
void wm_xr_session_gpu_binding_context_destroy(GHOST_TXrGraphicsBinding, GHOST_ContextHandle);
wmSurface *wm_xr_session_surface_create(wmWindowManager *, unsigned int);
void *wm_xr_session_gpu_binding_context_create();
void wm_xr_session_gpu_binding_context_destroy(GHOST_ContextHandle);
wmSurface *wm_xr_session_surface_create(void);
void wm_xr_pose_to_viewmat(const GHOST_XrPose *pose, float r_viewmat[4][4]);
/* -------------------------------------------------------------------- */
@ -109,11 +109,8 @@ typedef struct wmXrDrawData {
} wmXrDrawData;
typedef struct {
GHOST_TXrGraphicsBinding gpu_binding_type;
GPUOffScreen *offscreen;
GPUViewport *viewport;
GHOST_ContextHandle secondary_ghost_ctx;
} wmXrSurfaceData;
typedef struct {
@ -412,10 +409,9 @@ bool WM_xr_session_state_viewer_pose_matrix_info_get(const wmXrData *xr,
*
* \{ */
void *wm_xr_session_gpu_binding_context_create(GHOST_TXrGraphicsBinding graphics_binding)
void *wm_xr_session_gpu_binding_context_create(void)
{
wmSurface *surface = wm_xr_session_surface_create(G_MAIN->wm.first, graphics_binding);
wmXrSurfaceData *data = surface->customdata;
wmSurface *surface = wm_xr_session_surface_create();
wm_surface_add(surface);
@ -423,11 +419,10 @@ void *wm_xr_session_gpu_binding_context_create(GHOST_TXrGraphicsBinding graphics
* and running. */
WM_main_add_notifier(NC_WM | ND_XR_DATA_CHANGED, NULL);
return data->secondary_ghost_ctx ? data->secondary_ghost_ctx : surface->ghost_ctx;
return surface->ghost_ctx;
}
void wm_xr_session_gpu_binding_context_destroy(GHOST_TXrGraphicsBinding UNUSED(graphics_lib),
GHOST_ContextHandle UNUSED(context))
void wm_xr_session_gpu_binding_context_destroy(GHOST_ContextHandle UNUSED(context))
{
if (g_xr_surface) { /* Might have been freed already */
wm_surface_remove(g_xr_surface);
@ -532,13 +527,6 @@ static void wm_xr_session_free_data(wmSurface *surface)
{
wmXrSurfaceData *data = surface->customdata;
if (data->secondary_ghost_ctx) {
#ifdef WIN32
if (data->gpu_binding_type == GHOST_kXrGraphicsD3D11) {
WM_directx_context_dispose(data->secondary_ghost_ctx);
}
#endif
}
if (data->viewport) {
GPU_viewport_free(data->viewport);
}
@ -591,7 +579,7 @@ static bool wm_xr_session_surface_offscreen_ensure(const GHOST_XrDrawViewInfo *d
return true;
}
wmSurface *wm_xr_session_surface_create(wmWindowManager *UNUSED(wm), unsigned int gpu_binding_type)
wmSurface *wm_xr_session_surface_create(void)
{
if (g_xr_surface) {
BLI_assert(false);
@ -601,30 +589,13 @@ wmSurface *wm_xr_session_surface_create(wmWindowManager *UNUSED(wm), unsigned in
wmSurface *surface = MEM_callocN(sizeof(*surface), __func__);
wmXrSurfaceData *data = MEM_callocN(sizeof(*data), "XrSurfaceData");
#ifndef WIN32
BLI_assert(gpu_binding_type == GHOST_kXrGraphicsOpenGL);
#endif
surface->draw = wm_xr_session_surface_draw;
surface->free_data = wm_xr_session_free_data;
data->gpu_binding_type = gpu_binding_type;
surface->customdata = data;
surface->ghost_ctx = DRW_xr_opengl_context_get();
switch (gpu_binding_type) {
case GHOST_kXrGraphicsOpenGL:
break;
#ifdef WIN32
case GHOST_kXrGraphicsD3D11:
data->secondary_ghost_ctx = WM_directx_context_create();
break;
#endif
}
surface->gpu_ctx = DRW_xr_gpu_context_get();
surface->customdata = data;
g_xr_surface = surface;
return surface;
@ -679,10 +650,11 @@ static void wm_xr_draw_matrices_create(const wmXrDrawData *draw_data,
}
static void wm_xr_draw_viewport_buffers_to_active_framebuffer(
const wmXrSurfaceData *surface_data, const GHOST_XrDrawViewInfo *draw_view)
const wmXrRuntimeData *runtime_data,
const wmXrSurfaceData *surface_data,
const GHOST_XrDrawViewInfo *draw_view)
{
const bool is_upside_down = surface_data->secondary_ghost_ctx &&
GHOST_isUpsideDownContext(surface_data->secondary_ghost_ctx);
const bool is_upside_down = GHOST_XrSessionNeedsUpsideDownDrawing(runtime_data->context);
rcti rect = {.xmin = 0, .ymin = 0, .xmax = draw_view->width - 1, .ymax = draw_view->height - 1};
wmViewport(&rect);
@ -759,7 +731,7 @@ void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)
GPU_offscreen_bind(surface_data->offscreen, false);
wm_xr_draw_viewport_buffers_to_active_framebuffer(surface_data, draw_view);
wm_xr_draw_viewport_buffers_to_active_framebuffer(wm->xr.runtime, surface_data, draw_view);
}
/** \} */ /* XR Drawing */