UnityRendering.h 14 KB

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