SpoutGLDXinterop.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. spoutGLDXinterop.h
  3. Functions to manage texture sharing using the NVIDIA GL/DX opengl extensions
  4. https://www.opengl.org/registry/specs/NV/DX_interop.txt
  5. Copyright (c) 2014-2017, Lynn Jarvis. All rights reserved.
  6. Redistribution and use in source and binary forms, with or without modification,
  7. are permitted provided that the following conditions are met:
  8. 1. Redistributions of source code must retain the above copyright notice,
  9. this list of conditions and the following disclaimer.
  10. 2. Redistributions in binary form must reproduce the above copyright notice,
  11. this list of conditions and the following disclaimer in the documentation
  12. and/or other materials provided with the distribution.
  13. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  14. EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  15. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  17. INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  18. PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  19. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  20. LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  21. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22. */
  23. #pragma once
  24. #ifndef __spoutGLDXinterop__ // standard way as well
  25. #define __spoutGLDXinterop__
  26. #include "SpoutCommon.h"
  27. #include "spoutDirectX.h"
  28. #include "spoutSenderNames.h"
  29. #include "SpoutMemoryShare.h"
  30. #include "spoutCopy.h"
  31. #include <windowsx.h>
  32. #include <d3d9.h> // DX9
  33. #include <d3d11.h> // DX11
  34. #include <gl/gl.h>
  35. #include <gl/glu.h> // For glerror
  36. #include <shlwapi.h> // for path functions
  37. #include "spoutGLextensions.h" // include last due to redefinition problems with OpenCL
  38. class SPOUT_DLLEXP spoutGLDXinterop {
  39. public:
  40. spoutGLDXinterop();
  41. ~spoutGLDXinterop();
  42. // Spout objects
  43. spoutSenderNames senders; // Sender management
  44. spoutDirectX spoutdx; // DirectX functions
  45. spoutCopy spoutcopy; // Memory copy and rgb-rgba conversion functions
  46. spoutMemoryShare memoryshare; // Memory sharing
  47. // Initialization functions
  48. bool LoadGLextensions(); // Load required opengl extensions
  49. bool CreateInterop(HWND hWnd, const char* sendername, unsigned int width, unsigned int height, DWORD dwFormat, bool bReceive = true);
  50. void CleanupInterop(bool bExit = false); // Cleanup with flag to avoid unknown crash bug
  51. bool getSharedInfo(char* sharedMemoryName, SharedTextureInfo* info);
  52. bool setSharedInfo(char* sharedMemoryName, SharedTextureInfo* info);
  53. // Texture functions
  54. bool WriteTexture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO=0);
  55. bool ReadTexture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0);
  56. bool WriteTexturePixels(const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO = 0);
  57. bool ReadTexturePixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO=0);
  58. bool DrawSharedTexture (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = true, GLuint HostFBO = 0);
  59. bool DrawToSharedTexture (GLuint TexID, GLuint TexTarget, unsigned int width, unsigned int height, float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO = 0);
  60. bool BindSharedTexture();
  61. bool UnBindSharedTexture();
  62. // DX11 shared texture write and read
  63. bool WriteTexture(ID3D11Texture2D** texture);
  64. bool ReadTexture (ID3D11Texture2D** texture);
  65. // PBO functions for external access
  66. bool UnloadTexturePixels(GLuint TextureID, GLuint TextureTarget,
  67. unsigned int width, unsigned int height,
  68. unsigned char *data, GLenum glFormat = GL_RGBA,
  69. bool bInvert = false, GLuint HostFBO = 0);
  70. bool LoadTexturePixels(GLuint TextureID, GLuint TextureTarget,
  71. unsigned int width, unsigned int height,
  72. const unsigned char *data, GLenum glFormat = GL_RGBA,
  73. bool bInvert = false);
  74. // DX9
  75. bool m_bUseDX9; // Use DX11 (default) or DX9
  76. bool GetDX9();
  77. bool SetDX9(bool bDX9);
  78. bool UseDX9(bool bDX9); // Includes DX11 compatibility check
  79. bool isDX9(); // Test for DX11 in case it failed to initialize
  80. bool m_bUseCPU; // Use CPU texture processing
  81. bool SetCPUmode(bool bCPU = true);
  82. bool GetCPUmode();
  83. bool m_bUseMemory; // Use memoryshare
  84. bool SetMemoryShareMode(bool bMem = true);
  85. bool GetMemoryShareMode();
  86. int GetShareMode(); // 0 - memory, 1 - cpu, 2 - texture
  87. bool SetShareMode(int mode);
  88. bool IsBGRAavailable(); // are the bgra extensions available
  89. bool IsPBOavailable(); // Are pbo extensions supported
  90. void SetBufferMode(bool bActive); // Set the pbo availability on or off
  91. bool GetBufferMode();
  92. int GetNumAdapters(); // Get the number of graphics adapters in the system
  93. bool GetAdapterName(int index, char *adaptername, int maxchars); // Get an adapter name
  94. bool SetAdapter(int index); // Set required graphics adapter for output
  95. int GetAdapter(); // Get the SpoutDirectX global adapter index
  96. bool GetHostPath(const char *sendername, char *hostpath, int maxchars); // The path of the host that produced the sender
  97. // DX9
  98. D3DFORMAT DX9format; // the DX9 texture format to be used
  99. void SetDX9format(D3DFORMAT textureformat);
  100. bool CreateDX9interop(unsigned int width, unsigned int height, DWORD dwFormat, bool bReceive = true);
  101. bool OpenDirectX9(HWND hWnd); // Initialize and prepare DirectX9
  102. void CleanupDX9(bool bExit = false);
  103. // DX11
  104. DXGI_FORMAT DX11format; // the DX11 texture format to be used
  105. void SetDX11format(DXGI_FORMAT textureformat); // set format by user
  106. bool CreateDX11interop(unsigned int width, unsigned int height, DWORD dwFormat, bool bReceive);
  107. bool OpenDirectX11(); // Initialize and prepare DirectX11
  108. bool DX11available(); // Test for DX11 by attempting to open a device
  109. void CleanupDX11(bool bExit = false);
  110. // Common
  111. bool OpenDirectX(HWND hWnd, bool bDX9);
  112. void CleanupDirectX(bool bExit = false);
  113. HANDLE LinkGLDXtextures(void* pDXdevice, void* pSharedTexture, HANDLE dxShareHandle, GLuint glTextureID);
  114. // Locks for gl/dx interop functions
  115. HRESULT LockInteropObject(HANDLE hDevice, HANDLE *hObject);
  116. HRESULT UnlockInteropObject(HANDLE hDevice, HANDLE *hObject);
  117. // Utilities
  118. bool GLDXcompatible();
  119. bool isOptimus();
  120. int GetVerticalSync();
  121. bool SetVerticalSync(bool bSync = true);
  122. bool GetAdapterInfo(char *renderadapter,
  123. char *renderdescription, char *renderversion,
  124. char *displaydescription, char *displayversion,
  125. int maxsize, bool &bUseDX9);
  126. DWORD GetSpoutVersion(); // Get Spout version from the registry - starting at 2.005
  127. // OpenGL utilities
  128. bool InitOpenGL();
  129. bool CloseOpenGL();
  130. bool CopyTexture(GLuint SourceID, GLuint SourceTarget, GLuint DestID, GLuint DestTarget,
  131. unsigned int width, unsigned int height, bool bInvert, GLuint HostFBO);
  132. void InitTexture(GLuint &texID, GLenum GLformat, unsigned int width, unsigned int height);
  133. void CheckOpenGLTexture(GLuint &texID, GLenum GLformat,
  134. unsigned int newWidth, unsigned int newHeight,
  135. unsigned int &texWidth, unsigned int &texHeight);
  136. void SaveOpenGLstate(unsigned int width, unsigned int height, bool bFitWindow = true);
  137. void RestoreOpenGLstate();
  138. GLuint GetGLtextureID(); // Get OpenGL shared texture ID
  139. void GLerror();
  140. void PrintFBOstatus(GLenum status);
  141. GLuint m_glTexture; // the OpenGL texture linked to the shared DX texture
  142. GLuint m_fbo; // General fbo used for texture transfers
  143. // public for external access
  144. IDirect3DDevice9Ex* m_pDevice; // DX9 device
  145. LPDIRECT3DTEXTURE9 m_dxTexture; // the shared DX9 texture
  146. HANDLE m_dxShareHandle; // the shared DX texture handle
  147. ID3D11Device* g_pd3dDevice; // DX11 device
  148. ID3D11Texture2D* g_pSharedTexture; // The shared DX11 texture
  149. protected:
  150. bool m_bInitialized; // this instance initialized flag
  151. bool m_bExtensionsLoaded; // extensions have been loaded
  152. unsigned int m_caps; // extension capabilities
  153. bool m_bFBOavailable; // fbo extensions available
  154. bool m_bBLITavailable; // fbo blit extensions available
  155. bool m_bPBOavailable; // pbo extensions available
  156. bool m_bSWAPavailable; // swap extensions available
  157. bool m_bBGRAavailable; // BGRA extensions are supported
  158. bool m_bGLDXavailable; // GL/DX interop extensions are supported
  159. HWND m_hWnd; // parent window
  160. HANDLE m_hSharedMemory; // handle to the texture info shared memory
  161. SharedTextureInfo m_TextureInfo; // local texture info structure
  162. GLuint m_TexID; // Local texture used for memoryshare and CPU functions
  163. unsigned int m_TexWidth; // width and height of local texture
  164. unsigned int m_TexHeight; // height of local texture
  165. // PBO support
  166. GLuint m_pbo[2];
  167. int PboIndex;
  168. int NextPboIndex;
  169. // For InitOpenGL and CloseOpenGL
  170. HDC m_hdc;
  171. HWND m_hwndButton;
  172. HGLRC m_hRc;
  173. // DX11
  174. ID3D11DeviceContext* g_pImmediateContext;
  175. D3D_DRIVER_TYPE g_driverType;
  176. D3D_FEATURE_LEVEL g_featureLevel;
  177. ID3D11Texture2D* g_pStagingTexture; // A staging texture for CPU access
  178. // DX9
  179. IDirect3D9Ex* m_pD3D; // DX9 object
  180. LPDIRECT3DSURFACE9 g_DX9surface; // A surface for CPU access
  181. // Interop
  182. HANDLE m_hInteropDevice; // handle to the DX/GL interop device
  183. HANDLE m_hInteropObject; // handle to the DX/GL interop object (the shared texture)
  184. HANDLE m_hAccessMutex; // Texture access mutex lock handle
  185. bool getSharedTextureInfo(const char* sharedMemoryName);
  186. bool setSharedTextureInfo(const char* sharedMemoryName);
  187. // GL/DX interop texture functions
  188. bool WriteGLDXtexture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=true, GLuint HostFBO=0);
  189. bool ReadGLDXtexture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0);
  190. bool WriteGLDXpixels (const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO = 0);
  191. bool ReadGLDXpixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false, GLuint HostFBO=0);
  192. bool DrawGLDXtexture (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = true);
  193. bool DrawToGLDXtexture(GLuint TexID, GLuint TexTarget, unsigned int width, unsigned int height, float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO = 0);
  194. // DX11 staging texture functions for CPU access
  195. bool WriteDX11texture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0);
  196. bool ReadDX11texture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0);
  197. bool WriteDX11pixels (const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false);
  198. bool ReadDX11pixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false);
  199. bool DrawDX11texture (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO=0);
  200. bool DrawToDX11texture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO = 0);
  201. bool CheckStagingTexture(unsigned int width, unsigned int height);
  202. void FlushWait();
  203. // DX9 surface functions for CPU access
  204. bool WriteDX9surface (LPDIRECT3DSURFACE9 source_surface);
  205. bool WriteDX9texture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0);
  206. bool ReadDX9texture (GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert=false, GLuint HostFBO=0);
  207. bool WriteDX9pixels (const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false);
  208. bool ReadDX9pixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert=false);
  209. bool DrawDX9texture (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO = 0);
  210. bool DrawToDX9texture(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO = 0);
  211. bool CheckDX9surface (unsigned int width, unsigned int height);
  212. // Memoryshare functions
  213. bool WriteMemory (GLuint TexID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert = false, GLuint HostFBO=0);
  214. bool ReadMemory (GLuint TexID, GLuint TextureTarget, unsigned int width, unsigned int height, bool bInvert = false, GLuint HostFBO=0);
  215. bool WriteMemoryPixels (const unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false);
  216. bool ReadMemoryPixels (unsigned char *pixels, unsigned int width, unsigned int height, GLenum glFormat = GL_RGBA, bool bInvert = false);
  217. bool DrawSharedMemory (float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false);
  218. bool DrawToSharedMemory(GLuint TextureID, GLuint TextureTarget, unsigned int width, unsigned int height, float max_x = 1.0, float max_y = 1.0, float aspect = 1.0, bool bInvert = false, GLuint HostFBO = 0);
  219. // Utility
  220. bool OpenDeviceKey(const char* key, int maxsize, char *description, char *version);
  221. void trim(char * s);
  222. };
  223. #endif