CVTextureCache.mm 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #include "CVTextureCache.h"
  2. #include "DisplayManager.h"
  3. #include "UnityMetalSupport.h"
  4. #if UNITY_CAN_USE_METAL
  5. #include <CoreVideo/CVMetalTextureCache.h>
  6. #else
  7. typedef void* CVMetalTextureCacheRef;
  8. typedef void* CVMetalTextureRef;
  9. const CFStringRef kCVPixelBufferMetalCompatibilityKey = CFSTR("MetalCompatibility");
  10. inline CVReturn CVMetalTextureCacheCreate(CFAllocatorRef, CFDictionaryRef, MTLDeviceRef, CFDictionaryRef, CVMetalTextureCacheRef*) { return 0; }
  11. inline CVReturn CVMetalTextureCacheCreateTextureFromImage(CFAllocatorRef, CVMetalTextureCacheRef, CVImageBufferRef, CFDictionaryRef, MTLPixelFormat, size_t, size_t, size_t, CVMetalTextureRef*) { return 0; }
  12. inline void CVMetalTextureCacheFlush(CVMetalTextureCacheRef, uint64_t options) {}
  13. inline MTLTextureRef CVMetalTextureGetTexture(CVMetalTextureRef) { return nil; }
  14. inline Boolean CVMetalTextureIsFlipped(CVMetalTextureRef) { return 0; }
  15. #endif
  16. void* CreateCVTextureCache()
  17. {
  18. void* ret = 0;
  19. CVReturn err = 0;
  20. if (UnitySelectedRenderingAPI() == apiMetal)
  21. err = CVMetalTextureCacheCreate(kCFAllocatorDefault, 0, UnityGetMetalDevice(), 0, (CVMetalTextureCacheRef*)&ret);
  22. if (err)
  23. {
  24. ::printf("Error at CVMetalTextureCacheCreate: %d", err);
  25. ret = 0;
  26. }
  27. return ret;
  28. }
  29. void FlushCVTextureCache(void* cache)
  30. {
  31. if (UnitySelectedRenderingAPI() == apiMetal)
  32. CVMetalTextureCacheFlush((CVMetalTextureCacheRef)cache, 0);
  33. }
  34. void* CreateTextureFromCVTextureCache2(void* cache, void* image, size_t w, size_t h, uint64_t metalFormat)
  35. {
  36. void* texture = 0;
  37. CVReturn err = 0;
  38. if (UnitySelectedRenderingAPI() == apiMetal)
  39. {
  40. err = CVMetalTextureCacheCreateTextureFromImage(
  41. kCFAllocatorDefault, (CVMetalTextureCacheRef)cache, (CVImageBufferRef)image, 0,
  42. (MTLPixelFormat)metalFormat, w, h, 0, (CVMetalTextureRef*)&texture
  43. );
  44. }
  45. if (err)
  46. {
  47. ::printf("Error at CVMetalTextureCacheCreateTextureFromImage: %d\n", err);
  48. texture = 0;
  49. }
  50. return texture;
  51. }
  52. id<MTLTexture> GetMetalTextureFromCVTextureCache(void* texture)
  53. {
  54. assert(UnitySelectedRenderingAPI() == apiMetal);
  55. return CVMetalTextureGetTexture((CVMetalTextureRef)texture);
  56. }
  57. uintptr_t GetTextureFromCVTextureCache(void* texture)
  58. {
  59. if (UnitySelectedRenderingAPI() == apiMetal)
  60. return (uintptr_t)(__bridge void*)GetMetalTextureFromCVTextureCache(texture);
  61. return 0;
  62. }
  63. void* CreatePixelBufferForCVTextureCache2(size_t w, size_t h, uint32_t cvFormat)
  64. {
  65. CVPixelBufferRef pb = 0;
  66. NSDictionary* options = @{ (__bridge NSString*)kCVPixelBufferPixelFormatTypeKey: @(cvFormat),
  67. (__bridge NSString*)kCVPixelBufferWidthKey: @(w),
  68. (__bridge NSString*)kCVPixelBufferHeightKey: @(h),
  69. (__bridge NSString*)kCVPixelBufferMetalCompatibilityKey: @(YES),
  70. (__bridge NSString*)kCVPixelBufferIOSurfacePropertiesKey: @{}};
  71. CVPixelBufferCreate(kCFAllocatorDefault, w, h, cvFormat, (__bridge CFDictionaryRef)options, &pb);
  72. return pb;
  73. }
  74. void* CreateReadableRTFromCVTextureCache2(void* cache, size_t w, size_t h, uint32_t cvFormat, uint64_t metalFormat, void** pb)
  75. {
  76. *pb = CreatePixelBufferForCVTextureCache2(w, h, cvFormat);
  77. return CreateTextureFromCVTextureCache2(cache, *pb, w, h, metalFormat);
  78. }
  79. int IsCVTextureFlipped(void* texture)
  80. {
  81. if (UnitySelectedRenderingAPI() == apiMetal)
  82. return CVMetalTextureIsFlipped((CVMetalTextureRef)texture);
  83. return 0;
  84. }
  85. //
  86. // deprecated
  87. //
  88. void* CreatePixelBufferForCVTextureCache(size_t w, size_t h)
  89. {
  90. return CreatePixelBufferForCVTextureCache2(w, h, kCVPixelFormatType_32BGRA);
  91. }
  92. void* CreateReadableRTFromCVTextureCache(void* cache, size_t w, size_t h, void** pb)
  93. {
  94. *pb = CreatePixelBufferForCVTextureCache2(w, h, kCVPixelFormatType_32BGRA);
  95. return CreateBGRA32TextureFromCVTextureCache(cache, *pb, w, h);
  96. }
  97. void* CreateBGRA32TextureFromCVTextureCache(void* cache, void* image, size_t w, size_t h)
  98. {
  99. void* texture = 0;
  100. CVReturn err = 0;
  101. if (UnitySelectedRenderingAPI() == apiMetal)
  102. {
  103. err = CVMetalTextureCacheCreateTextureFromImage(
  104. kCFAllocatorDefault, (CVMetalTextureCacheRef)cache, (CVImageBufferRef)image, 0,
  105. (MTLPixelFormat)((UnityDisplaySurfaceMTL*)GetMainDisplaySurface())->colorFormat, w, h, 0, (CVMetalTextureRef*)&texture
  106. );
  107. }
  108. if (err)
  109. {
  110. ::printf("Error at CVMetalTextureCacheCreateTextureFromImage: %d\n", err);
  111. texture = 0;
  112. }
  113. return texture;
  114. }
  115. void* CreateHalfFloatTextureFromCVTextureCache(void* cache, void* image, size_t w, size_t h)
  116. {
  117. void* texture = 0;
  118. CVReturn err = 0;
  119. if (UnitySelectedRenderingAPI() == apiMetal)
  120. {
  121. err = CVMetalTextureCacheCreateTextureFromImage(
  122. kCFAllocatorDefault, (CVMetalTextureCacheRef)cache, (CVImageBufferRef)image, 0,
  123. MTLPixelFormatR16Float, w, h, 0, (CVMetalTextureRef*)&texture
  124. );
  125. }
  126. if (err)
  127. {
  128. ::printf("Error at CVMetalTextureCacheCreateTextureFromImage: %d\n", err);
  129. texture = 0;
  130. }
  131. return texture;
  132. }