[Bf-blender-cvs] [1404edbe3a1] soc-2019-openxr: Support DirectX Ghost context creation

Julian Eisel noreply at git.blender.org
Wed Jun 12 11:36:39 CEST 2019


Commit: 1404edbe3a15d2ca41615cfcd735cfa662708421
Author: Julian Eisel
Date:   Wed Jun 12 11:25:32 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB1404edbe3a15d2ca41615cfcd735cfa662708421

Support DirectX Ghost context creation

Adds support for creating a DirectX 11 Ghost context. It's not used yet
and more stuff besides creation is needed. Also, other versions than 11
should probably be supported.
We need a DirectX context to support the Windows Mixed Reality OpenXR
Runtime, a rather important one to support. Idea is to use an extension
for OpenGL-DirectX interoperability for drawing the OpenGL offscreen
viewport render using DirectX.

===================================================================

M	intern/ghost/CMakeLists.txt
M	intern/ghost/GHOST_C-api.h
M	intern/ghost/GHOST_ISystem.h
M	intern/ghost/GHOST_Types.h
M	intern/ghost/intern/GHOST_C-api.cpp
A	intern/ghost/intern/GHOST_ContextD3D.cpp
A	intern/ghost/intern/GHOST_ContextD3D.h
M	intern/ghost/intern/GHOST_SystemWin32.cpp
M	intern/ghost/intern/GHOST_SystemWin32.h

===================================================================

diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index b096fecced8..d7b1a396303 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -270,11 +270,13 @@ elseif(WIN32)
   )
 
   list(APPEND SRC
+    intern/GHOST_ContextD3D.cpp
     intern/GHOST_DisplayManagerWin32.cpp
     intern/GHOST_DropTargetWin32.cpp
     intern/GHOST_SystemWin32.cpp
     intern/GHOST_WindowWin32.cpp
 
+    intern/GHOST_ContextD3D.h
     intern/GHOST_DisplayManagerWin32.h
     intern/GHOST_DropTargetWin32.h
     intern/GHOST_SystemWin32.h
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index ea9d6925e23..18b513fdba6 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -193,6 +193,16 @@ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemha
 extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
                                                  GHOST_ContextHandle contexthandle);
 
+#ifdef WIN32
+/**
+ * Create a new DirectX 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).
+ */
+extern GHOST_ContextHandle GHOST_CreateDirectXContext(GHOST_SystemHandle systemhandle);
+#endif
+
 /**
  * Returns the window user data.
  * \param windowhandle The handle to the window
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index f0ceb7fb8ba..3721955ae6b 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -264,6 +264,20 @@ 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)
+  {
+    switch (type) {
+      case GHOST_kDrawingContextTypeOpenGL:
+        return createOffscreenContext();
+      default:
+        return NULL;
+    }
+  }
+
   /**
    * Dispose of a context.
    * \param   context Pointer to the context to be disposed.
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 68516c3ecf8..40705bf29e2 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -129,7 +129,10 @@ typedef enum { GHOST_kWindowOrderTop = 0, GHOST_kWindowOrderBottom } GHOST_TWind
 
 typedef enum {
   GHOST_kDrawingContextTypeNone = 0,
-  GHOST_kDrawingContextTypeOpenGL
+  GHOST_kDrawingContextTypeOpenGL,
+#if WIN32
+  GHOST_kDrawingContextTypeD3D,
+#endif
 } GHOST_TDrawingContextType;
 
 typedef enum {
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index ef653c114e8..1e9b8161239 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -127,6 +127,15 @@ 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);
+}
+#endif
+
 GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
                                       const char *title,
                                       GHOST_TInt32 left,
diff --git a/intern/ghost/intern/GHOST_ContextD3D.cpp b/intern/ghost/intern/GHOST_ContextD3D.cpp
new file mode 100644
index 00000000000..8a6f3aa7fa8
--- /dev/null
+++ b/intern/ghost/intern/GHOST_ContextD3D.cpp
@@ -0,0 +1,103 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup GHOST
+ */
+
+#include "GHOST_ContextD3D.h"
+
+HMODULE GHOST_ContextD3D::s_d3d_lib = NULL;
+PFN_D3D11_CREATE_DEVICE GHOST_ContextD3D::s_D3D11CreateDeviceFn = NULL;
+
+GHOST_ContextD3D::GHOST_ContextD3D(bool stereoVisual, HWND hWnd, HDC hDC)
+    : GHOST_Context(stereoVisual), m_hWnd(hWnd), m_hDC(hDC)
+{
+}
+
+GHOST_ContextD3D::~GHOST_ContextD3D()
+{
+}
+
+GHOST_TSuccess GHOST_ContextD3D::swapBuffers()
+{
+  return GHOST_kFailure;
+}
+
+GHOST_TSuccess GHOST_ContextD3D::activateDrawingContext()
+{
+  return GHOST_kFailure;
+}
+
+GHOST_TSuccess GHOST_ContextD3D::releaseDrawingContext()
+{
+  return GHOST_kFailure;
+}
+
+GHOST_TSuccess GHOST_ContextD3D::setupD3DLib()
+{
+  if (s_d3d_lib == NULL) {
+    s_d3d_lib = LoadLibraryA("d3d11.dll");
+
+    WIN32_CHK(s_d3d_lib != NULL);
+
+    if (s_d3d_lib == NULL) {
+      fprintf(stderr, "LoadLibrary(\"d3d11.dll\") failed!\n");
+      return GHOST_kFailure;
+    }
+  }
+
+  if (s_D3D11CreateDeviceFn == NULL) {
+    s_D3D11CreateDeviceFn = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(s_d3d_lib,
+                                                                    "D3D11CreateDevice");
+
+    WIN32_CHK(s_D3D11CreateDeviceFn != NULL);
+
+    if (s_D3D11CreateDeviceFn == NULL) {
+      fprintf(stderr, "GetProcAddress(s_d3d_lib, \"D3D11CreateDevice\") failed!\n");
+      return GHOST_kFailure;
+    }
+  }
+
+  return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_ContextD3D::initializeDrawingContext()
+{
+  if (setupD3DLib() == GHOST_kFailure) {
+    return GHOST_kFailure;
+  }
+
+  const D3D_FEATURE_LEVEL feature_level[] = {D3D_FEATURE_LEVEL_11_1};
+  HRESULT hres = s_D3D11CreateDeviceFn(NULL,
+                                       D3D_DRIVER_TYPE_HARDWARE,
+                                       NULL,
+                                       0,
+                                       feature_level,
+                                       std::size(feature_level),
+                                       D3D11_SDK_VERSION,
+                                       &m_d3d_device,
+                                       NULL,
+                                       &m_d3d_device_ctx);
+  WIN32_CHK(hres == S_OK);
+
+  return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_ContextD3D::releaseNativeHandles()
+{
+  return GHOST_kFailure;
+}
diff --git a/intern/ghost/intern/GHOST_ContextD3D.h b/intern/ghost/intern/GHOST_ContextD3D.h
new file mode 100644
index 00000000000..8d7561d6f4e
--- /dev/null
+++ b/intern/ghost/intern/GHOST_ContextD3D.h
@@ -0,0 +1,121 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup GHOST
+ */
+
+#ifndef __GHOST_CONTEXTD3D_H__
+#define __GHOST_CONTEXTD3D_H__
+
+#ifndef WIN32
+#  error WIN32 only!
+#endif  // WIN32
+
+#include <D3D11.h>
+#include <wrl.h>  // Microsoft::WRL::ComPtr
+
+#include "GHOST_Context.h"
+
+class GHOST_ContextD3D : public GHOST_Context {
+ public:
+  GHOST_ContextD3D(bool stereoVisual, HWND hWnd, HDC hDC);
+  ~GHOST_ContextD3D();
+
+  /**
+   * Swaps front and back buffers of a window.
+   * \return  A boolean success indicator.
+   */
+  GHOST_TSuccess swapBuffers();
+
+  /**
+   * Activates the drawing context of this window.
+   * \return  A boolean success indicator.
+   */
+  GHOST_TSuccess activateDrawingContext();
+
+  /**
+   * Release the drawing context of the calling thread.
+   * \return  A boolean success indicator.
+   */
+  GHOST_TSuccess releaseDrawingContext();
+
+  /**
+   * Call immediately after new to initialize.  If this fails then immediately delete the object.
+   * \return Indication as to whether initialization has succeeded.
+   */
+  GHOST_TSuccess initializeDrawingContext();
+
+  /**
+   * Updates the drawing context of this window. Needed
+   * whenever the window is changed.
+   * \return Indication of success.
+   */
+  GHOST_TSuccess updateDrawingContext()
+  {
+    return GHOST_kFailure;
+  }
+
+  /**
+   * Checks if it is OK for a remove the native display
+   * \return Indication as to whether removal has succeeded.
+   */
+  GHOST_TSuccess releaseNativeHandles();
+
+  /**
+   * Sets the swap interval for swapBuffers.
+   * \param interval The swap interval to use.
+   * \return A boolean success indicator.
+   */
+  GHOST_TSuccess setSwapInterval(int /*interval*/)
+  {
+    return GHOST_kFailure;
+  }
+
+  /**
+   * Gets the current swap interval for swapBuffers.
+   * \param intervalOut Variable to store the swap interval if it can be read.
+   * \return Whether the swap interval can be read.
+   */
+  GHOST_TSuccess getSwapInterval(int &)
+  {
+    return GHOST_kFailure;
+  }
+
+  /**
+   * Gets the OpenGL framebuffer associated with the OpenGL context
+   * \return The ID of an OpenGL framebuffer object.
+   */
+  unsigned int getDefaultFramebuffer()
+  {
+    return 0;
+  }
+
+ private:
+  GHOST_TSuccess setupD3DLib();
+
+  // TODO Not used yet.
+  HWND m_hWnd;
+  HDC m_hDC;
+
+  Microsoft::WRL::ComPtr<ID3D11Device> m_d3d_device;
+  Microsoft::WRL::Com

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list