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:
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
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue