UnityRendering.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. #pragma once
  2. #include <stdint.h>
  3. #ifdef __OBJC__
  4. @class CAEAGLLayer;
  5. @class EAGLContext;
  6. #else
  7. typedef struct objc_object CAEAGLLayer;
  8. typedef struct objc_object EAGLContext;
  9. #endif
  10. #ifdef __OBJC__
  11. @class CAMetalLayer;
  12. @protocol CAMetalDrawable;
  13. @protocol MTLDrawable;
  14. @protocol MTLDevice;
  15. @protocol MTLTexture;
  16. @protocol MTLCommandBuffer;
  17. @protocol MTLCommandQueue;
  18. @protocol MTLCommandEncoder;
  19. typedef id<CAMetalDrawable> CAMetalDrawableRef;
  20. typedef id<MTLDevice> MTLDeviceRef;
  21. typedef id<MTLTexture> MTLTextureRef;
  22. typedef id<MTLCommandBuffer> MTLCommandBufferRef;
  23. typedef id<MTLCommandQueue> MTLCommandQueueRef;
  24. typedef id<MTLCommandEncoder> MTLCommandEncoderRef;
  25. #else
  26. typedef struct objc_object CAMetalLayer;
  27. typedef struct objc_object* CAMetalDrawableRef;
  28. typedef struct objc_object* MTLDeviceRef;
  29. typedef struct objc_object* MTLTextureRef;
  30. typedef struct objc_object* MTLCommandBufferRef;
  31. typedef struct objc_object* MTLCommandQueueRef;
  32. typedef struct objc_object* MTLCommandEncoderRef;
  33. #endif
  34. // unity internal native render buffer struct (the one you acquire in C# with RenderBuffer.GetNativeRenderBufferPtr())
  35. struct RenderSurfaceBase;
  36. typedef struct RenderSurfaceBase* UnityRenderBufferHandle;
  37. // be aware that this struct is shared with unity implementation so you should absolutely not change it
  38. typedef struct UnityRenderBufferDesc
  39. {
  40. unsigned width, height, depth;
  41. unsigned samples;
  42. int backbuffer;
  43. } UnityRenderBufferDesc;
  44. // trick to make structure inheritance work transparently between c/cpp
  45. // for c we use "anonymous struct"
  46. #ifdef __cplusplus
  47. #define START_STRUCT(T, Base) struct T : Base {
  48. #define END_STRUCT(T) };
  49. #else
  50. #define START_STRUCT(T, Base) typedef struct T { struct Base;
  51. #define END_STRUCT(T) } T;
  52. #endif
  53. // we will keep objc objects in struct, so we need to explicitely mark references as strong to not confuse ARC
  54. // please note that actual object lifetime is managed in objc++ code, so __unsafe_unretained is good enough for objc code
  55. // DO NOT assign objects to UnityDisplaySurface* members in objc code.
  56. // DO NOT store objects from UnityDisplaySurface* members in objc code, as this wont be caught by ARC
  57. #ifdef __OBJC__
  58. #ifdef __cplusplus
  59. #define OBJC_OBJECT_PTR __strong
  60. #else
  61. #define OBJC_OBJECT_PTR __unsafe_unretained
  62. #endif
  63. #else
  64. #define OBJC_OBJECT_PTR
  65. #endif
  66. // unity common rendering (display) surface
  67. typedef struct UnityDisplaySurfaceBase
  68. {
  69. UnityRenderBufferHandle unityColorBuffer;
  70. UnityRenderBufferHandle unityDepthBuffer;
  71. UnityRenderBufferHandle systemColorBuffer;
  72. UnityRenderBufferHandle systemDepthBuffer;
  73. void* cvTextureCache; // CVMetalTextureCacheRef
  74. void* cvTextureCacheTexture; // CVMetalTextureRef
  75. void* cvPixelBuffer; // CVPixelBufferRef
  76. unsigned targetW, targetH;
  77. unsigned systemW, systemH;
  78. int msaaSamples;
  79. int useCVTextureCache; // [bool]
  80. int srgb; // [bool]
  81. int wideColor; // [bool]
  82. int hdr; // [bool]
  83. int disableDepthAndStencil; // [bool]
  84. int allowScreenshot; // [bool] currently we allow screenshots (from script) only on main display
  85. int memorylessDepth; // [bool]
  86. int api; // [UnityRenderingAPI]
  87. } UnityDisplaySurfaceBase;
  88. // START_STRUCT confuse clang c compiler (though it is idiomatic c code that works)
  89. #pragma clang diagnostic push
  90. #pragma clang diagnostic ignored "-Wmissing-declarations"
  91. #define kUnityNumOffscreenSurfaces 2
  92. // Metal display surface
  93. START_STRUCT(UnityDisplaySurfaceMTL, UnityDisplaySurfaceBase)
  94. OBJC_OBJECT_PTR CAMetalLayer * layer;
  95. OBJC_OBJECT_PTR MTLDeviceRef device;
  96. OBJC_OBJECT_PTR MTLCommandQueueRef commandQueue;
  97. OBJC_OBJECT_PTR MTLCommandQueueRef drawableCommandQueue;
  98. OBJC_OBJECT_PTR MTLCommandBufferRef presentCB;
  99. OBJC_OBJECT_PTR CAMetalDrawableRef drawable;
  100. OBJC_OBJECT_PTR MTLTextureRef drawableProxyRT[kUnityNumOffscreenSurfaces];
  101. // These are used on a Mac with drawableProxyRT when off-screen rendering is used
  102. volatile int32_t bufferCompleted;
  103. volatile int32_t bufferSwap;
  104. OBJC_OBJECT_PTR MTLTextureRef systemColorRB;
  105. OBJC_OBJECT_PTR MTLTextureRef targetColorRT;
  106. OBJC_OBJECT_PTR MTLTextureRef targetAAColorRT;
  107. OBJC_OBJECT_PTR MTLTextureRef depthRB;
  108. OBJC_OBJECT_PTR MTLTextureRef stencilRB;
  109. unsigned colorFormat; // [MTLPixelFormat]
  110. unsigned depthFormat; // [MTLPixelFormat]
  111. int framebufferOnly;
  112. END_STRUCT(UnityDisplaySurfaceMTL)
  113. // START_STRUCT confuse clang c compiler (though it is idiomatic c code that works)
  114. #pragma clang diagnostic pop
  115. // be aware that this enum is shared with unity implementation so you should absolutely not change it
  116. typedef enum UnityRenderingAPI
  117. {
  118. apiMetal = 4,
  119. // command line argument: -nographics
  120. // does not initialize real graphics device and bypass all the rendering
  121. // currently supported only on simulators
  122. apiNoGraphics = -1,
  123. } UnityRenderingAPI;
  124. typedef struct RenderingSurfaceParams
  125. {
  126. // rendering setup
  127. int msaaSampleCount;
  128. int renderW;
  129. int renderH;
  130. int srgb;
  131. int wideColor;
  132. int hdr;
  133. int metalFramebufferOnly;
  134. int metalMemorylessDepth;
  135. // unity setup
  136. int disableDepthAndStencil;
  137. int useCVTextureCache;
  138. } RenderingSurfaceParams;
  139. #ifdef __cplusplus
  140. extern "C" {
  141. #endif
  142. int UnitySelectedRenderingAPI(void);
  143. #ifdef __cplusplus
  144. } // extern "C"
  145. #endif
  146. // metal
  147. #ifdef __cplusplus
  148. extern "C" {
  149. #endif
  150. void InitRenderingMTL(void);
  151. void CreateSystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  152. void DestroySystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  153. void CreateRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  154. void DestroyRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  155. void CreateSharedDepthbufferMTL(UnityDisplaySurfaceMTL* surface);
  156. void DestroySharedDepthbufferMTL(UnityDisplaySurfaceMTL* surface);
  157. void CreateUnityRenderBuffersMTL(UnityDisplaySurfaceMTL* surface);
  158. void DestroyUnityRenderBuffersMTL(UnityDisplaySurfaceMTL* surface);
  159. void StartFrameRenderingMTL(UnityDisplaySurfaceMTL* surface);
  160. void EndFrameRenderingMTL(UnityDisplaySurfaceMTL* surface);
  161. void PreparePresentMTL(UnityDisplaySurfaceMTL* surface);
  162. void PresentMTL(UnityDisplaySurfaceMTL* surface);
  163. // Acquires CAMetalDrawable resource for the surface and returns the drawable texture
  164. MTLTextureRef AcquireDrawableMTL(UnityDisplaySurfaceMTL* surface);
  165. unsigned UnityHDRSurfaceDepth(void);
  166. // starting with ios11 apple insists on having just one presentDrawable per command buffer
  167. // hence we keep normal processing for main screen, but when airplay is used we will create extra command buffers
  168. void PreparePresentNonMainScreenMTL(UnityDisplaySurfaceMTL* surface);
  169. void SetDrawableSizeMTL(UnityDisplaySurfaceMTL* surface, int width, int height);
  170. #ifdef __cplusplus
  171. } // extern "C"
  172. #endif
  173. // no graphics
  174. #ifdef __cplusplus
  175. extern "C" {
  176. #endif
  177. void InitRenderingNULL(void);
  178. void CreateSystemRenderingSurfaceNULL(UnityDisplaySurfaceBase* surface);
  179. void CreateRenderingSurfaceNULL(UnityDisplaySurfaceBase* surface);
  180. void DestroyRenderingSurfaceNULL(UnityDisplaySurfaceBase* surface);
  181. void CreateSharedDepthbufferNULL(UnityDisplaySurfaceBase* surface);
  182. void DestroySharedDepthbufferNULL(UnityDisplaySurfaceBase* surface);
  183. void CreateUnityRenderBuffersNULL(UnityDisplaySurfaceBase* surface);
  184. void DestroySystemRenderingSurfaceNULL(UnityDisplaySurfaceBase* surface);
  185. void DestroyUnityRenderBuffersNULL(UnityDisplaySurfaceBase* surface);
  186. void StartFrameRenderingNULL(UnityDisplaySurfaceBase* surface);
  187. void EndFrameRenderingNULL(UnityDisplaySurfaceBase* surface);
  188. void PreparePresentNULL(UnityDisplaySurfaceBase* surface);
  189. void PresentNULL(UnityDisplaySurfaceBase* surface);
  190. #ifdef __cplusplus
  191. } // extern "C"
  192. #endif
  193. #ifdef __cplusplus
  194. extern "C" {
  195. #endif
  196. // for Create* functions if surf is null we will actuially create new one, otherwise we update the one provided
  197. // metal: resolveTex should be non-nil only if tex have AA
  198. UnityRenderBufferHandle UnityCreateExternalSurfaceMTL(UnityRenderBufferHandle surf, int isColor, MTLTextureRef tex, const UnityRenderBufferDesc* desc);
  199. // Passing non-nil displaySurface will mark render surface as proxy and will do a delayed drawable acquisition when setting up framebuffer
  200. UnityRenderBufferHandle UnityCreateExternalColorSurfaceMTL(UnityRenderBufferHandle surf, MTLTextureRef tex, MTLTextureRef resolveTex, const UnityRenderBufferDesc* desc, UnityDisplaySurfaceMTL* displaySurface);
  201. UnityRenderBufferHandle UnityCreateExternalDepthSurfaceMTL(UnityRenderBufferHandle surf, MTLTextureRef tex, MTLTextureRef stencilTex, const UnityRenderBufferDesc* desc);
  202. // creates "dummy" surface - will indicate "missing" buffer (e.g. depth-only RT will have color as dummy)
  203. UnityRenderBufferHandle UnityCreateDummySurface(UnityRenderBufferHandle surf, int isColor, const UnityRenderBufferDesc* desc);
  204. // disable rendering to render buffers (all Cameras that were rendering to one of buffers would be reset to use backbuffer)
  205. void UnityDisableRenderBuffers(UnityRenderBufferHandle color, UnityRenderBufferHandle depth);
  206. // destroys render buffer
  207. void UnityDestroyExternalSurface(UnityRenderBufferHandle surf);
  208. // sets current render target
  209. void UnitySetRenderTarget(UnityRenderBufferHandle color, UnityRenderBufferHandle depth);
  210. // final blit to backbuffer
  211. void UnityBlitToBackbuffer(UnityRenderBufferHandle srcColor, UnityRenderBufferHandle dstColor, UnityRenderBufferHandle dstDepth);
  212. // get native renderbuffer from handle
  213. // sets vSync on OSX 10.13 and up
  214. #if PLATFORM_OSX
  215. void MetalUpdateDisplaySync(void);
  216. #endif
  217. UnityRenderBufferHandle UnityNativeRenderBufferFromHandle(void *rb);
  218. MTLCommandBufferRef UnityCurrentMTLCommandBuffer(void);
  219. void UnityUpdateDrawableSize(UnityDisplaySurfaceMTL* surface);
  220. #ifdef __cplusplus
  221. } // extern "C"
  222. #endif
  223. // metal/gles unification
  224. #define GLES_METAL_COMMON_IMPL_SURF(f) \
  225. inline void f(UnityDisplaySurfaceBase* surface) \
  226. { \
  227. switch(surface->api) { \
  228. case apiMetal: f ## MTL((UnityDisplaySurfaceMTL*)surface); break; \
  229. case apiNoGraphics: f ## NULL(surface); break; \
  230. } \
  231. } \
  232. #define GLES_METAL_COMMON_IMPL(f) \
  233. inline void f() \
  234. { \
  235. switch(UnitySelectedRenderingAPI()) { \
  236. case apiMetal: f ## MTL(); break; \
  237. case apiNoGraphics: f ## NULL(); break; \
  238. } \
  239. } \
  240. GLES_METAL_COMMON_IMPL(InitRendering);
  241. GLES_METAL_COMMON_IMPL_SURF(CreateSystemRenderingSurface);
  242. GLES_METAL_COMMON_IMPL_SURF(DestroySystemRenderingSurface);
  243. GLES_METAL_COMMON_IMPL_SURF(CreateRenderingSurface);
  244. GLES_METAL_COMMON_IMPL_SURF(DestroyRenderingSurface);
  245. GLES_METAL_COMMON_IMPL_SURF(CreateSharedDepthbuffer);
  246. GLES_METAL_COMMON_IMPL_SURF(DestroySharedDepthbuffer);
  247. GLES_METAL_COMMON_IMPL_SURF(CreateUnityRenderBuffers);
  248. GLES_METAL_COMMON_IMPL_SURF(DestroyUnityRenderBuffers);
  249. GLES_METAL_COMMON_IMPL_SURF(StartFrameRendering);
  250. GLES_METAL_COMMON_IMPL_SURF(EndFrameRendering);
  251. GLES_METAL_COMMON_IMPL_SURF(PreparePresent);
  252. GLES_METAL_COMMON_IMPL_SURF(Present);
  253. #undef GLES_METAL_COMMON_IMPL_SURF
  254. #undef GLES_METAL_COMMON_IMPL