[Bf-blender-cvs] [34fa0f8ac69] soc-2019-openxr: Set up DirectX window to support drawing

Julian Eisel noreply at git.blender.org
Fri Jun 14 19:09:53 CEST 2019


Commit: 34fa0f8ac69afb1770a0561092fc3ae9f6cec793
Author: Julian Eisel
Date:   Fri Jun 14 18:53:26 2019 +0200
Branches: soc-2019-openxr
https://developer.blender.org/rB34fa0f8ac69afb1770a0561092fc3ae9f6cec793

Set up DirectX window to support drawing

With this the VR window should open fine and get cleared in a red-ish
orange using Direct3D 11 calls (well, on Windows that is).

The window still draws a 3D view to an offscreen buffer. Where we
usually just swap the buffers, we now allow calling a GHOST function to
blit the offscreen OpenGL buffer to whatever type of graphics buffer the
window uses (DirectX here).
The nice thing about this approach is that all DirectX code stays in
GHOST_ContextD3D.cpp. And the entire compatibiliy code can go into a
single function higher level modules don't need to care about.

This also fixes a number of issues introduced in earlier commits.

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

M	intern/ghost/GHOST_C-api.h
M	intern/ghost/GHOST_IWindow.h
M	intern/ghost/intern/GHOST_C-api.cpp
M	intern/ghost/intern/GHOST_Context.h
M	intern/ghost/intern/GHOST_ContextD3D.cpp
M	intern/ghost/intern/GHOST_ContextD3D.h
M	intern/ghost/intern/GHOST_SystemWin32.cpp
M	intern/ghost/intern/GHOST_Window.cpp
M	intern/ghost/intern/GHOST_Window.h
M	intern/ghost/intern/GHOST_WindowWin32.cpp
M	source/blender/windowmanager/intern/wm_draw.c
M	source/blender/windowmanager/intern/wm_operators.c
M	source/blender/windowmanager/intern/wm_window.c
M	source/blender/windowmanager/wm_window.h

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

diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 8acfa8ec943..f6fcc60a696 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -193,15 +193,8 @@ 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
+GHOST_TSuccess GHOST_BlitOpenGLOffscreenContext(GHOST_WindowHandle windowhandle,
+                                                GHOST_ContextHandle offscreen_contexthandle);
 
 extern GHOST_ContextHandle GHOST_GetWindowContext(GHOST_WindowHandle windowhandle);
 
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index cf65decf9c6..902af107bdf 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -79,6 +79,8 @@ class GHOST_IWindow {
 
   virtual class GHOST_IContext *getDrawingContext() = 0;
 
+  virtual GHOST_TSuccess blitOpenGLOffscreenContext(GHOST_IContext *offscreen) = 0;
+
   /**
    * Sets the title displayed in the title bar.
    * \param title The title to display in the title bar.
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index a326742bfe8..ebb574288a3 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -127,14 +127,13 @@ GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
   return system->disposeContext(context);
 }
 
-#ifdef WIN32
-GHOST_ContextHandle GHOST_CreateDirectXContext(GHOST_SystemHandle systemhandle)
+GHOST_TSuccess GHOST_BlitOpenGLOffscreenContext(GHOST_WindowHandle windowhandle,
+                                                GHOST_ContextHandle offscreen_contexthandle)
 {
-  GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
+  GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
 
-  return (GHOST_ContextHandle)system->createOffscreenContext(GHOST_kDrawingContextTypeD3D);
+  return window->blitOpenGLOffscreenContext((GHOST_IContext *)offscreen_contexthandle);
 }
-#endif
 
 GHOST_ContextHandle GHOST_GetWindowContext(GHOST_WindowHandle windowhandle)
 {
diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h
index bbf6d6a510d..8858c6cb0b3 100644
--- a/intern/ghost/intern/GHOST_Context.h
+++ b/intern/ghost/intern/GHOST_Context.h
@@ -128,6 +128,12 @@ class GHOST_Context : public GHOST_IContext {
     return 0;
   }
 
+  virtual GHOST_TSuccess blitOpenGLOffscreenContext(GHOST_Context *offscreen)
+  {
+    /* Not implemented. Could just implement as activateDrawingContext(offscreen)? */
+    return GHOST_kFailure;
+  }
+
  protected:
   void initContextGLEW();
 
diff --git a/intern/ghost/intern/GHOST_ContextD3D.cpp b/intern/ghost/intern/GHOST_ContextD3D.cpp
index 8a6f3aa7fa8..7b5e73088d0 100644
--- a/intern/ghost/intern/GHOST_ContextD3D.cpp
+++ b/intern/ghost/intern/GHOST_ContextD3D.cpp
@@ -21,10 +21,10 @@
 #include "GHOST_ContextD3D.h"
 
 HMODULE GHOST_ContextD3D::s_d3d_lib = NULL;
-PFN_D3D11_CREATE_DEVICE GHOST_ContextD3D::s_D3D11CreateDeviceFn = NULL;
+PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN GHOST_ContextD3D::s_D3D11CreateDeviceAndSwapChainFn = NULL;
 
-GHOST_ContextD3D::GHOST_ContextD3D(bool stereoVisual, HWND hWnd, HDC hDC)
-    : GHOST_Context(stereoVisual), m_hWnd(hWnd), m_hDC(hDC)
+GHOST_ContextD3D::GHOST_ContextD3D(bool stereoVisual, HWND hWnd)
+    : GHOST_Context(stereoVisual), m_hWnd(hWnd)
 {
 }
 
@@ -34,7 +34,8 @@ GHOST_ContextD3D::~GHOST_ContextD3D()
 
 GHOST_TSuccess GHOST_ContextD3D::swapBuffers()
 {
-  return GHOST_kFailure;
+  HRESULT res = m_swapchain->Present(0, 0);
+  return (res == S_OK) ? GHOST_kSuccess : GHOST_kFailure;
 }
 
 GHOST_TSuccess GHOST_ContextD3D::activateDrawingContext()
@@ -60,14 +61,14 @@ GHOST_TSuccess GHOST_ContextD3D::setupD3DLib()
     }
   }
 
-  if (s_D3D11CreateDeviceFn == NULL) {
-    s_D3D11CreateDeviceFn = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(s_d3d_lib,
-                                                                    "D3D11CreateDevice");
+  if (s_D3D11CreateDeviceAndSwapChainFn == NULL) {
+    s_D3D11CreateDeviceAndSwapChainFn = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(
+        s_d3d_lib, "D3D11CreateDeviceAndSwapChain");
 
-    WIN32_CHK(s_D3D11CreateDeviceFn != NULL);
+    WIN32_CHK(s_D3D11CreateDeviceAndSwapChainFn != NULL);
 
-    if (s_D3D11CreateDeviceFn == NULL) {
-      fprintf(stderr, "GetProcAddress(s_d3d_lib, \"D3D11CreateDevice\") failed!\n");
+    if (s_D3D11CreateDeviceAndSwapChainFn == NULL) {
+      fprintf(stderr, "GetProcAddress(s_d3d_lib, \"D3D11CreateDeviceAndSwapChain\") failed!\n");
       return GHOST_kFailure;
     }
   }
@@ -81,19 +82,34 @@ GHOST_TSuccess GHOST_ContextD3D::initializeDrawingContext()
     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);
+  DXGI_SWAP_CHAIN_DESC sd{};
+
+  sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+  sd.SampleDesc.Count = 1;
+  sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+  sd.BufferCount = 1;
+  sd.OutputWindow = m_hWnd;
+  sd.Windowed = TRUE;
+  sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+
+  HRESULT hres = s_D3D11CreateDeviceAndSwapChainFn(NULL,
+                                                   D3D_DRIVER_TYPE_HARDWARE,
+                                                   NULL,
+                                                   0,
+                                                   NULL,
+                                                   0,
+                                                   D3D11_SDK_VERSION,
+                                                   &sd,
+                                                   &m_swapchain,
+                                                   &m_device,
+                                                   NULL,
+                                                   &m_device_ctx);
   WIN32_CHK(hres == S_OK);
 
+  Microsoft::WRL::ComPtr<ID3D11Resource> back_buffer = nullptr;
+  m_swapchain->GetBuffer(0, __uuidof(ID3D11Resource), &back_buffer);
+  m_device->CreateRenderTargetView(back_buffer.Get(), nullptr, &m_backbuffer_view);
+
   return GHOST_kSuccess;
 }
 
@@ -101,3 +117,13 @@ GHOST_TSuccess GHOST_ContextD3D::releaseNativeHandles()
 {
   return GHOST_kFailure;
 }
+
+GHOST_TSuccess GHOST_ContextD3D::blitOpenGLOffscreenContext(GHOST_Context *offscreen_ctx)
+{
+  /* Just testing. OpenGL compatibility code goes here (using NV_DX_interop extensions) */
+
+  const float col[] = {0.9f, 0.3f, 0.0f, 1.0f};
+  m_device_ctx->ClearRenderTargetView(m_backbuffer_view.Get(), col);
+
+  return GHOST_kSuccess;
+}
diff --git a/intern/ghost/intern/GHOST_ContextD3D.h b/intern/ghost/intern/GHOST_ContextD3D.h
index 8d7561d6f4e..4e4317c4f9a 100644
--- a/intern/ghost/intern/GHOST_ContextD3D.h
+++ b/intern/ghost/intern/GHOST_ContextD3D.h
@@ -32,7 +32,7 @@
 
 class GHOST_ContextD3D : public GHOST_Context {
  public:
-  GHOST_ContextD3D(bool stereoVisual, HWND hWnd, HDC hDC);
+  GHOST_ContextD3D(bool stereoVisual, HWND hWnd);
   ~GHOST_ContextD3D();
 
   /**
@@ -104,18 +104,20 @@ class GHOST_ContextD3D : public GHOST_Context {
     return 0;
   }
 
+  GHOST_TSuccess blitOpenGLOffscreenContext(GHOST_Context *offscreen_ctx);
+
  private:
   GHOST_TSuccess setupD3DLib();
 
-  // TODO Not used yet.
   HWND m_hWnd;
-  HDC m_hDC;
 
-  Microsoft::WRL::ComPtr<ID3D11Device> m_d3d_device;
-  Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_d3d_device_ctx;
+  Microsoft::WRL::ComPtr<ID3D11Device> m_device;
+  Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_device_ctx;
+  Microsoft::WRL::ComPtr<IDXGISwapChain> m_swapchain;
+  Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_backbuffer_view;
 
   static HMODULE s_d3d_lib;
-  static PFN_D3D11_CREATE_DEVICE s_D3D11CreateDeviceFn;
+  static PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN s_D3D11CreateDeviceAndSwapChainFn;
 };
 
 #endif /* __GHOST_CONTEXTD3D_H__ */
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index a677004fe75..fc3946dd5e7 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -428,9 +428,13 @@ GHOST_IContext *GHOST_SystemWin32::createOffscreenContextD3D()
                            GetModuleHandle(NULL),
                            NULL);
 
-  HDC mHDC = GetDC(wnd);
-
-  context = new GHOST_ContextD3D(false, wnd, mHDC);
+  context = new GHOST_ContextD3D(false, wnd);
+  if (context->initializeDrawingContext()) {
+    return context;
+  }
+  else {
+    delete context;
+  }
 
   return context;
 }
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index 76f2d2347db..9b1dbe8414c 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -114,6 +114,11 @@ unsigned int GHOST_Window::getDefaultFramebuffer()
   return (m_context) ? m_context->getDefaultFramebuffer() : 0;
 }
 
+GHOST_TSuccess GHOST_Window::blitOpenGLOffscreenContext(GHOST_IContext *offscreen_ctx)
+{
+  return m_context->blitOpenGLOffscreenContext((GHOST_Context *)offscreen_ctx);
+}
+
 GHOST_TSuccess GHOST_Window::activateDrawingContext()
 {
   return m_context->activateDrawingContext();
diff --git a/intern/ghost/intern/GHOST_Window.h b

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list