GrMtlPipelineStateBuilder.mm 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /*
  2. * Copyright 2018 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/gpu/mtl/GrMtlPipelineStateBuilder.h"
  8. #include "include/gpu/GrContext.h"
  9. #include "src/gpu/GrContextPriv.h"
  10. #include "src/gpu/mtl/GrMtlGpu.h"
  11. #include "src/gpu/mtl/GrMtlPipelineState.h"
  12. #include "src/gpu/mtl/GrMtlUtil.h"
  13. #include "src/gpu/GrRenderTargetPriv.h"
  14. #import <simd/simd.h>
  15. #if !__has_feature(objc_arc)
  16. #error This file must be compiled with Arc. Use -fobjc-arc flag
  17. #endif
  18. GrMtlPipelineState* GrMtlPipelineStateBuilder::CreatePipelineState(
  19. GrMtlGpu* gpu,
  20. GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
  21. const GrPrimitiveProcessor& primProc,
  22. const GrTextureProxy* const primProcProxies[],
  23. const GrPipeline& pipeline,
  24. Desc* desc) {
  25. GrMtlPipelineStateBuilder builder(gpu, renderTarget, origin, pipeline, primProc,
  26. primProcProxies, desc);
  27. if (!builder.emitAndInstallProcs()) {
  28. return nullptr;
  29. }
  30. return builder.finalize(renderTarget, primProc, pipeline, desc);
  31. }
  32. GrMtlPipelineStateBuilder::GrMtlPipelineStateBuilder(GrMtlGpu* gpu,
  33. GrRenderTarget* renderTarget,
  34. GrSurfaceOrigin origin,
  35. const GrPipeline& pipeline,
  36. const GrPrimitiveProcessor& primProc,
  37. const GrTextureProxy* const primProcProxies[],
  38. GrProgramDesc* desc)
  39. : INHERITED(renderTarget, origin, primProc, primProcProxies, pipeline, desc)
  40. , fGpu(gpu)
  41. , fUniformHandler(this)
  42. , fVaryingHandler(this) {
  43. }
  44. const GrCaps* GrMtlPipelineStateBuilder::caps() const {
  45. return fGpu->caps();
  46. }
  47. void GrMtlPipelineStateBuilder::finalizeFragmentOutputColor(GrShaderVar& outputColor) {
  48. outputColor.addLayoutQualifier("location = 0, index = 0");
  49. }
  50. void GrMtlPipelineStateBuilder::finalizeFragmentSecondaryColor(GrShaderVar& outputColor) {
  51. outputColor.addLayoutQualifier("location = 0, index = 1");
  52. }
  53. id<MTLLibrary> GrMtlPipelineStateBuilder::createMtlShaderLibrary(
  54. const GrGLSLShaderBuilder& builder,
  55. SkSL::Program::Kind kind,
  56. const SkSL::Program::Settings& settings,
  57. GrProgramDesc* desc) {
  58. SkSL::Program::Inputs inputs;
  59. id<MTLLibrary> shaderLibrary = GrCompileMtlShaderLibrary(fGpu, builder.fCompilerString.c_str(),
  60. kind, settings, &inputs);
  61. if (shaderLibrary == nil) {
  62. return nil;
  63. }
  64. if (inputs.fRTHeight) {
  65. this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
  66. }
  67. return shaderLibrary;
  68. }
  69. static inline MTLVertexFormat attribute_type_to_mtlformat(GrVertexAttribType type) {
  70. // All half types will actually be float types. We are currently not using half types with
  71. // metal to avoid an issue with narrow type coercions (float->half) http://skbug.com/8221
  72. switch (type) {
  73. case kFloat_GrVertexAttribType:
  74. return MTLVertexFormatFloat;
  75. case kFloat2_GrVertexAttribType:
  76. return MTLVertexFormatFloat2;
  77. case kFloat3_GrVertexAttribType:
  78. return MTLVertexFormatFloat3;
  79. case kFloat4_GrVertexAttribType:
  80. return MTLVertexFormatFloat4;
  81. case kHalf_GrVertexAttribType:
  82. return MTLVertexFormatHalf;
  83. case kHalf2_GrVertexAttribType:
  84. return MTLVertexFormatHalf2;
  85. case kHalf3_GrVertexAttribType:
  86. return MTLVertexFormatHalf3;
  87. case kHalf4_GrVertexAttribType:
  88. return MTLVertexFormatHalf4;
  89. case kInt2_GrVertexAttribType:
  90. return MTLVertexFormatInt2;
  91. case kInt3_GrVertexAttribType:
  92. return MTLVertexFormatInt3;
  93. case kInt4_GrVertexAttribType:
  94. return MTLVertexFormatInt4;
  95. case kByte_GrVertexAttribType:
  96. return MTLVertexFormatChar;
  97. case kByte2_GrVertexAttribType:
  98. return MTLVertexFormatChar2;
  99. case kByte3_GrVertexAttribType:
  100. return MTLVertexFormatChar3;
  101. case kByte4_GrVertexAttribType:
  102. return MTLVertexFormatChar4;
  103. case kUByte_GrVertexAttribType:
  104. return MTLVertexFormatUChar;
  105. case kUByte2_GrVertexAttribType:
  106. return MTLVertexFormatUChar2;
  107. case kUByte3_GrVertexAttribType:
  108. return MTLVertexFormatUChar3;
  109. case kUByte4_GrVertexAttribType:
  110. return MTLVertexFormatUChar4;
  111. case kUByte_norm_GrVertexAttribType:
  112. return MTLVertexFormatUCharNormalized;
  113. case kUByte4_norm_GrVertexAttribType:
  114. return MTLVertexFormatUChar4Normalized;
  115. case kShort2_GrVertexAttribType:
  116. return MTLVertexFormatShort2;
  117. case kShort4_GrVertexAttribType:
  118. return MTLVertexFormatShort4;
  119. case kUShort2_GrVertexAttribType:
  120. return MTLVertexFormatUShort2;
  121. case kUShort2_norm_GrVertexAttribType:
  122. return MTLVertexFormatUShort2Normalized;
  123. case kInt_GrVertexAttribType:
  124. return MTLVertexFormatInt;
  125. case kUint_GrVertexAttribType:
  126. return MTLVertexFormatUInt;
  127. case kUShort_norm_GrVertexAttribType:
  128. return MTLVertexFormatUShortNormalized;
  129. // Experimental (for Y416)
  130. case kUShort4_norm_GrVertexAttribType:
  131. return MTLVertexFormatUShort4Normalized;
  132. }
  133. SK_ABORT("Unknown vertex attribute type");
  134. return MTLVertexFormatInvalid;
  135. }
  136. static MTLVertexDescriptor* create_vertex_descriptor(const GrPrimitiveProcessor& primProc) {
  137. uint32_t vertexBinding = 0, instanceBinding = 0;
  138. int nextBinding = GrMtlUniformHandler::kLastUniformBinding + 1;
  139. if (primProc.hasVertexAttributes()) {
  140. vertexBinding = nextBinding++;
  141. }
  142. if (primProc.hasInstanceAttributes()) {
  143. instanceBinding = nextBinding;
  144. }
  145. auto vertexDescriptor = [[MTLVertexDescriptor alloc] init];
  146. int attributeIndex = 0;
  147. int vertexAttributeCount = primProc.numVertexAttributes();
  148. size_t vertexAttributeOffset = 0;
  149. for (const auto& attribute : primProc.vertexAttributes()) {
  150. MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
  151. mtlAttribute.format = attribute_type_to_mtlformat(attribute.cpuType());
  152. mtlAttribute.offset = vertexAttributeOffset;
  153. mtlAttribute.bufferIndex = vertexBinding;
  154. vertexAttributeOffset += attribute.sizeAlign4();
  155. attributeIndex++;
  156. }
  157. SkASSERT(vertexAttributeOffset == primProc.vertexStride());
  158. if (vertexAttributeCount) {
  159. MTLVertexBufferLayoutDescriptor* vertexBufferLayout =
  160. vertexDescriptor.layouts[vertexBinding];
  161. vertexBufferLayout.stepFunction = MTLVertexStepFunctionPerVertex;
  162. vertexBufferLayout.stepRate = 1;
  163. vertexBufferLayout.stride = vertexAttributeOffset;
  164. }
  165. int instanceAttributeCount = primProc.numInstanceAttributes();
  166. size_t instanceAttributeOffset = 0;
  167. for (const auto& attribute : primProc.instanceAttributes()) {
  168. MTLVertexAttributeDescriptor* mtlAttribute = vertexDescriptor.attributes[attributeIndex];
  169. mtlAttribute.format = attribute_type_to_mtlformat(attribute.cpuType());
  170. mtlAttribute.offset = instanceAttributeOffset;
  171. mtlAttribute.bufferIndex = instanceBinding;
  172. instanceAttributeOffset += attribute.sizeAlign4();
  173. attributeIndex++;
  174. }
  175. SkASSERT(instanceAttributeOffset == primProc.instanceStride());
  176. if (instanceAttributeCount) {
  177. MTLVertexBufferLayoutDescriptor* instanceBufferLayout =
  178. vertexDescriptor.layouts[instanceBinding];
  179. instanceBufferLayout.stepFunction = MTLVertexStepFunctionPerInstance;
  180. instanceBufferLayout.stepRate = 1;
  181. instanceBufferLayout.stride = instanceAttributeOffset;
  182. }
  183. return vertexDescriptor;
  184. }
  185. static MTLBlendFactor blend_coeff_to_mtl_blend(GrBlendCoeff coeff) {
  186. static const MTLBlendFactor gTable[] = {
  187. MTLBlendFactorZero, // kZero_GrBlendCoeff
  188. MTLBlendFactorOne, // kOne_GrBlendCoeff
  189. MTLBlendFactorSourceColor, // kSC_GrBlendCoeff
  190. MTLBlendFactorOneMinusSourceColor, // kISC_GrBlendCoeff
  191. MTLBlendFactorDestinationColor, // kDC_GrBlendCoeff
  192. MTLBlendFactorOneMinusDestinationColor, // kIDC_GrBlendCoeff
  193. MTLBlendFactorSourceAlpha, // kSA_GrBlendCoeff
  194. MTLBlendFactorOneMinusSourceAlpha, // kISA_GrBlendCoeff
  195. MTLBlendFactorDestinationAlpha, // kDA_GrBlendCoeff
  196. MTLBlendFactorOneMinusDestinationAlpha, // kIDA_GrBlendCoeff
  197. MTLBlendFactorBlendColor, // kConstC_GrBlendCoeff
  198. MTLBlendFactorOneMinusBlendColor, // kIConstC_GrBlendCoeff
  199. MTLBlendFactorBlendAlpha, // kConstA_GrBlendCoeff
  200. MTLBlendFactorOneMinusBlendAlpha, // kIConstA_GrBlendCoeff
  201. MTLBlendFactorSource1Color, // kS2C_GrBlendCoeff
  202. MTLBlendFactorOneMinusSource1Color, // kIS2C_GrBlendCoeff
  203. MTLBlendFactorSource1Alpha, // kS2A_GrBlendCoeff
  204. MTLBlendFactorOneMinusSource1Alpha, // kIS2A_GrBlendCoeff
  205. MTLBlendFactorZero, // kIllegal_GrBlendCoeff
  206. };
  207. GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kGrBlendCoeffCnt);
  208. GR_STATIC_ASSERT(0 == kZero_GrBlendCoeff);
  209. GR_STATIC_ASSERT(1 == kOne_GrBlendCoeff);
  210. GR_STATIC_ASSERT(2 == kSC_GrBlendCoeff);
  211. GR_STATIC_ASSERT(3 == kISC_GrBlendCoeff);
  212. GR_STATIC_ASSERT(4 == kDC_GrBlendCoeff);
  213. GR_STATIC_ASSERT(5 == kIDC_GrBlendCoeff);
  214. GR_STATIC_ASSERT(6 == kSA_GrBlendCoeff);
  215. GR_STATIC_ASSERT(7 == kISA_GrBlendCoeff);
  216. GR_STATIC_ASSERT(8 == kDA_GrBlendCoeff);
  217. GR_STATIC_ASSERT(9 == kIDA_GrBlendCoeff);
  218. GR_STATIC_ASSERT(10 == kConstC_GrBlendCoeff);
  219. GR_STATIC_ASSERT(11 == kIConstC_GrBlendCoeff);
  220. GR_STATIC_ASSERT(12 == kConstA_GrBlendCoeff);
  221. GR_STATIC_ASSERT(13 == kIConstA_GrBlendCoeff);
  222. GR_STATIC_ASSERT(14 == kS2C_GrBlendCoeff);
  223. GR_STATIC_ASSERT(15 == kIS2C_GrBlendCoeff);
  224. GR_STATIC_ASSERT(16 == kS2A_GrBlendCoeff);
  225. GR_STATIC_ASSERT(17 == kIS2A_GrBlendCoeff);
  226. SkASSERT((unsigned)coeff < kGrBlendCoeffCnt);
  227. return gTable[coeff];
  228. }
  229. static MTLBlendOperation blend_equation_to_mtl_blend_op(GrBlendEquation equation) {
  230. static const MTLBlendOperation gTable[] = {
  231. MTLBlendOperationAdd, // kAdd_GrBlendEquation
  232. MTLBlendOperationSubtract, // kSubtract_GrBlendEquation
  233. MTLBlendOperationReverseSubtract, // kReverseSubtract_GrBlendEquation
  234. };
  235. GR_STATIC_ASSERT(SK_ARRAY_COUNT(gTable) == kFirstAdvancedGrBlendEquation);
  236. GR_STATIC_ASSERT(0 == kAdd_GrBlendEquation);
  237. GR_STATIC_ASSERT(1 == kSubtract_GrBlendEquation);
  238. GR_STATIC_ASSERT(2 == kReverseSubtract_GrBlendEquation);
  239. SkASSERT((unsigned)equation < kGrBlendEquationCnt);
  240. return gTable[equation];
  241. }
  242. static MTLRenderPipelineColorAttachmentDescriptor* create_color_attachment(
  243. GrPixelConfig config, const GrPipeline& pipeline) {
  244. auto mtlColorAttachment = [[MTLRenderPipelineColorAttachmentDescriptor alloc] init];
  245. // pixel format
  246. MTLPixelFormat format;
  247. SkAssertResult(GrPixelConfigToMTLFormat(config, &format));
  248. mtlColorAttachment.pixelFormat = format;
  249. // blending
  250. const GrXferProcessor::BlendInfo& blendInfo = pipeline.getXferProcessor().getBlendInfo();
  251. GrBlendEquation equation = blendInfo.fEquation;
  252. GrBlendCoeff srcCoeff = blendInfo.fSrcBlend;
  253. GrBlendCoeff dstCoeff = blendInfo.fDstBlend;
  254. bool blendOff = (kAdd_GrBlendEquation == equation || kSubtract_GrBlendEquation == equation) &&
  255. kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff;
  256. mtlColorAttachment.blendingEnabled = !blendOff;
  257. if (!blendOff) {
  258. mtlColorAttachment.sourceRGBBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
  259. mtlColorAttachment.destinationRGBBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
  260. mtlColorAttachment.rgbBlendOperation = blend_equation_to_mtl_blend_op(equation);
  261. mtlColorAttachment.sourceAlphaBlendFactor = blend_coeff_to_mtl_blend(srcCoeff);
  262. mtlColorAttachment.destinationAlphaBlendFactor = blend_coeff_to_mtl_blend(dstCoeff);
  263. mtlColorAttachment.alphaBlendOperation = blend_equation_to_mtl_blend_op(equation);
  264. }
  265. if (!blendInfo.fWriteColor) {
  266. mtlColorAttachment.writeMask = MTLColorWriteMaskNone;
  267. } else {
  268. mtlColorAttachment.writeMask = MTLColorWriteMaskAll;
  269. }
  270. return mtlColorAttachment;
  271. }
  272. uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment) {
  273. // Metal expects the buffer to be padded at the end according to the alignment
  274. // of the largest element in the buffer.
  275. uint32_t offsetDiff = offset & maxAlignment;
  276. if (offsetDiff != 0) {
  277. offsetDiff = maxAlignment - offsetDiff + 1;
  278. }
  279. return offset + offsetDiff;
  280. }
  281. GrMtlPipelineState* GrMtlPipelineStateBuilder::finalize(GrRenderTarget* renderTarget,
  282. const GrPrimitiveProcessor& primProc,
  283. const GrPipeline& pipeline,
  284. Desc* desc) {
  285. auto pipelineDescriptor = [MTLRenderPipelineDescriptor new];
  286. fVS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
  287. fFS.extensions().appendf("#extension GL_ARB_separate_shader_objects : enable\n");
  288. fVS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
  289. fFS.extensions().appendf("#extension GL_ARB_shading_language_420pack : enable\n");
  290. this->finalizeShaders();
  291. SkSL::Program::Settings settings;
  292. settings.fCaps = this->caps()->shaderCaps();
  293. settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin;
  294. settings.fSharpenTextures = fGpu->getContext()->priv().options().fSharpenMipmappedTextures;
  295. SkASSERT(!this->fragColorIsInOut());
  296. // TODO: Store shaders in cache
  297. id<MTLLibrary> vertexLibrary = nil;
  298. id<MTLLibrary> fragmentLibrary = nil;
  299. vertexLibrary = this->createMtlShaderLibrary(fVS,
  300. SkSL::Program::kVertex_Kind,
  301. settings,
  302. desc);
  303. fragmentLibrary = this->createMtlShaderLibrary(fFS,
  304. SkSL::Program::kFragment_Kind,
  305. settings,
  306. desc);
  307. SkASSERT(!this->primitiveProcessor().willUseGeoShader());
  308. if (!vertexLibrary || !fragmentLibrary) {
  309. return nullptr;
  310. }
  311. id<MTLFunction> vertexFunction = [vertexLibrary newFunctionWithName: @"vertexMain"];
  312. id<MTLFunction> fragmentFunction = [fragmentLibrary newFunctionWithName: @"fragmentMain"];
  313. if (vertexFunction == nil) {
  314. SkDebugf("Couldn't find vertexMain() in library\n");
  315. return nullptr;
  316. }
  317. if (fragmentFunction == nil) {
  318. SkDebugf("Couldn't find fragmentMain() in library\n");
  319. return nullptr;
  320. }
  321. pipelineDescriptor.vertexFunction = vertexFunction;
  322. pipelineDescriptor.fragmentFunction = fragmentFunction;
  323. pipelineDescriptor.vertexDescriptor = create_vertex_descriptor(primProc);
  324. pipelineDescriptor.colorAttachments[0] = create_color_attachment(this->config(), pipeline);
  325. pipelineDescriptor.sampleCount = renderTarget->numSamples();
  326. bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
  327. GrMtlCaps* mtlCaps = (GrMtlCaps*)this->caps();
  328. pipelineDescriptor.stencilAttachmentPixelFormat =
  329. hasStencilAttachment ? mtlCaps->preferredStencilFormat().fInternalFormat
  330. : MTLPixelFormatInvalid;
  331. SkASSERT(pipelineDescriptor.vertexFunction);
  332. SkASSERT(pipelineDescriptor.fragmentFunction);
  333. SkASSERT(pipelineDescriptor.vertexDescriptor);
  334. SkASSERT(pipelineDescriptor.colorAttachments[0]);
  335. #if defined(SK_BUILD_FOR_MAC) && defined(GR_USE_COMPLETION_HANDLER)
  336. bool timedout;
  337. id<MTLRenderPipelineState> pipelineState = GrMtlNewRenderPipelineStateWithDescriptor(
  338. fGpu->device(), pipelineDescriptor, &timedout);
  339. if (timedout) {
  340. // try a second time
  341. pipelineState = GrMtlNewRenderPipelineStateWithDescriptor(
  342. fGpu->device(), pipelineDescriptor, &timedout);
  343. }
  344. if (!pipelineState) {
  345. return nullptr;
  346. }
  347. #else
  348. NSError* error = nil;
  349. id<MTLRenderPipelineState> pipelineState =
  350. [fGpu->device() newRenderPipelineStateWithDescriptor: pipelineDescriptor
  351. error: &error];
  352. if (error) {
  353. SkDebugf("Error creating pipeline: %s\n",
  354. [[error localizedDescription] cStringUsingEncoding: NSASCIIStringEncoding]);
  355. return nullptr;
  356. }
  357. #endif
  358. uint32_t geomBufferSize = buffer_size(fUniformHandler.fCurrentGeometryUBOOffset,
  359. fUniformHandler.fCurrentGeometryUBOMaxAlignment);
  360. uint32_t fragBufferSize = buffer_size(fUniformHandler.fCurrentFragmentUBOOffset,
  361. fUniformHandler.fCurrentFragmentUBOMaxAlignment);
  362. return new GrMtlPipelineState(fGpu,
  363. pipelineState,
  364. pipelineDescriptor.colorAttachments[0].pixelFormat,
  365. fUniformHandles,
  366. fUniformHandler.fUniforms,
  367. geomBufferSize,
  368. fragBufferSize,
  369. (uint32_t)fUniformHandler.numSamplers(),
  370. std::move(fGeometryProcessor),
  371. std::move(fXferProcessor),
  372. std::move(fFragmentProcessors),
  373. fFragmentProcessorCnt);
  374. }
  375. //////////////////////////////////////////////////////////////////////////////
  376. bool GrMtlPipelineStateBuilder::Desc::Build(Desc* desc,
  377. GrRenderTarget* renderTarget,
  378. const GrPrimitiveProcessor& primProc,
  379. const GrPipeline& pipeline,
  380. GrPrimitiveType primitiveType,
  381. GrMtlGpu* gpu) {
  382. if (!INHERITED::Build(desc, renderTarget, primProc,
  383. GrPrimitiveType::kLines == primitiveType, pipeline, gpu)) {
  384. return false;
  385. }
  386. GrProcessorKeyBuilder b(&desc->key());
  387. int keyLength = desc->key().count();
  388. SkASSERT(0 == (keyLength % 4));
  389. desc->fShaderKeyLength = SkToU32(keyLength);
  390. b.add32(renderTarget->config());
  391. b.add32(renderTarget->numSamples());
  392. bool hasStencilAttachment = SkToBool(renderTarget->renderTargetPriv().getStencilAttachment());
  393. b.add32(hasStencilAttachment ? gpu->mtlCaps().preferredStencilFormat().fInternalFormat
  394. : MTLPixelFormatInvalid);
  395. b.add32((uint32_t)pipeline.isStencilEnabled());
  396. // Stencil samples don't seem to be tracked in the MTLRenderPipeline
  397. b.add32(pipeline.getBlendInfoKey());
  398. b.add32((uint32_t)primitiveType);
  399. return true;
  400. }