HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_OGLInteropTextureBase.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RV_OGLInteropTextureBase.h ( RV Library, C++)
7  *
8  * COMMENTS:
9  * Texture usable in Vulkan and OpenGL
10  */
11 
12 
13 #ifndef RV_OGLInteropTextureBase_h
14 #define RV_OGLInteropTextureBase_h
15 
16 #include "RV_API.h"
17 #include "RV_TypePtrs.h"
18 #include "RV_VKImage.h"
19 
20 #include <RE/RE_Texture.h>
21 #include <VE/VE_VK.h>
22 
23 #include <UT/UT_UniquePtr.h>
24 
25 #include <atomic>
26 #include <glcorearb.h>
27 
28 #ifdef WIN32
29  #include <windows.h>
30  typedef HANDLE handle;
31 #elif defined(LINUX)
32 // export handles
33 // NOTE: vulkan + GL function signatures use `int`,
34 // in `xx_external_fd` functions, rather than
35 // sized type .. using `int` to match
36  typedef int handle;
37 #elif defined(MBSD)
38 
39  #include <CoreVideo/CoreVideo.h>
40  #include <CoreVideo/CVPixelFormatDescription.h>
41  typedef IOSurfaceRef handle;
42 #endif
43 
44 class RE_RenderContext;
45 class RE_Render;
46 
47 class RV_VKCommandBuffer;
48 class RV_VKQueue;
50 class RV_Instance;
51 class RV_Render;
52 
54 class VE_Memory;
55 
56 // RV_VKInteropImageCreateInfo
57 // Create info for a VkImage which can be exported.
59 {
60 public:
61  bool fillCreateInfo() override;
62 
64  {
66  }
67 
68  RV_VKInteropImageCreateInfo() = default;
70  {
72  new RV_VKInteropImageCreateInfo(*this));
73  }
75 
76 protected:
79 };
80 
81 // RV_OGLInteropTextureBase
82 /// Set of resources needed to share a texture between
83 /// OpenGL and Vulkan. Can create a vulkan image,
84 /// or recieve an alloacted memory. Creates semaphores
85 /// for sync, and exports the handles for the memory and
86 /// semaphores then imports them into an openGL context.
88 {
89 public:
90  struct SemaphoreSet
91  {
92  VkSemaphore vkHandle;
93  handle shareHandle;
95  };
96 
98  {
101  } myCurOwner;
102 
104  virtual ~RV_OGLInteropTextureBase();
105 
106  // Returns a new texture with no attributes of the given type.
107  static RV_OGLInteropTexturePtr create(RE_TextureDimension dim);
108 
109  // Default usage state is GL. Change to Vulkan if rendering or uploading via
110  // VK to the texture first.
112  { myCurOwner = owner; }
113 
115  {
116  UT_ASSERT(myCurOwner == RV_VULKAN);
117  return myRvImg.get();
118  }
119  const RV_VKImage* getRvImage() const
120  {
121  return myRvImg.get();
122  }
123  // Use this method to fetch the image to bind to an FBO.
125  {
126  return myRvImg.get();
127  }
128  virtual RE_Texture* getRe() = 0;
129 
130  RV_OGLInteropOwner getCurrentRenderType() const { return myCurOwner; }
131 
132  bool isValidAlloc() const { return myRvImg && myOglID; }
133 
135  {
136  return SemaphoreSet{
137  myVkSemGLToVk, /* vkHandle*/
138  myShareSemGLToVk, /* shareHandle */
139  myOglSemGLToVk, /* oglHandle */
140  };
141  }
142 
144  {
145  return SemaphoreSet{
146  myVkSemVkToGL, /* vkHandle*/
147  myShareSemVkToGL, /* shareHandle */
148  myOglSemVkToGL, /* oglHandle */
149  };
150  }
151 
152  bool beginTransferToVk(RE_Render *r);
153  bool finishTransferToVk(RV_Render *r);
154 
155  bool beginTransferToGL(RV_Render *r);
156  bool finishTransferToGL(RE_Render *r);
157 
158 
159  bool submitTransferToGL(RE_RenderContext r);
160 
161  bool submitTransferToVk(RE_RenderContext r);
162 
163  bool allocateImage(RV_Instance* inst,
164  RV_ImageDim image_type, VkFormat format,
165  size_t width, size_t height, size_t depth=1,
166  int levels =1, int layers =1, int samples=1);
167 
168  bool checkImageParams(RV_Instance* inst,
169  RV_ImageDim image_type, VkFormat format,
170  size_t width, size_t height, size_t depth=1,
171  int levels =1, int layers =1, int samples=1);
172 
173 
174 #ifdef MBSD
175  static IOSurfaceRef exportIoSurfaceHandle(RV_Instance* inst, VkImage vk_img);
176  static MTLTexture_id exportMTLTextureId(RV_Instance* inst, VkImage vk_img);
177 #endif
178 
179 protected:
180  bool allocateResources(RV_Instance* inst, RE_Render *re, void *opt_mem_ptr,
181  RV_ImageDim image_type, VkFormat format,
182  size_t width, size_t height, size_t depth=1,
183  int levels =1, int layers =1, int samples=1);
184 
185  // Checks whether the image will created with this create
186  // info will be exportable
187  static bool queryMemoryHandleValid(
188  RV_Instance *inst,
190 
191  // Assigns memory backing image -- called from allocateImage
192  // if image was allocated internally
193  // Doesn't take ownership if given external memory
194  // external memory should be destroyed AFTER this object
195  bool assignMemory(RV_Instance *inst, VE_Memory* mem);
196 
197  void deleteImage(RV_Instance* inst);
198 
199  // Vulkan Image -- may be NULL,
200  // if initialized with externally allocated memory
203 
204  VkDeviceMemory myVkMem = VK_NULL_HANDLE;
205  VkDeviceSize myMemSize = 0;
206  VkDeviceSize myMemOffset = 0;
207  VkImage myVkImg = VK_NULL_HANDLE;
208 
210  VkAccessFlags myLastAccess = 0;
211  VkPipelineStageFlags myLastStage = 0;
212 
213  // transfer must be committed by submitting the command buffer
214  // before work on the GL side can be done
215  // -- tacked atomically since they may be accessed form
216  // Vulkan or GL flag
217  std::atomic_bool myIsTransferToGLWaiting = false;
218 
219 #if 0 // TODO: allow multiple GL->VK sems to be signaled with a single signal+flush op
220  // Note: not locking access to this member,
221  // it will always be accessed from the
222  // GL thread
223  std::atomic_bool myIsTransferToVkWaiting = false;
224  static void commitAllTransfersToVk(RE_Render* r);
225  static std::list<std::atomic_bool*> theWaitingVkTransfers;
226 #endif
227 
228  // semaphores from Vulkan perspective
229  VkSemaphore myVkSemVkToGL = VK_NULL_HANDLE;
230  VkSemaphore myVkSemGLToVk = VK_NULL_HANDLE;
231 
232  bool allocateSemaphores(RV_Instance* inst);
233  void deleteSemaphores(RV_Instance* inst);
234 
235  int myRERenderID = -1;
236 
237  // semaphores from OS perspective
238  handle myShareSemVkToGL = 0;
239  handle myShareSemGLToVk = 0;
240 
241  // semaphores from OpenGL perspective
242  GLuint myOglSemVkToGL = 0;
243  GLuint myOglSemGLToVk = 0;
244 
245  handle myShareMem = 0;
246 
247  // Memory from GL perspective
248  GLuint myOglMem = 0;
249  GLuint myOglID = 0;
250 
251  // buffer used to transfer data if interop isn't supported
252  // TODO: would be better to have a mappable RV_VKImage allocated
253  // to avoid the staging buffer allocations
255 
256  bool importMemory(RE_Render *r);
257  bool importOglSemaphores(RE_Render *r);
258  void deleteMemory(RE_Render *r);
259  void deleteOglSemaphores(RE_Render *r);
260 
261  void deleteMemoryHandle();
262  void deleteSemaphoreHandles();
263 };
264 
265 /// Transfer a list of interop textures from VK to GL usage
267  RE_RenderContext rc,
268  const UT_Array<RV_OGLInteropTextureBase*> &tex_list);
269 
270 /// Transfer a list of interop textures from GL to VK usage
272  RE_RenderContext rc,
273  const UT_Array<RV_OGLInteropTextureBase*> &tex_list);
274 
275 #endif
#define VK_NULL_HANDLE
Definition: vulkan_core.h:45
unsigned int GLuint
Definition: cl.hpp:167
VkFlags VkPipelineStageFlags
Definition: vulkan_core.h:2401
RE_TextureDimension
Temporary container for either a RV_Render and an RE_Render.
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
struct __IOSurface * IOSurfaceRef
Definition: vulkan_metal.h:79
virtual bool fillCreateInfo()
UT_UniquePtr< RV_VKImageCreateInfo > clone() const override
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
#define RV_API
Definition: RV_API.h:10
RV_API void RVtransferToVK(RE_RenderContext rc, const UT_Array< RV_OGLInteropTextureBase * > &tex_list)
Transfer a list of interop textures from GL to VK usage.
RV_MemType getAllocType(RV_Instance *inst) override
Setup allocation info for memory.
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:48
GLsizei levels
Definition: glcorearb.h:2224
GLsizei samples
Definition: glcorearb.h:1298
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glcorearb.h:476
UT_UniquePtr< RV_VKImage > myRvImg
UT_UniquePtr< RV_OGLInteropTextureBase > RV_OGLInteropTexturePtr
VkFlags VkAccessFlags
Definition: vulkan_core.h:2155
VkImageLayout
Definition: vulkan_core.h:1250
void setCurrentState(RV_OGLInteropOwner owner)
RV_API void RVtransferToGL(RE_RenderContext rc, const UT_Array< RV_OGLInteropTextureBase * > &tex_list)
Transfer a list of interop textures from VK to GL usage.
RV_VKImageCreateInfo & operator=(const RV_VKImageCreateInfo &)=delete
VkFormat
Definition: vulkan_core.h:1386
GLint GLsizei width
Definition: glcorearb.h:103
uint64_t VkDeviceSize
Definition: vulkan_core.h:95
RV_MemType
Definition: RV_Type.h:111
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
GLboolean r
Definition: glcorearb.h:1222
RV_ImageDim
Definition: RV_Type.h:120
RV_OGLInteropOwner getCurrentRenderType() const
void * MTLTexture_id
Definition: vulkan_metal.h:76
const RV_VKImage * getRvImage() const