No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

UnityRendering.h 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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 CAMetalDrawableRef drawable;
  99. OBJC_OBJECT_PTR MTLTextureRef drawableProxyRT[kUnityNumOffscreenSurfaces];
  100. UnityRenderBufferHandle drawableProxyRS[kUnityNumOffscreenSurfaces];
  101. int drawableProxyNeedsClear[kUnityNumOffscreenSurfaces]; // [bool] Tracks whether the drawableProxy requires a clear after initial creation
  102. // This is used on a Mac with drawableProxyRT when off-screen rendering is used
  103. int proxySwaps; // Counts times proxy RTs have swapped since surface recreated
  104. int proxyReady; // [bool] Proxy RT has swapped since last present; frame ended
  105. int calledPresentDrawable; // Tracks presenting for editor.
  106. int vsync; // Is vsync enabled or not
  107. OBJC_OBJECT_PTR MTLTextureRef drawableTex;
  108. OBJC_OBJECT_PTR MTLTextureRef systemColorRB;
  109. OBJC_OBJECT_PTR MTLTextureRef targetColorRT;
  110. OBJC_OBJECT_PTR MTLTextureRef targetAAColorRT;
  111. OBJC_OBJECT_PTR MTLTextureRef depthRB;
  112. OBJC_OBJECT_PTR MTLTextureRef stencilRB;
  113. unsigned colorFormat; // [MTLPixelFormat]
  114. unsigned depthFormat; // [MTLPixelFormat]
  115. int framebufferOnly;
  116. END_STRUCT(UnityDisplaySurfaceMTL)
  117. // START_STRUCT confuse clang c compiler (though it is idiomatic c code that works)
  118. #pragma clang diagnostic pop
  119. // be aware that this enum is shared with unity implementation so you should absolutely not change it
  120. typedef enum UnityRenderingAPI
  121. {
  122. apiMetal = 4,
  123. // command line argument: -nographics
  124. // does not initialize real graphics device and bypass all the rendering
  125. // currently supported only on simulators
  126. apiNoGraphics = -1,
  127. } UnityRenderingAPI;
  128. typedef struct RenderingSurfaceParams
  129. {
  130. // rendering setup
  131. int msaaSampleCount;
  132. int renderW;
  133. int renderH;
  134. int srgb;
  135. int wideColor;
  136. int hdr;
  137. int metalFramebufferOnly;
  138. int metalMemorylessDepth;
  139. // unity setup
  140. int disableDepthAndStencil;
  141. int useCVTextureCache;
  142. } RenderingSurfaceParams;
  143. #ifdef __cplusplus
  144. extern "C" {
  145. #endif
  146. int UnitySelectedRenderingAPI(void);
  147. #ifdef __cplusplus
  148. } // extern "C"
  149. #endif
  150. // metal
  151. #ifdef __cplusplus
  152. extern "C" {
  153. #endif
  154. void InitRenderingMTL(void);
  155. void CreateSystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  156. void DestroySystemRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  157. void CreateRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  158. void DestroyRenderingSurfaceMTL(UnityDisplaySurfaceMTL* surface);
  159. void CreateSharedDepthbufferMTL(UnityDisplaySurfaceMTL* surface);
  160. void DestroySharedDepthbufferMTL(UnityDisplaySurfaceMTL* surface);
  161. void CreateUnityRenderBuffersMTL(UnityDisplaySurfaceMTL* surface);
  162. void DestroyUnityRenderBuffersMTL(UnityDisplaySurfaceMTL* surface);
  163. void StartFrameRenderingMTL(UnityDisplaySurfaceMTL* surface);
  164. void EndFrameRenderingMTL(UnityDisplaySurfaceMTL* surface);
  165. void PreparePresentMTL(UnityDisplaySurfaceMTL* surface);
  166. void PresentMTL(UnityDisplaySurfaceMTL* surface);
  167. // Acquires CAMetalDrawable resource for the surface and returns the drawable texture
  168. MTLTextureRef AcquireDrawableMTL(UnityDisplaySurfaceMTL* surface);
  169. unsigned UnityHDRSurfaceDepth(void);
  170. // starting with ios11 apple insists on having just one presentDrawable per command buffer
  171. // hence we keep normal processing for main screen, but when airplay is used we will create extra command buffers
  172. void PreparePresentNonMainScreenMTL(UnityDisplaySurfaceMTL* surface);
  173. void SetDrawableSizeMTL(UnityDisplaySurfaceMTL* surface, int width, int height);
  174. #ifdef __cplusplus
  175. } // extern "C"
  176. #endif
  177. // no graphics
  178. #ifdef __cplusplus
  179. extern "C" {
  180. #endif
  181. void InitRenderingNULL(void);
  182. void CreateSystemRenderingSurfaceNULL(UnityDisplaySurfaceBase* surface);
  183. void CreateRenderingSurfaceNULL(UnityDisplaySurfaceBase* surface);
  184. void DestroyRenderingSurfaceNULL(UnityDisplaySurfaceBase* surface);
  185. void CreateSharedDepthbufferNULL(UnityDisplaySurfaceBase* surface);
  186. void DestroySharedDepthbufferNULL(UnityDisplaySurfaceBase* surface);
  187. void CreateUnityRenderBuffersNULL(UnityDisplaySurfaceBase* surface);
  188. void DestroySystemRenderingSurfaceNULL(UnityDisplaySurfaceBase* surface);
  189. void DestroyUnityRenderBuffersNULL(UnityDisplaySurfaceBase* surface);
  190. void StartFrameRenderingNULL(UnityDisplaySurfaceBase* surface);
  191. void EndFrameRenderingNULL(UnityDisplaySurfaceBase* surface);
  192. void PreparePresentNULL(UnityDisplaySurfaceBase* surface);
  193. void PresentNULL(UnityDisplaySurfaceBase* surface);
  194. #ifdef __cplusplus
  195. } // extern "C"
  196. #endif
  197. #ifdef __cplusplus
  198. extern "C" {
  199. #endif
  200. // for Create* functions if surf is null we will actuially create new one, otherwise we update the one provided
  201. // metal: resolveTex should be non-nil only if tex have AA
  202. UnityRenderBufferHandle UnityCreateExternalSurfaceMTL(UnityRenderBufferHandle surf, int isColor, MTLTextureRef tex, const UnityRenderBufferDesc* desc);
  203. // Passing non-nil displaySurface will mark render surface as proxy and will do a delayed drawable acquisition when setting up framebuffer
  204. UnityRenderBufferHandle UnityCreateExternalColorSurfaceMTL(UnityRenderBufferHandle surf, MTLTextureRef tex, MTLTextureRef resolveTex, const UnityRenderBufferDesc* desc, UnityDisplaySurfaceMTL* displaySurface);
  205. UnityRenderBufferHandle UnityCreateExternalDepthSurfaceMTL(UnityRenderBufferHandle surf, MTLTextureRef tex, MTLTextureRef stencilTex, const UnityRenderBufferDesc* desc);
  206. // creates "dummy" surface - will indicate "missing" buffer (e.g. depth-only RT will have color as dummy)
  207. UnityRenderBufferHandle UnityCreateDummySurface(UnityRenderBufferHandle surf, int isColor, const UnityRenderBufferDesc* desc);
  208. // external render surfaces and textures are "out of scope" for memory profiler, hence we add means to register them separately
  209. // the separate mechanism is needed because unity cannot know what manages the lifetime of textures in this case
  210. // specifically since we allow external render surfaces and textures to share metal textures
  211. void UnityRegisterExternalRenderSurfaceTextureForMemoryProfiler(MTLTextureRef tex);
  212. void UnityRegisterExternalTextureForMemoryProfiler(MTLTextureRef tex);
  213. void UnityUnregisterMetalTextureForMemoryProfiler(MTLTextureRef tex);
  214. // disable rendering to render buffers (all Cameras that were rendering to one of buffers would be reset to use backbuffer)
  215. void UnityDisableRenderBuffers(UnityRenderBufferHandle color, UnityRenderBufferHandle depth);
  216. // destroys render buffer
  217. void UnityDestroyExternalSurface(UnityRenderBufferHandle surf);
  218. // sets current render target
  219. void UnitySetRenderTarget(UnityRenderBufferHandle color, UnityRenderBufferHandle depth);
  220. // final blit to backbuffer
  221. void UnityBlitToBackbuffer(UnityRenderBufferHandle srcColor, UnityRenderBufferHandle dstColor, UnityRenderBufferHandle dstDepth);
  222. // get native renderbuffer from handle
  223. // sets vSync on OSX 10.13 and up
  224. #if PLATFORM_OSX
  225. void MetalUpdateDisplaySync(void);
  226. #endif
  227. UnityRenderBufferHandle UnityNativeRenderBufferFromHandle(void *rb);
  228. MTLCommandBufferRef UnityCurrentMTLCommandBuffer(void);
  229. void UnityUpdateDrawableSize(UnityDisplaySurfaceMTL* surface);
  230. #ifdef __cplusplus
  231. } // extern "C"
  232. #endif
  233. // metal/gles unification
  234. #define GLES_METAL_COMMON_IMPL_SURF(f) \
  235. inline void f(UnityDisplaySurfaceBase* surface) \
  236. { \
  237. switch(surface->api) { \
  238. case apiMetal: f ## MTL((UnityDisplaySurfaceMTL*)surface); break; \
  239. case apiNoGraphics: f ## NULL(surface); break; \
  240. } \
  241. } \
  242. #define GLES_METAL_COMMON_IMPL(f) \
  243. inline void f() \
  244. { \
  245. switch(UnitySelectedRenderingAPI()) { \
  246. case apiMetal: f ## MTL(); break; \
  247. case apiNoGraphics: f ## NULL(); break; \
  248. } \
  249. } \
  250. GLES_METAL_COMMON_IMPL(InitRendering);
  251. GLES_METAL_COMMON_IMPL_SURF(CreateSystemRenderingSurface);
  252. GLES_METAL_COMMON_IMPL_SURF(DestroySystemRenderingSurface);
  253. GLES_METAL_COMMON_IMPL_SURF(CreateRenderingSurface);
  254. GLES_METAL_COMMON_IMPL_SURF(DestroyRenderingSurface);
  255. GLES_METAL_COMMON_IMPL_SURF(CreateSharedDepthbuffer);
  256. GLES_METAL_COMMON_IMPL_SURF(DestroySharedDepthbuffer);
  257. GLES_METAL_COMMON_IMPL_SURF(CreateUnityRenderBuffers);
  258. GLES_METAL_COMMON_IMPL_SURF(DestroyUnityRenderBuffers);
  259. GLES_METAL_COMMON_IMPL_SURF(StartFrameRendering);
  260. GLES_METAL_COMMON_IMPL_SURF(EndFrameRendering);
  261. GLES_METAL_COMMON_IMPL_SURF(PreparePresent);
  262. GLES_METAL_COMMON_IMPL_SURF(Present);
  263. #undef GLES_METAL_COMMON_IMPL_SURF
  264. #undef GLES_METAL_COMMON_IMPL