Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-04-02 18:40:29 +0300
committerJulian Eisel <julian@blender.org>2020-04-02 18:43:45 +0300
commit34465a7fb091664b07611353d99dcaa0862d4a4c (patch)
tree973457851e3836286daf07345b4ea4fd517347e1
parent868d4526a8818fbffc5ea993fbbbd3890046a6e9 (diff)
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.
-rw-r--r--intern/ghost/GHOST_C-api.h26
-rw-r--r--intern/ghost/GHOST_IContext.h5
-rw-r--r--intern/ghost/GHOST_ISystem.h6
-rw-r--r--intern/ghost/GHOST_IXrContext.h2
-rw-r--r--intern/ghost/GHOST_Types.h5
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp34
-rw-r--r--intern/ghost/intern/GHOST_Context.h4
-rw-r--r--intern/ghost/intern/GHOST_IXrGraphicsBinding.h3
-rw-r--r--intern/ghost/intern/GHOST_System.cpp10
-rw-r--r--intern/ghost/intern/GHOST_System.h6
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp17
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h28
-rw-r--r--intern/ghost/intern/GHOST_XrContext.cpp7
-rw-r--r--intern/ghost/intern/GHOST_XrContext.h1
-rw-r--r--intern/ghost/intern/GHOST_XrGraphicsBinding.cpp67
-rw-r--r--intern/ghost/intern/GHOST_XrSession.cpp14
-rw-r--r--intern/ghost/intern/GHOST_XrSession.h1
-rw-r--r--source/blender/windowmanager/WM_api.h4
-rw-r--r--source/blender/windowmanager/intern/wm_window.c21
-rw-r--r--source/blender/windowmanager/intern/wm_xr.c58
20 files changed, 123 insertions, 196 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index aba5b5f733b..4f994f76539 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -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
diff --git a/intern/ghost/GHOST_IContext.h b/intern/ghost/GHOST_IContext.h
index d404287fe56..1225262a908 100644
--- a/intern/ghost/GHOST_IContext.h
+++ b/intern/ghost/GHOST_IContext.h
@@ -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
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 8adf49fe1f9..58d1a08da74 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -267,12 +267,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.
* \return Indication of success.
diff --git a/intern/ghost/GHOST_IXrContext.h b/intern/ghost/GHOST_IXrContext.h
index 362bc923ee8..3076de96690 100644
--- a/intern/ghost/GHOST_IXrContext.h
+++ b/intern/ghost/GHOST_IXrContext.h
@@ -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__
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 637935d9142..6667d113fe8 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -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
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index af2a13945d1..6ee1557122d 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -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
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index 0bd6f63d07e..411a7de5c79 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -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;
}
diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
index 25281d3d0ba..cddb557d163 100644
--- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
+++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h
@@ -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__ */
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 97704435f04..85eb6d58679 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -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);
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 2eec6ca43b3..eaaa2ff6ee6 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -119,12 +119,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.
* \return Indication of validity.
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index e4988d8a0b3..9149d81e32e 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -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)
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 0d9fd268d0f..27f23e00ae7 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -42,6 +42,7 @@ class GHOST_EventWheel;
class GHOST_EventWindow;
class GHOST_EventDragnDrop;
+class GHOST_ContextD3D;
class GHOST_WindowWin32;
/**
@@ -131,18 +132,28 @@ class GHOST_SystemWin32 : public GHOST_System {
GHOST_IContext *createOffscreenContext();
/**
- * Create a new offscreen context.
- * Never explicitly delete the window, use disposeContext() instead.
+ * Dispose of a context.
+ * \param context Pointer to the context to be disposed.
+ * \return Indication of success.
+ */
+ 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).
*/
- GHOST_IContext *createOffscreenContext(GHOST_TDrawingContextType type);
+ static GHOST_ContextD3D *createOffscreenContextD3D();
/**
- * Dispose of a context.
+ * 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.
*/
- GHOST_TSuccess disposeContext(GHOST_IContext *context);
+ static GHOST_TSuccess disposeContextD3D(GHOST_ContextD3D *context);
/***************************************************************************************
** Event management functionality
@@ -256,13 +267,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
* \param ScanCode The ScanCode of pressed key (similar to PS/2 Set 1)
diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp
index a757aa9a555..2cd5b2ca8c8 100644
--- a/intern/ghost/intern/GHOST_XrContext.cpp
+++ b/intern/ghost/intern/GHOST_XrContext.cpp
@@ -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 */
/* -------------------------------------------------------------------- */
diff --git a/intern/ghost/intern/GHOST_XrContext.h b/intern/ghost/intern/GHOST_XrContext.h
index af65f262323..7dbd0a0d011 100644
--- a/intern/ghost/intern/GHOST_XrContext.h
+++ b/intern/ghost/intern/GHOST_XrContext.h
@@ -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);
diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
index ea97b3a50cf..fa4ca2283ea 100644
--- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
+++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cpp
@@ -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;
diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp
index 7be0f300210..1f24f2fb37f 100644
--- a/intern/ghost/intern/GHOST_XrSession.cpp
+++ b/intern/ghost/intern/GHOST_XrSession.cpp
@@ -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;
}
diff --git a/intern/ghost/intern/GHOST_XrSession.h b/intern/ghost/intern/GHOST_XrSession.h
index 9c1ed3756d4..39e1a63ffda 100644
--- a/intern/ghost/intern/GHOST_XrSession.h
+++ b/intern/ghost/intern/GHOST_XrSession.h
@@ -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. */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index a29ee4131cb..8047e5e2112 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -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,
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 505383d295f..c29fd24d4cd 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -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
diff --git a/source/blender/windowmanager/intern/wm_xr.c b/source/blender/windowmanager/intern/wm_xr.c
index 18c3b70ed01..5115607101c 100644
--- a/source/blender/windowmanager/intern/wm_xr.c
+++ b/source/blender/windowmanager/intern/wm_xr.c
@@ -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 */