renderer_mtl.h 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175
  1. /*
  2. * Copyright 2011-2015 Attila Kocsis, Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #ifndef BGFX_RENDERER_METAL_H_HEADER_GUARD
  6. #define BGFX_RENDERER_METAL_H_HEADER_GUARD
  7. #include "bgfx_p.h"
  8. #if BGFX_CONFIG_RENDERER_METAL
  9. #import <QuartzCore/CAMetalLayer.h>
  10. #import <Metal/Metal.h>
  11. #import <MetalKit/MetalKit.h>
  12. #if BX_PLATFORM_IOS
  13. # import <UIKit/UIKit.h>
  14. #endif // BX_PLATFORM_*
  15. #define BGFX_MTL_PROFILER_BEGIN(_view, _abgr) \
  16. BX_MACRO_BLOCK_BEGIN \
  17. BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \
  18. BX_MACRO_BLOCK_END
  19. #define BGFX_MTL_PROFILER_BEGIN_LITERAL(_name, _abgr) \
  20. BX_MACRO_BLOCK_BEGIN \
  21. BGFX_PROFILER_BEGIN_LITERAL("" # _name, _abgr); \
  22. BX_MACRO_BLOCK_END
  23. #define BGFX_MTL_PROFILER_END() \
  24. BX_MACRO_BLOCK_BEGIN \
  25. BGFX_PROFILER_END(); \
  26. BX_MACRO_BLOCK_END
  27. namespace bgfx { namespace mtl
  28. {
  29. //runtime os check
  30. inline bool iOSVersionEqualOrGreater(const char* _version)
  31. {
  32. #if BX_PLATFORM_IOS
  33. return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending);
  34. #else
  35. BX_UNUSED(_version);
  36. return false;
  37. #endif
  38. }
  39. inline bool macOSVersionEqualOrGreater(
  40. NSInteger _majorVersion
  41. , NSInteger _minorVersion
  42. , NSInteger _patchVersion
  43. )
  44. {
  45. #if BX_PLATFORM_OSX
  46. NSOperatingSystemVersion v = [[NSProcessInfo processInfo] operatingSystemVersion];
  47. return (v.majorVersion<<16) + (v.minorVersion<<8) + v.patchVersion >=
  48. (_majorVersion<<16) + (_minorVersion<<8) + _patchVersion;
  49. #else
  50. BX_UNUSED(_majorVersion, _minorVersion, _patchVersion);
  51. return false;
  52. #endif
  53. }
  54. // c++ wrapper
  55. // objects with creation functions starting with 'new' has a refcount 1 after creation, object must be destroyed with release.
  56. // commandBuffer, commandEncoders are autoreleased objects. Needs AutoreleasePool!
  57. #define MTL_MAX_FRAMES_IN_FLIGHT (3)
  58. #define MTL_CLASS(name) \
  59. class name \
  60. { \
  61. public: \
  62. name(id <MTL##name> _obj = nil) : m_obj(_obj) {} \
  63. operator id <MTL##name>() const { return m_obj; } \
  64. id <MTL##name> m_obj;
  65. #define MTL_CLASS_END };
  66. typedef void (*mtlCallback)(void* userData);
  67. MTL_CLASS(BlitCommandEncoder)
  68. void copyFromTexture(
  69. id<MTLTexture> _sourceTexture
  70. , NSUInteger _sourceSlice
  71. , NSUInteger _sourceLevel
  72. , MTLOrigin _sourceOrigin
  73. , MTLSize _sourceSize
  74. , id<MTLTexture> _destinationTexture
  75. , NSUInteger _destinationSlice
  76. , NSUInteger _destinationLevel
  77. , MTLOrigin _destinationOrigin
  78. )
  79. {
  80. [m_obj copyFromTexture:_sourceTexture sourceSlice:_sourceSlice sourceLevel:_sourceLevel sourceOrigin:_sourceOrigin sourceSize:_sourceSize
  81. toTexture:_destinationTexture destinationSlice:_destinationSlice destinationLevel:_destinationLevel destinationOrigin:_destinationOrigin];
  82. }
  83. void copyFromBuffer(
  84. id<MTLBuffer> _sourceBuffer
  85. , NSUInteger _sourceOffset
  86. , id<MTLBuffer> _destinationBuffer
  87. , NSUInteger _destinationOffset
  88. , NSUInteger _size
  89. )
  90. {
  91. [m_obj copyFromBuffer:_sourceBuffer sourceOffset:_sourceOffset toBuffer:_destinationBuffer
  92. destinationOffset:_destinationOffset size:_size];
  93. }
  94. void copyFromBuffer(
  95. id<MTLBuffer> _sourceBuffer
  96. , NSUInteger _sourceOffset
  97. , NSUInteger _sourceBytesPerRow
  98. , NSUInteger _sourceBytesPerImage
  99. , MTLSize _sourceSize
  100. , id<MTLTexture> _destinationTexture
  101. , NSUInteger _destinationSlice
  102. , NSUInteger _destinationLevel
  103. , MTLOrigin _destinationOrigin
  104. )
  105. {
  106. [m_obj copyFromBuffer:_sourceBuffer sourceOffset:_sourceOffset sourceBytesPerRow:_sourceBytesPerRow
  107. sourceBytesPerImage:_sourceBytesPerImage sourceSize:_sourceSize toTexture:_destinationTexture
  108. destinationSlice:_destinationSlice destinationLevel:_destinationLevel destinationOrigin:_destinationOrigin];
  109. }
  110. #if BX_PLATFORM_OSX
  111. void synchronizeTexture(id<MTLTexture> _texture, NSUInteger _slice, NSUInteger _level)
  112. {
  113. [m_obj synchronizeTexture:_texture slice:_slice level:_level];
  114. }
  115. void synchronizeResource(id<MTLResource> _resource)
  116. {
  117. [m_obj synchronizeResource:_resource];
  118. }
  119. #endif // BX_PLATFORM_OSX
  120. void endEncoding()
  121. {
  122. [m_obj endEncoding];
  123. }
  124. MTL_CLASS_END
  125. MTL_CLASS(Buffer)
  126. void* contents()
  127. {
  128. return m_obj.contents;
  129. }
  130. uint32_t length()
  131. {
  132. return (uint32_t)m_obj.length;
  133. }
  134. void setLabel(const char* _label)
  135. {
  136. [m_obj setLabel:@(_label)];
  137. }
  138. MTL_CLASS_END
  139. MTL_CLASS(CommandBuffer)
  140. // Creating Command Encoders
  141. id<MTLRenderCommandEncoder> renderCommandEncoderWithDescriptor(MTLRenderPassDescriptor* _renderPassDescriptor){
  142. return [m_obj renderCommandEncoderWithDescriptor:_renderPassDescriptor];
  143. }
  144. id<MTLComputeCommandEncoder> computeCommandEncoder()
  145. {
  146. return [m_obj computeCommandEncoder];
  147. }
  148. id<MTLBlitCommandEncoder> blitCommandEncoder()
  149. {
  150. return [m_obj blitCommandEncoder];
  151. }
  152. // Scheduling and Executing Commands
  153. void enqueue()
  154. {
  155. [m_obj enqueue];
  156. }
  157. void commit()
  158. {
  159. [m_obj commit];
  160. }
  161. void addScheduledHandler(mtlCallback _cb, void* _data)
  162. {
  163. [m_obj addScheduledHandler:^(id <MTLCommandBuffer>){ _cb(_data); }];
  164. }
  165. void addCompletedHandler(mtlCallback _cb, void* _data)
  166. {
  167. [m_obj addCompletedHandler:^(id <MTLCommandBuffer>){ _cb(_data); }];
  168. }
  169. void presentDrawable(id<MTLDrawable> _drawable)
  170. {
  171. [m_obj presentDrawable:_drawable];
  172. }
  173. void waitUntilCompleted()
  174. {
  175. [m_obj waitUntilCompleted];
  176. }
  177. MTL_CLASS_END
  178. MTL_CLASS(CommandQueue)
  179. id<MTLCommandBuffer> commandBuffer()
  180. {
  181. return [m_obj commandBuffer];
  182. }
  183. id<MTLCommandBuffer> commandBufferWithUnretainedReferences()
  184. {
  185. return [m_obj commandBufferWithUnretainedReferences];
  186. }
  187. MTL_CLASS_END
  188. MTL_CLASS(ComputeCommandEncoder)
  189. void setComputePipelineState(id<MTLComputePipelineState> _state)
  190. {
  191. [m_obj setComputePipelineState:_state];
  192. }
  193. void setBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index)
  194. {
  195. [m_obj setBuffer:_buffer offset:_offset atIndex:_index];
  196. }
  197. void setTexture(id<MTLTexture> _texture, NSUInteger _index)
  198. {
  199. [m_obj setTexture:_texture atIndex:_index];
  200. }
  201. void setSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index)
  202. {
  203. [m_obj setSamplerState:_sampler atIndex:_index];
  204. }
  205. void dispatchThreadgroups(MTLSize _threadgroupsPerGrid, MTLSize _threadsPerThreadgroup)
  206. {
  207. [m_obj dispatchThreadgroups:_threadgroupsPerGrid threadsPerThreadgroup:_threadsPerThreadgroup];
  208. }
  209. void dispatchThreadgroupsWithIndirectBuffer(id <MTLBuffer> _indirectBuffer,
  210. NSUInteger _indirectBufferOffset, MTLSize _threadsPerThreadgroup)
  211. {
  212. [m_obj dispatchThreadgroupsWithIndirectBuffer:_indirectBuffer indirectBufferOffset:_indirectBufferOffset threadsPerThreadgroup:_threadsPerThreadgroup];
  213. }
  214. void endEncoding()
  215. {
  216. [m_obj endEncoding];
  217. }
  218. void pushDebugGroup(const char* _string)
  219. {
  220. [m_obj pushDebugGroup:@(_string)];
  221. }
  222. void popDebugGroup()
  223. {
  224. [m_obj popDebugGroup];
  225. }
  226. MTL_CLASS_END
  227. MTL_CLASS(Device)
  228. bool supportsFeatureSet(MTLFeatureSet _featureSet)
  229. {
  230. return [m_obj supportsFeatureSet:_featureSet];
  231. }
  232. id<MTLLibrary> newLibraryWithData(const void* _data)
  233. {
  234. NSError* error;
  235. id<MTLLibrary> lib = [m_obj newLibraryWithData:(dispatch_data_t)_data error:&error];
  236. BX_WARN(NULL == error
  237. , "newLibraryWithData failed: %s"
  238. , [error.localizedDescription cStringUsingEncoding:NSASCIIStringEncoding]
  239. );
  240. return lib;
  241. }
  242. id<MTLLibrary> newLibraryWithSource(const char* _source)
  243. {
  244. NSError* error;
  245. id<MTLLibrary> lib = [m_obj newLibraryWithSource:@(_source) options:nil error:&error];
  246. BX_WARN(NULL == error
  247. , "Shader compilation failed: %s"
  248. , [error.localizedDescription cStringUsingEncoding:NSASCIIStringEncoding]
  249. );
  250. return lib;
  251. }
  252. id<MTLCommandQueue> newCommandQueue()
  253. {
  254. return [m_obj newCommandQueue];
  255. }
  256. id<MTLCommandQueue> newCommandQueueWithMaxCommandBufferCount(NSUInteger _maxCommandBufferCount)
  257. {
  258. return [m_obj newCommandQueueWithMaxCommandBufferCount:_maxCommandBufferCount];
  259. }
  260. // Creating Resources
  261. id<MTLBuffer> newBufferWithLength(unsigned int _length, MTLResourceOptions _options)
  262. {
  263. return [m_obj newBufferWithLength:_length options:_options ];
  264. }
  265. id<MTLBuffer> newBufferWithBytes(const void* _pointer, NSUInteger _length, MTLResourceOptions _options)
  266. {
  267. return [m_obj newBufferWithBytes:_pointer length:_length options:_options];
  268. }
  269. id<MTLTexture> newTextureWithDescriptor(MTLTextureDescriptor* _descriptor)
  270. {
  271. return [m_obj newTextureWithDescriptor:_descriptor];
  272. }
  273. id<MTLSamplerState> newSamplerStateWithDescriptor(MTLSamplerDescriptor* _descriptor)
  274. {
  275. return [m_obj newSamplerStateWithDescriptor:_descriptor];
  276. }
  277. // Creating Command Objects Needed to Render Graphics
  278. id<MTLDepthStencilState> newDepthStencilStateWithDescriptor(MTLDepthStencilDescriptor* _descriptor)
  279. {
  280. return [m_obj newDepthStencilStateWithDescriptor:_descriptor];
  281. }
  282. id <MTLRenderPipelineState> newRenderPipelineStateWithDescriptor(MTLRenderPipelineDescriptor* _descriptor)
  283. {
  284. NSError* error;
  285. id <MTLRenderPipelineState> state = [m_obj newRenderPipelineStateWithDescriptor:_descriptor error:&error];
  286. BX_WARN(NULL == error
  287. , "newRenderPipelineStateWithDescriptor failed: %s"
  288. , [error.localizedDescription cStringUsingEncoding:NSASCIIStringEncoding]
  289. );
  290. return state;
  291. }
  292. id <MTLRenderPipelineState> newRenderPipelineStateWithDescriptor(
  293. MTLRenderPipelineDescriptor* _descriptor
  294. , MTLPipelineOption _options
  295. , MTLRenderPipelineReflection** _reflection
  296. )
  297. {
  298. NSError* error;
  299. id <MTLRenderPipelineState> state = [m_obj newRenderPipelineStateWithDescriptor:_descriptor options:_options reflection:_reflection error:&error];
  300. BX_WARN(NULL == error
  301. , "newRenderPipelineStateWithDescriptor failed: %s"
  302. , [error.localizedDescription cStringUsingEncoding:NSASCIIStringEncoding]
  303. );
  304. return state;
  305. }
  306. // Creating Command Objects Needed to Perform Computational Tasks
  307. id <MTLComputePipelineState> newComputePipelineStateWithFunction(
  308. id <MTLFunction> _computeFunction
  309. , MTLPipelineOption _options
  310. , MTLComputePipelineReflection** _reflection
  311. )
  312. {
  313. NSError* error;
  314. id <MTLComputePipelineState> state = [m_obj newComputePipelineStateWithFunction:_computeFunction options:_options reflection:_reflection error:&error];
  315. BX_WARN(NULL == error
  316. , "newComputePipelineStateWithFunction failed: %s"
  317. , [error.localizedDescription cStringUsingEncoding:NSASCIIStringEncoding]
  318. );
  319. return state;
  320. }
  321. bool supportsTextureSampleCount(int sampleCount)
  322. {
  323. if (BX_ENABLED(BX_PLATFORM_IOS) && !iOSVersionEqualOrGreater("9.0.0") )
  324. return sampleCount == 1 || sampleCount == 2 || sampleCount == 4;
  325. else
  326. return [m_obj supportsTextureSampleCount:sampleCount];
  327. }
  328. bool depth24Stencil8PixelFormatSupported()
  329. {
  330. #if BX_PLATFORM_IOS
  331. return false;
  332. #else
  333. return m_obj.depth24Stencil8PixelFormatSupported;
  334. #endif // BX_PLATFORM_IOS
  335. }
  336. MTL_CLASS_END
  337. MTL_CLASS(Function)
  338. NSArray* vertexAttributes()
  339. {
  340. return m_obj.vertexAttributes;
  341. }
  342. void setLabel(const char* _label)
  343. {
  344. if ([m_obj respondsToSelector:@selector(setLabel:)])
  345. {
  346. [m_obj setLabel:@(_label)];
  347. }
  348. }
  349. MTL_CLASS_END
  350. MTL_CLASS(Library)
  351. id <MTLFunction> newFunctionWithName(const char* _functionName)
  352. {
  353. return [m_obj newFunctionWithName:@(_functionName)];
  354. }
  355. MTL_CLASS_END
  356. MTL_CLASS(RenderCommandEncoder)
  357. // Setting Graphics Rendering State
  358. void setBlendColor(float _red, float _green, float _blue, float _alpha)
  359. {
  360. [m_obj setBlendColorRed:_red green:_green blue:_blue alpha:_alpha];
  361. }
  362. void setCullMode(MTLCullMode _cullMode)
  363. {
  364. [m_obj setCullMode:_cullMode];
  365. }
  366. void setDepthBias(float _depthBias, float _slopeScale, float _clamp)
  367. {
  368. [m_obj setDepthBias:_depthBias slopeScale:_slopeScale clamp:_clamp];
  369. }
  370. void setDepthStencilState(id<MTLDepthStencilState> _depthStencilState)
  371. {
  372. [m_obj setDepthStencilState:_depthStencilState];
  373. }
  374. void setFrontFacingWinding(MTLWinding _frontFacingWinding)
  375. {
  376. [m_obj setFrontFacingWinding:_frontFacingWinding];
  377. }
  378. void setRenderPipelineState(id<MTLRenderPipelineState> _pipelineState)
  379. {
  380. [m_obj setRenderPipelineState:_pipelineState];
  381. }
  382. void setScissorRect(MTLScissorRect _rect)
  383. {
  384. [m_obj setScissorRect:_rect];
  385. }
  386. void setStencilReferenceValue(uint32_t _ref)
  387. {
  388. [m_obj setStencilReferenceValue:_ref];
  389. }
  390. void setTriangleFillMode(MTLTriangleFillMode _fillMode)
  391. {
  392. [m_obj setTriangleFillMode:_fillMode];
  393. }
  394. void setViewport(MTLViewport _viewport)
  395. {
  396. [m_obj setViewport:_viewport];
  397. }
  398. void setVisibilityResultMode(MTLVisibilityResultMode _mode, NSUInteger _offset)
  399. {
  400. [m_obj setVisibilityResultMode:_mode offset:_offset];
  401. }
  402. // Specifying Resources for a Vertex Function
  403. void setVertexBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index)
  404. {
  405. [m_obj setVertexBuffer:_buffer offset:_offset atIndex:_index];
  406. }
  407. void setVertexSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index)
  408. {
  409. [m_obj setVertexSamplerState:_sampler atIndex:_index];
  410. }
  411. void setVertexTexture(id<MTLTexture> _texture, NSUInteger _index)
  412. {
  413. [m_obj setVertexTexture:_texture atIndex:_index];
  414. }
  415. // Specifying Resources for a Fragment Function
  416. void setFragmentBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index)
  417. {
  418. [m_obj setFragmentBuffer:_buffer offset:_offset atIndex:_index];
  419. }
  420. void setFragmentSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index)
  421. {
  422. [m_obj setFragmentSamplerState:_sampler atIndex:_index];
  423. }
  424. void setFragmentTexture(id<MTLTexture> _texture, NSUInteger _index)
  425. {
  426. [m_obj setFragmentTexture:_texture atIndex:_index];
  427. }
  428. //Drawing Geometric Primitives
  429. //NOTE: not exposing functions without instanceCount, it seems they are just wrappers
  430. void drawIndexedPrimitives(
  431. MTLPrimitiveType _primitiveType
  432. , NSUInteger _indexCount
  433. , MTLIndexType _indexType
  434. , id<MTLBuffer> _indexBuffer
  435. , NSUInteger _indexBufferOffset
  436. , NSUInteger _instanceCount
  437. )
  438. {
  439. [m_obj drawIndexedPrimitives:_primitiveType indexCount:_indexCount indexType:_indexType indexBuffer:_indexBuffer indexBufferOffset:_indexBufferOffset instanceCount:_instanceCount];
  440. }
  441. void drawPrimitives(
  442. MTLPrimitiveType _primitiveType
  443. , NSUInteger _vertexStart
  444. , NSUInteger _vertexCount
  445. , NSUInteger _instanceCount
  446. )
  447. {
  448. [m_obj drawPrimitives:_primitiveType vertexStart:_vertexStart vertexCount:_vertexCount instanceCount:_instanceCount];
  449. }
  450. void drawPrimitives(
  451. MTLPrimitiveType _primitiveType
  452. , id <MTLBuffer> _indirectBuffer
  453. , NSUInteger _indirectBufferOffset)
  454. {
  455. [m_obj drawPrimitives:_primitiveType indirectBuffer:_indirectBuffer indirectBufferOffset:_indirectBufferOffset];
  456. }
  457. void drawIndexedPrimitives(
  458. MTLPrimitiveType _primitiveType
  459. , MTLIndexType _indexType
  460. , id <MTLBuffer> _indexBuffer
  461. , NSUInteger _indexBufferOffset
  462. , id <MTLBuffer> _indirectBuffer
  463. , NSUInteger _indirectBufferOffset)
  464. {
  465. [m_obj drawIndexedPrimitives:_primitiveType indexType:_indexType indexBuffer:_indexBuffer indexBufferOffset:_indexBufferOffset indirectBuffer:_indirectBuffer indirectBufferOffset:_indirectBufferOffset];
  466. }
  467. void insertDebugSignpost(const char* _string)
  468. {
  469. [m_obj insertDebugSignpost:@(_string)];
  470. }
  471. void pushDebugGroup(const char* _string)
  472. {
  473. [m_obj pushDebugGroup:@(_string)];
  474. }
  475. void popDebugGroup()
  476. {
  477. [m_obj popDebugGroup];
  478. }
  479. void endEncoding()
  480. {
  481. [m_obj endEncoding];
  482. }
  483. MTL_CLASS_END
  484. MTL_CLASS(Texture)
  485. // Copying Data into a Texture Image
  486. void replaceRegion(MTLRegion _region, NSUInteger _level, NSUInteger _slice, const void* _pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage)
  487. {
  488. [m_obj replaceRegion:_region mipmapLevel:_level slice:_slice withBytes:_pixelBytes bytesPerRow:_bytesPerRow bytesPerImage:_bytesPerImage];
  489. }
  490. // Copying Data from a Texture Image
  491. void getBytes(void* _pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage, MTLRegion _region, NSUInteger _mipmapLevel, NSUInteger _slice) const
  492. {
  493. [m_obj getBytes:_pixelBytes bytesPerRow:_bytesPerRow bytesPerImage:_bytesPerImage fromRegion:_region mipmapLevel:_mipmapLevel slice:_slice];
  494. }
  495. // Creating Textures by Reusing Image Data
  496. id<MTLTexture> newTextureViewWithPixelFormat(MTLPixelFormat _pixelFormat)
  497. {
  498. return [m_obj newTextureViewWithPixelFormat:_pixelFormat];
  499. }
  500. id<MTLTexture> newTextureViewWithPixelFormat(MTLPixelFormat _pixelFormat, MTLTextureType _textureType, NSRange _levelRange, NSRange _sliceRange)
  501. {
  502. return [m_obj newTextureViewWithPixelFormat:_pixelFormat textureType:_textureType levels:_levelRange slices:_sliceRange];
  503. }
  504. //properties
  505. uint32_t width() const
  506. {
  507. return (uint32_t)m_obj.width;
  508. }
  509. uint32_t height() const
  510. {
  511. return (uint32_t)m_obj.height;
  512. }
  513. uint32_t arrayLength() const
  514. {
  515. return (uint32_t)m_obj.arrayLength;
  516. }
  517. MTLPixelFormat pixelFormat() const
  518. {
  519. return m_obj.pixelFormat;
  520. }
  521. uint32_t sampleCount() const
  522. {
  523. return (uint32_t)m_obj.sampleCount;
  524. }
  525. MTLTextureType textureType() const
  526. {
  527. return m_obj.textureType;
  528. }
  529. void setLabel(const char* _label)
  530. {
  531. [m_obj setLabel:@(_label)];
  532. }
  533. MTL_CLASS_END
  534. typedef id<MTLComputePipelineState> ComputePipelineState;
  535. typedef id<MTLDepthStencilState> DepthStencilState;
  536. typedef id<MTLRenderPipelineState> RenderPipelineState;
  537. typedef id<MTLSamplerState> SamplerState;
  538. //descriptors
  539. //NOTE: [class new] is same as [[class alloc] init]
  540. typedef MTLRenderPipelineDescriptor* RenderPipelineDescriptor;
  541. typedef MTLComputePipelineReflection* ComputePipelineReflection;
  542. inline RenderPipelineDescriptor newRenderPipelineDescriptor()
  543. {
  544. return [MTLRenderPipelineDescriptor new];
  545. }
  546. inline void reset(RenderPipelineDescriptor _desc)
  547. {
  548. [_desc reset];
  549. }
  550. typedef MTLRenderPipelineColorAttachmentDescriptor* RenderPipelineColorAttachmentDescriptor;
  551. typedef MTLDepthStencilDescriptor* DepthStencilDescriptor;
  552. inline MTLDepthStencilDescriptor* newDepthStencilDescriptor()
  553. {
  554. return [MTLDepthStencilDescriptor new];
  555. }
  556. typedef MTLStencilDescriptor* StencilDescriptor;
  557. inline MTLStencilDescriptor* newStencilDescriptor()
  558. {
  559. return [MTLStencilDescriptor new];
  560. }
  561. typedef MTLRenderPassColorAttachmentDescriptor* RenderPassColorAttachmentDescriptor;
  562. typedef MTLRenderPassDepthAttachmentDescriptor* RenderPassDepthAttachmentDescriptor;
  563. typedef MTLRenderPassStencilAttachmentDescriptor* RenderPassStencilAttachmentDescriptor;
  564. typedef MTLRenderPassDescriptor* RenderPassDescriptor;
  565. inline MTLRenderPassDescriptor* newRenderPassDescriptor()
  566. {
  567. return [MTLRenderPassDescriptor new];
  568. }
  569. typedef MTLVertexDescriptor* VertexDescriptor;
  570. inline MTLVertexDescriptor* newVertexDescriptor()
  571. {
  572. return [MTLVertexDescriptor new];
  573. }
  574. inline void reset(VertexDescriptor _desc)
  575. {
  576. [_desc reset];
  577. }
  578. typedef MTLSamplerDescriptor* SamplerDescriptor;
  579. inline MTLSamplerDescriptor* newSamplerDescriptor()
  580. {
  581. return [MTLSamplerDescriptor new];
  582. }
  583. typedef MTLTextureDescriptor* TextureDescriptor;
  584. inline MTLTextureDescriptor* newTextureDescriptor()
  585. {
  586. return [MTLTextureDescriptor new];
  587. }
  588. typedef MTLRenderPipelineReflection* RenderPipelineReflection;
  589. //helper functions
  590. inline void release(NSObject* _obj)
  591. {
  592. [_obj release];
  593. }
  594. inline void retain(NSObject* _obj)
  595. {
  596. [_obj retain];
  597. }
  598. inline const char* utf8String(NSString* _str)
  599. {
  600. return [_str UTF8String];
  601. }
  602. #define MTL_RELEASE(_obj) \
  603. BX_MACRO_BLOCK_BEGIN \
  604. [_obj release]; \
  605. _obj = nil; \
  606. BX_MACRO_BLOCK_END
  607. // end of c++ wrapper
  608. template <typename Ty>
  609. class StateCacheT
  610. {
  611. public:
  612. void add(uint64_t _id, Ty _item)
  613. {
  614. invalidate(_id);
  615. m_hashMap.insert(stl::make_pair(_id, _item) );
  616. }
  617. Ty find(uint64_t _id)
  618. {
  619. typename HashMap::iterator it = m_hashMap.find(_id);
  620. if (it != m_hashMap.end() )
  621. {
  622. return it->second;
  623. }
  624. return NULL;
  625. }
  626. void invalidate(uint64_t _id)
  627. {
  628. typename HashMap::iterator it = m_hashMap.find(_id);
  629. if (it != m_hashMap.end() )
  630. {
  631. release(it->second);
  632. m_hashMap.erase(it);
  633. }
  634. }
  635. void invalidate()
  636. {
  637. for (typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
  638. {
  639. release(it->second);
  640. }
  641. m_hashMap.clear();
  642. }
  643. uint32_t getCount() const
  644. {
  645. return uint32_t(m_hashMap.size() );
  646. }
  647. private:
  648. typedef stl::unordered_map<uint64_t, Ty> HashMap;
  649. HashMap m_hashMap;
  650. };
  651. struct BufferMtl
  652. {
  653. BufferMtl()
  654. : m_flags(BGFX_BUFFER_NONE)
  655. , m_dynamic(NULL)
  656. {
  657. }
  658. void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false);
  659. void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
  660. void destroy()
  661. {
  662. MTL_RELEASE(m_ptr);
  663. if (NULL != m_dynamic)
  664. {
  665. BX_DELETE(g_allocator, m_dynamic);
  666. m_dynamic = NULL;
  667. }
  668. }
  669. uint32_t m_size;
  670. uint16_t m_flags;
  671. bool m_vertex;
  672. Buffer m_ptr;
  673. uint8_t* m_dynamic;
  674. };
  675. typedef BufferMtl IndexBufferMtl;
  676. struct VertexBufferMtl : public BufferMtl
  677. {
  678. VertexBufferMtl()
  679. : BufferMtl()
  680. {
  681. }
  682. void create(uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags);
  683. VertexLayoutHandle m_layoutHandle;
  684. };
  685. struct ShaderMtl
  686. {
  687. ShaderMtl()
  688. : m_function(NULL)
  689. {
  690. }
  691. void create(const Memory* _mem);
  692. void destroy()
  693. {
  694. MTL_RELEASE(m_function);
  695. }
  696. Function m_function;
  697. uint32_t m_hash;
  698. uint16_t m_numThreads[3];
  699. };
  700. struct PipelineStateMtl;
  701. struct ProgramMtl
  702. {
  703. ProgramMtl()
  704. : m_vsh(NULL)
  705. , m_fsh(NULL)
  706. , m_computePS(NULL)
  707. {
  708. }
  709. void create(const ShaderMtl* _vsh, const ShaderMtl* _fsh);
  710. void destroy();
  711. uint8_t m_used[Attrib::Count+1]; // dense
  712. uint32_t m_attributes[Attrib::Count]; // sparse
  713. uint32_t m_instanceData[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT+1];
  714. const ShaderMtl* m_vsh;
  715. const ShaderMtl* m_fsh;
  716. PipelineStateMtl* m_computePS;
  717. };
  718. struct PipelineStateMtl
  719. {
  720. PipelineStateMtl()
  721. : m_vshConstantBuffer(NULL)
  722. , m_fshConstantBuffer(NULL)
  723. , m_vshConstantBufferSize(0)
  724. , m_vshConstantBufferAlignmentMask(0)
  725. , m_fshConstantBufferSize(0)
  726. , m_fshConstantBufferAlignmentMask(0)
  727. , m_numPredefined(0)
  728. , m_rps(NULL)
  729. , m_cps(NULL)
  730. {
  731. m_numThreads[0] = 1;
  732. m_numThreads[1] = 1;
  733. m_numThreads[2] = 1;
  734. for(uint32_t i=0; i<BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++i)
  735. m_bindingTypes[i] = 0;
  736. }
  737. ~PipelineStateMtl()
  738. {
  739. if (NULL != m_vshConstantBuffer)
  740. {
  741. UniformBuffer::destroy(m_vshConstantBuffer);
  742. m_vshConstantBuffer = NULL;
  743. }
  744. if (NULL != m_fshConstantBuffer)
  745. {
  746. UniformBuffer::destroy(m_fshConstantBuffer);
  747. m_fshConstantBuffer = NULL;
  748. }
  749. release(m_rps);
  750. release(m_cps);
  751. }
  752. UniformBuffer* m_vshConstantBuffer;
  753. UniformBuffer* m_fshConstantBuffer;
  754. uint32_t m_vshConstantBufferSize;
  755. uint32_t m_vshConstantBufferAlignmentMask;
  756. uint32_t m_fshConstantBufferSize;
  757. uint32_t m_fshConstantBufferAlignmentMask;
  758. enum
  759. {
  760. BindToVertexShader = 1 << 0,
  761. BindToFragmentShader = 1 << 1,
  762. };
  763. uint8_t m_bindingTypes[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
  764. uint16_t m_numThreads[3];
  765. PredefinedUniform m_predefined[PredefinedUniform::Count*2];
  766. uint8_t m_numPredefined;
  767. RenderPipelineState m_rps;
  768. ComputePipelineState m_cps;
  769. };
  770. void release(PipelineStateMtl* _ptr)
  771. {
  772. BX_DELETE(g_allocator, _ptr);
  773. }
  774. struct TextureMtl
  775. {
  776. enum Enum
  777. {
  778. Texture2D,
  779. Texture3D,
  780. TextureCube,
  781. };
  782. TextureMtl()
  783. : m_ptr(NULL)
  784. , m_ptrMsaa(NULL)
  785. , m_ptrStencil(NULL)
  786. , m_sampler(NULL)
  787. , m_flags(0)
  788. , m_width(0)
  789. , m_height(0)
  790. , m_depth(0)
  791. , m_numMips(0)
  792. {
  793. for(uint32_t ii = 0; ii < BX_COUNTOF(m_ptrMips); ++ii)
  794. {
  795. m_ptrMips[ii] = NULL;
  796. }
  797. }
  798. void create(const Memory* _mem, uint64_t _flags, uint8_t _skip);
  799. void destroy()
  800. {
  801. MTL_RELEASE(m_ptr);
  802. MTL_RELEASE(m_ptrStencil);
  803. for (uint32_t ii = 0; ii < m_numMips; ++ii)
  804. {
  805. MTL_RELEASE(m_ptrMips[ii]);
  806. }
  807. }
  808. void update(
  809. uint8_t _side
  810. , uint8_t _mip
  811. , const Rect& _rect
  812. , uint16_t _z
  813. , uint16_t _depth
  814. , uint16_t _pitch
  815. , const Memory* _mem
  816. );
  817. void commit(
  818. uint8_t _stage
  819. , bool _vertex
  820. , bool _fragment
  821. , uint32_t _flags = BGFX_SAMPLER_INTERNAL_DEFAULT
  822. );
  823. Texture getTextureMipLevel(int _mip);
  824. Texture m_ptr;
  825. Texture m_ptrMsaa;
  826. Texture m_ptrStencil; // for emulating packed depth/stencil formats - only for iOS8...
  827. Texture m_ptrMips[14];
  828. SamplerState m_sampler;
  829. uint64_t m_flags;
  830. uint32_t m_width;
  831. uint32_t m_height;
  832. uint32_t m_depth;
  833. uint8_t m_type;
  834. uint8_t m_requestedFormat;
  835. uint8_t m_textureFormat;
  836. uint8_t m_numMips;
  837. };
  838. struct FrameBufferMtl;
  839. struct SwapChainMtl
  840. {
  841. SwapChainMtl()
  842. : m_metalLayer(nil)
  843. , m_drawable(nil)
  844. , m_drawableTexture(nil)
  845. , m_backBufferColorMsaa()
  846. , m_backBufferDepth()
  847. , m_backBufferStencil()
  848. , m_maxAnisotropy(0)
  849. {
  850. }
  851. ~SwapChainMtl();
  852. void init(void* _nwh);
  853. void resize(FrameBufferMtl &_frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags);
  854. id <MTLTexture> currentDrawableTexture();
  855. CAMetalLayer* m_metalLayer;
  856. id <CAMetalDrawable> m_drawable;
  857. id <MTLTexture> m_drawableTexture;
  858. Texture m_backBufferColorMsaa;
  859. Texture m_backBufferDepth;
  860. Texture m_backBufferStencil;
  861. uint32_t m_maxAnisotropy;
  862. };
  863. struct FrameBufferMtl
  864. {
  865. FrameBufferMtl()
  866. : m_swapChain(NULL)
  867. , m_nwh(NULL)
  868. , m_denseIdx(UINT16_MAX)
  869. , m_pixelFormatHash(0)
  870. , m_num(0)
  871. {
  872. m_depthHandle.idx = kInvalidHandle;
  873. }
  874. void create(uint8_t _num, const Attachment* _attachment);
  875. void create(
  876. uint16_t _denseIdx
  877. , void* _nwh
  878. , uint32_t _width
  879. , uint32_t _height
  880. , TextureFormat::Enum _format
  881. , TextureFormat::Enum _depthFormat
  882. );
  883. void postReset();
  884. uint16_t destroy();
  885. SwapChainMtl* m_swapChain;
  886. void* m_nwh;
  887. uint32_t m_width;
  888. uint32_t m_height;
  889. uint16_t m_denseIdx;
  890. uint32_t m_pixelFormatHash;
  891. TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
  892. TextureHandle m_depthHandle;
  893. Attachment m_colorAttachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1];
  894. Attachment m_depthAttachment;
  895. uint8_t m_num; // number of color handles
  896. };
  897. struct CommandQueueMtl
  898. {
  899. CommandQueueMtl()
  900. : m_releaseWriteIndex(0)
  901. , m_releaseReadIndex(0)
  902. {
  903. }
  904. void init(Device _device);
  905. void shutdown();
  906. CommandBuffer alloc();
  907. void kick(bool _endFrame, bool _waitForFinish = false);
  908. void finish(bool _finishAll = false);
  909. void release(NSObject* _ptr);
  910. void consume();
  911. bx::Semaphore m_framesSemaphore;
  912. CommandQueue m_commandQueue;
  913. CommandBuffer m_activeCommandBuffer;
  914. int m_releaseWriteIndex;
  915. int m_releaseReadIndex;
  916. typedef stl::vector<NSObject*> ResourceArray;
  917. ResourceArray m_release[MTL_MAX_FRAMES_IN_FLIGHT];
  918. };
  919. struct TimerQueryMtl
  920. {
  921. TimerQueryMtl()
  922. : m_control(4)
  923. {
  924. }
  925. void init();
  926. void shutdown();
  927. uint32_t begin(uint32_t _resultIdx);
  928. void end(uint32_t _idx);
  929. void addHandlers(CommandBuffer& _commandBuffer);
  930. bool get();
  931. struct Result
  932. {
  933. void reset()
  934. {
  935. m_begin = 0;
  936. m_end = 0;
  937. m_pending = 0;
  938. }
  939. uint64_t m_begin;
  940. uint64_t m_end;
  941. uint32_t m_pending;
  942. };
  943. uint64_t m_begin;
  944. uint64_t m_end;
  945. uint64_t m_elapsed;
  946. uint64_t m_frequency;
  947. Result m_result[4*2];
  948. bx::RingBufferControl m_control;
  949. };
  950. struct OcclusionQueryMTL
  951. {
  952. OcclusionQueryMTL()
  953. : m_control(BX_COUNTOF(m_query) )
  954. {
  955. }
  956. void postReset();
  957. void preReset();
  958. void begin(RenderCommandEncoder& _rce, Frame* _render, OcclusionQueryHandle _handle);
  959. void end(RenderCommandEncoder& _rce);
  960. void resolve(Frame* _render, bool _wait = false);
  961. void invalidate(OcclusionQueryHandle _handle);
  962. struct Query
  963. {
  964. OcclusionQueryHandle m_handle;
  965. };
  966. Buffer m_buffer;
  967. Query m_query[BGFX_CONFIG_MAX_OCCLUSION_QUERIES];
  968. bx::RingBufferControl m_control;
  969. };
  970. } /* namespace metal */ } // namespace bgfx
  971. #endif // BGFX_CONFIG_RENDERER_METAL
  972. #endif // BGFX_RENDERER_METAL_H_HEADER_GUARD