1 // 2 // Copyright 2019 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // mtl_render_utils.h: 7 // Defines the class interface for RenderUtils, which contains many utility functions and shaders 8 // for converting, blitting, copying as well as generating data, and many more. 9 // 10 11 #ifndef LIBANGLE_RENDERER_METAL_MTL_RENDER_UTILS_H_ 12 #define LIBANGLE_RENDERER_METAL_MTL_RENDER_UTILS_H_ 13 14 #import <Metal/Metal.h> 15 16 #include "libANGLE/angletypes.h" 17 #include "libANGLE/renderer/metal/RenderTargetMtl.h" 18 #include "libANGLE/renderer/metal/mtl_command_buffer.h" 19 #include "libANGLE/renderer/metal/mtl_context_device.h" 20 #include "libANGLE/renderer/metal/mtl_state_cache.h" 21 #include "libANGLE/renderer/metal/shaders/constants.h" 22 23 namespace rx 24 { 25 26 class BufferMtl; 27 class ContextMtl; 28 class DisplayMtl; 29 class VisibilityBufferOffsetsMtl; 30 31 namespace mtl 32 { 33 34 struct ClearRectParams 35 { ClearRectParamsClearRectParams36 ClearRectParams() { clearWriteMaskArray.fill(MTLColorWriteMaskAll); } 37 38 Optional<ClearColorValue> clearColor; 39 Optional<float> clearDepth; 40 Optional<uint32_t> clearStencil; 41 42 WriteMaskArray clearWriteMaskArray; 43 44 const mtl::Format *colorFormat = nullptr; 45 gl::Extents dstTextureSize; 46 47 // Only clear enabled buffers 48 gl::DrawBufferMask enabledBuffers; 49 gl::Rectangle clearArea; 50 51 bool flipY = false; 52 }; 53 54 struct NormalizedCoords 55 { 56 NormalizedCoords(); 57 NormalizedCoords(float x, float y, float width, float height, const gl::Rectangle &rect); 58 NormalizedCoords(const gl::Rectangle &rect, const gl::Extents &extents); 59 float v[4]; 60 }; 61 62 struct BlitParams 63 { 64 gl::Extents dstTextureSize; 65 gl::Rectangle dstRect; 66 gl::Rectangle dstScissorRect; 67 // Destination texture needs to have viewport Y flipped? 68 // The difference between this param and unpackFlipY is that unpackFlipY is from 69 // glCopyImageCHROMIUM()/glBlitFramebuffer(), and dstFlipY controls whether the final viewport 70 // needs to be flipped when drawing to destination texture. It is possible to combine the two 71 // flags before passing to RenderUtils. However, to avoid duplicated works, just pass the two 72 // flags to RenderUtils, they will be combined internally by RenderUtils logic. 73 bool dstFlipY = false; 74 bool dstFlipX = false; 75 76 TextureRef src; 77 MipmapNativeLevel srcLevel = kZeroNativeMipLevel; 78 uint32_t srcLayer = 0; 79 80 // Source rectangle: 81 // NOTE: if srcYFlipped=true, this rectangle will be converted internally to flipped rect before 82 // blitting. 83 NormalizedCoords srcNormalizedCoords; 84 85 bool srcYFlipped = false; // source texture has data flipped in Y direction 86 bool unpackFlipX = false; // flip texture data copying process in X direction 87 bool unpackFlipY = false; // flip texture data copying process in Y direction 88 }; 89 90 struct ColorBlitParams : public BlitParams 91 { ColorBlitParamsColorBlitParams92 ColorBlitParams() {} 93 94 gl::DrawBufferMask enabledBuffers; 95 GLenum filter = GL_NEAREST; 96 bool unpackPremultiplyAlpha = false; 97 bool unpackUnmultiplyAlpha = false; 98 bool dstLuminance = false; 99 }; 100 101 struct DepthStencilBlitParams : public BlitParams 102 { 103 TextureRef srcStencil; 104 }; 105 106 // Stencil blit via an intermediate buffer. NOTE: source depth texture parameter is ignored. 107 // See DepthStencilBlitUtils::blitStencilViaCopyBuffer() 108 struct StencilBlitViaBufferParams : public DepthStencilBlitParams 109 { 110 StencilBlitViaBufferParams(); 111 StencilBlitViaBufferParams(const DepthStencilBlitParams &src); 112 113 TextureRef dstStencil; 114 MipmapNativeLevel dstStencilLevel = kZeroNativeMipLevel; 115 uint32_t dstStencilLayer = 0; 116 bool dstPackedDepthStencilFormat = false; 117 }; 118 119 struct TriFanOrLineLoopFromArrayParams 120 { 121 uint32_t firstVertex; 122 uint32_t vertexCount; 123 BufferRef dstBuffer; 124 // Must be multiples of kIndexBufferOffsetAlignment 125 uint32_t dstOffset; 126 }; 127 128 struct IndexConversionParams 129 { 130 131 gl::DrawElementsType srcType; 132 uint32_t indexCount; 133 const BufferRef &srcBuffer; 134 uint32_t srcOffset; 135 const BufferRef &dstBuffer; 136 // Must be multiples of kIndexBufferOffsetAlignment 137 uint32_t dstOffset; 138 bool primitiveRestartEnabled = false; 139 }; 140 141 struct IndexGenerationParams 142 { 143 gl::DrawElementsType srcType; 144 GLsizei indexCount; 145 const void *indices; 146 BufferRef dstBuffer; 147 uint32_t dstOffset; 148 bool primitiveRestartEnabled = false; 149 }; 150 151 struct CopyPixelsCommonParams 152 { 153 BufferRef buffer; 154 uint32_t bufferStartOffset = 0; 155 uint32_t bufferRowPitch = 0; 156 157 TextureRef texture; 158 }; 159 160 struct CopyPixelsFromBufferParams : CopyPixelsCommonParams 161 { 162 uint32_t bufferDepthPitch = 0; 163 164 // z offset is: 165 // - slice index if texture is array. 166 // - depth if texture is 3d. 167 gl::Box textureArea; 168 }; 169 170 struct CopyPixelsToBufferParams : CopyPixelsCommonParams 171 { 172 gl::Rectangle textureArea; 173 MipmapNativeLevel textureLevel = kZeroNativeMipLevel; 174 uint32_t textureSliceOrDeph = 0; 175 bool reverseTextureRowOrder; 176 }; 177 178 struct VertexFormatConvertParams 179 { 180 BufferRef srcBuffer; 181 uint32_t srcBufferStartOffset = 0; 182 uint32_t srcStride = 0; 183 uint32_t srcDefaultAlphaData = 0; // casted as uint 184 185 BufferRef dstBuffer; 186 uint32_t dstBufferStartOffset = 0; 187 uint32_t dstStride = 0; 188 uint32_t dstComponents = 0; 189 190 uint32_t vertexCount = 0; 191 }; 192 193 // Utils class for clear & blitting 194 class ClearUtils final : angle::NonCopyable 195 { 196 public: 197 ClearUtils() = delete; 198 ClearUtils(const std::string &fragmentShaderName); 199 200 // Clear current framebuffer 201 angle::Result clearWithDraw(const gl::Context *context, 202 RenderCommandEncoder *cmdEncoder, 203 const ClearRectParams ¶ms); 204 205 private: 206 angle::Result ensureShadersInitialized(ContextMtl *ctx, uint32_t numColorAttachments); 207 208 angle::Result setupClearWithDraw(const gl::Context *context, 209 RenderCommandEncoder *cmdEncoder, 210 const ClearRectParams ¶ms); 211 id<MTLDepthStencilState> getClearDepthStencilState(const gl::Context *context, 212 const ClearRectParams ¶ms); 213 angle::Result getClearRenderPipelineState( 214 const gl::Context *context, 215 RenderCommandEncoder *cmdEncoder, 216 const ClearRectParams ¶ms, 217 AutoObjCPtr<id<MTLRenderPipelineState>> *outPipelineState); 218 219 const std::string mFragmentShaderName; 220 221 AutoObjCPtr<id<MTLFunction>> mVertexShader; 222 std::array<AutoObjCPtr<id<MTLFunction>>, kMaxRenderTargets + 1> mFragmentShaders; 223 }; 224 225 class ColorBlitUtils final : angle::NonCopyable 226 { 227 public: 228 ColorBlitUtils() = delete; 229 ColorBlitUtils(const std::string &fragmentShaderName); 230 231 // Blit texture data to current framebuffer 232 angle::Result blitColorWithDraw(const gl::Context *context, 233 RenderCommandEncoder *cmdEncoder, 234 const ColorBlitParams ¶ms); 235 236 private: 237 angle::Result ensureShadersInitialized(ContextMtl *ctx, 238 uint32_t numColorAttachments, 239 int alphaPremultiplyType, 240 int sourceTextureType, 241 AutoObjCPtr<id<MTLFunction>> *fragmentShaderOut); 242 243 angle::Result setupColorBlitWithDraw(const gl::Context *context, 244 RenderCommandEncoder *cmdEncoder, 245 const ColorBlitParams ¶ms); 246 247 angle::Result getColorBlitRenderPipelineState( 248 const gl::Context *context, 249 RenderCommandEncoder *cmdEncoder, 250 const ColorBlitParams ¶ms, 251 AutoObjCPtr<id<MTLRenderPipelineState>> *outPipelineState); 252 253 const std::string mFragmentShaderName; 254 255 AutoObjCPtr<id<MTLFunction>> mVertexShader; 256 257 // Blit fragment shaders: 258 // First array dimension: number of outputs. 259 // Second array dimension: source texture type (2d, ms, array, 3d, etc) 260 using ColorBlitFragmentShaderArray = 261 std::array<std::array<AutoObjCPtr<id<MTLFunction>>, mtl_shader::kTextureTypeCount>, 262 kMaxRenderTargets>; 263 ColorBlitFragmentShaderArray mBlitFragmentShaders; 264 ColorBlitFragmentShaderArray mBlitPremultiplyAlphaFragmentShaders; 265 ColorBlitFragmentShaderArray mBlitUnmultiplyAlphaFragmentShaders; 266 }; 267 268 class DepthStencilBlitUtils final : angle::NonCopyable 269 { 270 public: 271 angle::Result blitDepthStencilWithDraw(const gl::Context *context, 272 RenderCommandEncoder *cmdEncoder, 273 const DepthStencilBlitParams ¶ms); 274 275 // Blit stencil data using intermediate buffer. This function is used on devices with no 276 // support for direct stencil write in shader. Thus an intermediate buffer storing copied 277 // stencil data is needed. 278 // NOTE: this function shares the params struct with depth & stencil blit, but depth texture 279 // parameter is not used. This function will break existing render pass. 280 angle::Result blitStencilViaCopyBuffer(const gl::Context *context, 281 const StencilBlitViaBufferParams ¶ms); 282 283 private: 284 angle::Result ensureShadersInitialized(ContextMtl *ctx, 285 int sourceDepthTextureType, 286 int sourceStencilTextureType, 287 AutoObjCPtr<id<MTLFunction>> *fragmentShaderOut); 288 289 angle::Result setupDepthStencilBlitWithDraw(const gl::Context *context, 290 RenderCommandEncoder *cmdEncoder, 291 const DepthStencilBlitParams ¶ms); 292 293 angle::Result getDepthStencilBlitRenderPipelineState( 294 const gl::Context *context, 295 RenderCommandEncoder *cmdEncoder, 296 const DepthStencilBlitParams ¶ms, 297 AutoObjCPtr<id<MTLRenderPipelineState>> *outRenderPipelineState); 298 299 angle::Result getStencilToBufferComputePipelineState( 300 ContextMtl *ctx, 301 const StencilBlitViaBufferParams ¶ms, 302 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipelineState); 303 304 AutoObjCPtr<id<MTLFunction>> mVertexShader; 305 306 std::array<AutoObjCPtr<id<MTLFunction>>, mtl_shader::kTextureTypeCount> 307 mDepthBlitFragmentShaders; 308 std::array<AutoObjCPtr<id<MTLFunction>>, mtl_shader::kTextureTypeCount> 309 mStencilBlitFragmentShaders; 310 std::array<std::array<AutoObjCPtr<id<MTLFunction>>, mtl_shader::kTextureTypeCount>, 311 mtl_shader::kTextureTypeCount> 312 mDepthStencilBlitFragmentShaders; 313 314 std::array<AutoObjCPtr<id<MTLFunction>>, mtl_shader::kTextureTypeCount> 315 mStencilBlitToBufferComputeShaders; 316 317 // Intermediate buffer for storing copied stencil data. Used when device doesn't support 318 // writing stencil in shader. 319 BufferRef mStencilCopyBuffer; 320 }; 321 322 // util class for generating index buffer 323 class IndexGeneratorUtils final : angle::NonCopyable 324 { 325 public: 326 angle::Result convertIndexBufferGPU(ContextMtl *contextMtl, 327 const IndexConversionParams ¶ms); 328 angle::Result generateTriFanBufferFromArrays(ContextMtl *contextMtl, 329 const TriFanOrLineLoopFromArrayParams ¶ms); 330 // Generate triangle fan index buffer for glDrawElements(). 331 angle::Result generateTriFanBufferFromElementsArray(ContextMtl *contextMtl, 332 const IndexGenerationParams ¶ms, 333 uint32_t *indicesGenerated); 334 335 angle::Result generateLineLoopBufferFromArrays(ContextMtl *contextMtl, 336 const TriFanOrLineLoopFromArrayParams ¶ms); 337 angle::Result generateLineLoopLastSegment(ContextMtl *contextMtl, 338 uint32_t firstVertex, 339 uint32_t lastVertex, 340 const BufferRef &dstBuffer, 341 uint32_t dstOffset); 342 // Generate line loop index buffer for glDrawElements(). 343 // Destination buffer must have at least 2x the number of original indices if primitive restart 344 // is enabled. 345 angle::Result generateLineLoopBufferFromElementsArray(ContextMtl *contextMtl, 346 const IndexGenerationParams ¶ms, 347 uint32_t *indicesGenerated); 348 // Generate line loop's last segment index buffer for glDrawElements(). 349 // NOTE: this function assumes primitive restart is not enabled. 350 angle::Result generateLineLoopLastSegmentFromElementsArray(ContextMtl *contextMtl, 351 const IndexGenerationParams ¶ms); 352 353 angle::Result generatePrimitiveRestartPointsBuffer(ContextMtl *contextMtl, 354 const IndexGenerationParams ¶ms, 355 size_t *indicesGenerated); 356 357 angle::Result generatePrimitiveRestartLinesBuffer(ContextMtl *contextMtl, 358 const IndexGenerationParams ¶ms, 359 size_t *indicesGenerated); 360 361 angle::Result generatePrimitiveRestartTrianglesBuffer(ContextMtl *contextMtl, 362 const IndexGenerationParams ¶ms, 363 size_t *indicesGenerated); 364 365 private: 366 // Index generator compute shaders: 367 // - First dimension: index type. 368 // - second dimension: source buffer's offset is aligned or not. 369 using IndexConversionShaderArray = std::array<std::array<AutoObjCPtr<id<MTLFunction>>, 2>, 370 angle::EnumSize<gl::DrawElementsType>()>; 371 372 angle::Result getIndexConversionPipeline( 373 ContextMtl *contextMtl, 374 gl::DrawElementsType srcType, 375 uint32_t srcOffset, 376 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 377 // Get compute pipeline to generate tri fan/line loop index for glDrawElements(). 378 angle::Result getIndicesFromElemArrayGeneratorPipeline( 379 ContextMtl *contextMtl, 380 gl::DrawElementsType srcType, 381 uint32_t srcOffset, 382 NSString *shaderName, 383 IndexConversionShaderArray *pipelineCacheArray, 384 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 385 // Defer loading of compute pipeline to generate tri fan index for glDrawArrays(). 386 angle::Result getTriFanFromArrayGeneratorPipeline( 387 ContextMtl *contextMtl, 388 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 389 // Defer loading of compute pipeline to generate line loop index for glDrawArrays(). 390 angle::Result getLineLoopFromArrayGeneratorPipeline( 391 ContextMtl *contextMtl, 392 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 393 394 angle::Result generateTriFanBufferFromElementsArrayGPU( 395 ContextMtl *contextMtl, 396 gl::DrawElementsType srcType, 397 uint32_t indexCount, 398 const BufferRef &srcBuffer, 399 uint32_t srcOffset, 400 const BufferRef &dstBuffer, 401 // Must be multiples of kIndexBufferOffsetAlignment 402 uint32_t dstOffset); 403 angle::Result generateTriFanBufferFromElementsArrayCPU(ContextMtl *contextMtl, 404 const IndexGenerationParams ¶ms, 405 uint32_t *indicesGenerated); 406 407 angle::Result generateLineLoopBufferFromElementsArrayGPU( 408 ContextMtl *contextMtl, 409 gl::DrawElementsType srcType, 410 uint32_t indexCount, 411 const BufferRef &srcBuffer, 412 uint32_t srcOffset, 413 const BufferRef &dstBuffer, 414 // Must be multiples of kIndexBufferOffsetAlignment 415 uint32_t dstOffset); 416 angle::Result generateLineLoopBufferFromElementsArrayCPU(ContextMtl *contextMtl, 417 const IndexGenerationParams ¶ms, 418 uint32_t *indicesGenerated); 419 angle::Result generateLineLoopLastSegmentFromElementsArrayCPU( 420 ContextMtl *contextMtl, 421 const IndexGenerationParams ¶ms); 422 423 angle::Result generatePrimitiveRestartBuffer(ContextMtl *contextMtl, 424 unsigned numVerticesPerPrimitive, 425 const IndexGenerationParams ¶ms, 426 size_t *indicesGenerated); 427 428 IndexConversionShaderArray mIndexConversionShaders; 429 430 IndexConversionShaderArray mTriFanFromElemArrayGeneratorShaders; 431 AutoObjCPtr<id<MTLFunction>> mTriFanFromArraysGeneratorShader; 432 433 IndexConversionShaderArray mLineLoopFromElemArrayGeneratorShaders; 434 AutoObjCPtr<id<MTLFunction>> mLineLoopFromArraysGeneratorShader; 435 }; 436 437 // Util class for handling visibility query result 438 class VisibilityResultUtils final : angle::NonCopyable 439 { 440 public: 441 angle::Result combineVisibilityResult( 442 ContextMtl *contextMtl, 443 bool keepOldValue, 444 const VisibilityBufferOffsetsMtl &renderPassResultBufOffsets, 445 const BufferRef &renderPassResultBuf, 446 const BufferRef &finalResultBuf); 447 448 private: 449 angle::Result getVisibilityResultCombinePipeline( 450 ContextMtl *contextMtl, 451 bool keepOldValue, 452 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 453 // Visibility combination compute shaders: 454 // - 0: This compute shader only combines the new values and discard old value. 455 // - 1: This compute shader keep the old value and combines with new values. 456 std::array<AutoObjCPtr<id<MTLFunction>>, 2> mVisibilityResultCombineComputeShaders; 457 }; 458 459 // Util class for handling mipmap generation 460 class MipmapUtils final : angle::NonCopyable 461 { 462 public: 463 // Compute based mipmap generation. 464 angle::Result generateMipmapCS(ContextMtl *contextMtl, 465 const TextureRef &srcTexture, 466 bool sRGBMipmap, 467 NativeTexLevelArray *mipmapOutputViews); 468 469 private: 470 angle::Result get3DMipGeneratorPipeline( 471 ContextMtl *contextMtl, 472 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 473 angle::Result get2DMipGeneratorPipeline( 474 ContextMtl *contextMtl, 475 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 476 angle::Result get2DArrayMipGeneratorPipeline( 477 ContextMtl *contextMtl, 478 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 479 angle::Result getCubeMipGeneratorPipeline( 480 ContextMtl *contextMtl, 481 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 482 483 // Mipmaps generating compute pipeline: 484 AutoObjCPtr<id<MTLFunction>> m3DMipGeneratorShader; 485 AutoObjCPtr<id<MTLFunction>> m2DMipGeneratorShader; 486 AutoObjCPtr<id<MTLFunction>> m2DArrayMipGeneratorShader; 487 AutoObjCPtr<id<MTLFunction>> mCubeMipGeneratorShader; 488 }; 489 490 // Util class for handling pixels copy between buffers and textures 491 class CopyPixelsUtils final : angle::NonCopyable 492 { 493 public: 494 CopyPixelsUtils() = default; 495 CopyPixelsUtils(const std::string &readShaderName, const std::string &writeShaderName); 496 497 angle::Result unpackPixelsFromBufferToTexture(ContextMtl *contextMtl, 498 const angle::Format &srcAngleFormat, 499 const CopyPixelsFromBufferParams ¶ms); 500 angle::Result packPixelsFromTextureToBuffer(ContextMtl *contextMtl, 501 const angle::Format &dstAngleFormat, 502 const CopyPixelsToBufferParams ¶ms); 503 504 private: 505 angle::Result getPixelsCopyPipeline( 506 ContextMtl *contextMtl, 507 const angle::Format &angleFormat, 508 const TextureRef &texture, 509 bool bufferWrite, 510 AutoObjCPtr<id<MTLComputePipelineState>> *outComputePipeline); 511 // Copy pixels between buffer and texture compute pipelines: 512 // - First dimension: pixel format. 513 // - Second dimension: texture type * (buffer read/write flag) 514 using PixelsCopyComputeShaderArray = 515 std::array<std::array<AutoObjCPtr<id<MTLFunction>>, mtl_shader::kTextureTypeCount * 2>, 516 angle::kNumANGLEFormats>; 517 PixelsCopyComputeShaderArray mPixelsCopyComputeShaders; 518 519 const std::string mReadShaderName; 520 const std::string mWriteShaderName; 521 }; 522 523 // Util class for handling vertex format conversion on GPU 524 class VertexFormatConversionUtils final : angle::NonCopyable 525 { 526 public: 527 // Convert vertex format to float. Compute shader version. 528 angle::Result convertVertexFormatToFloatCS(ContextMtl *contextMtl, 529 const angle::Format &srcAngleFormat, 530 const VertexFormatConvertParams ¶ms); 531 // Convert vertex format to float. Vertex shader version. This version should be used if 532 // a render pass is active and we don't want to break it. Explicit memory barrier must be 533 // supported. 534 angle::Result convertVertexFormatToFloatVS(const gl::Context *context, 535 RenderCommandEncoder *renderEncoder, 536 const angle::Format &srcAngleFormat, 537 const VertexFormatConvertParams ¶ms); 538 // Expand number of components per vertex's attribute (or just simply copy components between 539 // buffers with different stride and offset) 540 angle::Result expandVertexFormatComponentsCS(ContextMtl *contextMtl, 541 const angle::Format &srcAngleFormat, 542 const VertexFormatConvertParams ¶ms); 543 angle::Result expandVertexFormatComponentsVS(const gl::Context *context, 544 RenderCommandEncoder *renderEncoder, 545 const angle::Format &srcAngleFormat, 546 const VertexFormatConvertParams ¶ms); 547 548 private: 549 angle::Result getComponentsExpandComputePipeline( 550 ContextMtl *contextMtl, 551 AutoObjCPtr<id<MTLComputePipelineState>> *outPipelineState); 552 angle::Result getComponentsExpandRenderPipeline( 553 ContextMtl *contextMtl, 554 RenderCommandEncoder *renderEncoder, 555 AutoObjCPtr<id<MTLRenderPipelineState>> *outPipelineState); 556 557 angle::Result getFloatConverstionComputePipeline( 558 ContextMtl *contextMtl, 559 const angle::Format &srcAngleFormat, 560 AutoObjCPtr<id<MTLComputePipelineState>> *outPipelineState); 561 562 angle::Result getFloatConverstionRenderPipeline( 563 ContextMtl *contextMtl, 564 RenderCommandEncoder *renderEncoder, 565 const angle::Format &srcAngleFormat, 566 AutoObjCPtr<id<MTLRenderPipelineState>> *outPipelineState); 567 568 template <typename EncoderType, typename PipelineType> 569 angle::Result setupCommonConvertVertexFormatToFloat(ContextMtl *contextMtl, 570 EncoderType cmdEncoder, 571 const PipelineType &pipeline, 572 const angle::Format &srcAngleFormat, 573 const VertexFormatConvertParams ¶ms); 574 template <typename EncoderType, typename PipelineType> 575 angle::Result setupCommonExpandVertexFormatComponents(ContextMtl *contextMtl, 576 EncoderType cmdEncoder, 577 const PipelineType &pipeline, 578 const angle::Format &srcAngleFormat, 579 const VertexFormatConvertParams ¶ms); 580 581 using ConvertToFloatComputeShaderArray = 582 std::array<AutoObjCPtr<id<MTLFunction>>, angle::kNumANGLEFormats>; 583 using ConvertToFloatVertexShaderArray = 584 std::array<AutoObjCPtr<id<MTLFunction>>, angle::kNumANGLEFormats>; 585 586 ConvertToFloatComputeShaderArray mConvertToFloatCompPipelineCaches; 587 ConvertToFloatVertexShaderArray mConvertToFloatVertexShaders; 588 589 AutoObjCPtr<id<MTLFunction>> mComponentsExpandComputeShader; 590 AutoObjCPtr<id<MTLFunction>> mComponentsExpandVertexShader; 591 }; 592 593 // RenderUtils: container class of various util classes above 594 class RenderUtils : public Context, angle::NonCopyable 595 { 596 public: 597 RenderUtils(DisplayMtl *display); 598 ~RenderUtils() override; 599 600 // Clear current framebuffer 601 angle::Result clearWithDraw(const gl::Context *context, 602 RenderCommandEncoder *cmdEncoder, 603 const ClearRectParams ¶ms); 604 // Blit texture data to current framebuffer 605 angle::Result blitColorWithDraw(const gl::Context *context, 606 RenderCommandEncoder *cmdEncoder, 607 const angle::Format &srcAngleFormat, 608 const ColorBlitParams ¶ms); 609 // Same as above but blit the whole texture to the whole of current framebuffer. 610 // This function assumes the framebuffer and the source texture have same size. 611 angle::Result blitColorWithDraw(const gl::Context *context, 612 RenderCommandEncoder *cmdEncoder, 613 const angle::Format &srcAngleFormat, 614 const TextureRef &srcTexture); 615 angle::Result copyTextureWithDraw(const gl::Context *context, 616 RenderCommandEncoder *cmdEncoder, 617 const angle::Format &srcAngleFormat, 618 const angle::Format &dstAngleFormat, 619 const ColorBlitParams ¶ms); 620 621 angle::Result blitDepthStencilWithDraw(const gl::Context *context, 622 RenderCommandEncoder *cmdEncoder, 623 const DepthStencilBlitParams ¶ms); 624 // See DepthStencilBlitUtils::blitStencilViaCopyBuffer() 625 angle::Result blitStencilViaCopyBuffer(const gl::Context *context, 626 const StencilBlitViaBufferParams ¶ms); 627 628 // See IndexGeneratorUtils 629 angle::Result convertIndexBufferGPU(ContextMtl *contextMtl, 630 const IndexConversionParams ¶ms); 631 angle::Result generateTriFanBufferFromArrays(ContextMtl *contextMtl, 632 const TriFanOrLineLoopFromArrayParams ¶ms); 633 angle::Result generateTriFanBufferFromElementsArray(ContextMtl *contextMtl, 634 const IndexGenerationParams ¶ms, 635 uint32_t *indicesGenerated); 636 637 angle::Result generateLineLoopBufferFromArrays(ContextMtl *contextMtl, 638 const TriFanOrLineLoopFromArrayParams ¶ms); 639 angle::Result generateLineLoopLastSegment(ContextMtl *contextMtl, 640 uint32_t firstVertex, 641 uint32_t lastVertex, 642 const BufferRef &dstBuffer, 643 uint32_t dstOffset); 644 angle::Result generateLineLoopBufferFromElementsArray(ContextMtl *contextMtl, 645 const IndexGenerationParams ¶ms, 646 uint32_t *indicesGenerated); 647 angle::Result generateLineLoopLastSegmentFromElementsArray(ContextMtl *contextMtl, 648 const IndexGenerationParams ¶ms); 649 650 void combineVisibilityResult(ContextMtl *contextMtl, 651 bool keepOldValue, 652 const VisibilityBufferOffsetsMtl &renderPassResultBufOffsets, 653 const BufferRef &renderPassResultBuf, 654 const BufferRef &finalResultBuf); 655 656 // Compute based mipmap generation. Only possible for 3D texture for now. 657 angle::Result generateMipmapCS(ContextMtl *contextMtl, 658 const TextureRef &srcTexture, 659 bool sRGBMipmap, 660 NativeTexLevelArray *mipmapOutputViews); 661 662 angle::Result unpackPixelsFromBufferToTexture(ContextMtl *contextMtl, 663 const angle::Format &srcAngleFormat, 664 const CopyPixelsFromBufferParams ¶ms); 665 angle::Result packPixelsFromTextureToBuffer(ContextMtl *contextMtl, 666 const angle::Format &dstAngleFormat, 667 const CopyPixelsToBufferParams ¶ms); 668 669 // See VertexFormatConversionUtils::convertVertexFormatToFloatCS() 670 angle::Result convertVertexFormatToFloatCS(ContextMtl *contextMtl, 671 const angle::Format &srcAngleFormat, 672 const VertexFormatConvertParams ¶ms); 673 // See VertexFormatConversionUtils::convertVertexFormatToFloatVS() 674 angle::Result convertVertexFormatToFloatVS(const gl::Context *context, 675 RenderCommandEncoder *renderEncoder, 676 const angle::Format &srcAngleFormat, 677 const VertexFormatConvertParams ¶ms); 678 // See VertexFormatConversionUtils::expandVertexFormatComponentsCS() 679 angle::Result expandVertexFormatComponentsCS(ContextMtl *contextMtl, 680 const angle::Format &srcAngleFormat, 681 const VertexFormatConvertParams ¶ms); 682 // See VertexFormatConversionUtils::expandVertexFormatComponentsVS() 683 angle::Result expandVertexFormatComponentsVS(const gl::Context *context, 684 RenderCommandEncoder *renderEncoder, 685 const angle::Format &srcAngleFormat, 686 const VertexFormatConvertParams ¶ms); 687 688 angle::Result generatePrimitiveRestartPointsBuffer(ContextMtl *contextMtl, 689 const IndexGenerationParams ¶ms, 690 size_t *indicesGenerated); 691 angle::Result generatePrimitiveRestartLinesBuffer(ContextMtl *contextMtl, 692 const IndexGenerationParams ¶ms, 693 size_t *indicesGenerated); 694 angle::Result generatePrimitiveRestartTrianglesBuffer(ContextMtl *contextMtl, 695 const IndexGenerationParams ¶ms, 696 size_t *indicesGenerated); 697 698 private: 699 // override ErrorHandler 700 void handleError(GLenum error, 701 const char *message, 702 const char *file, 703 const char *function, 704 unsigned int line) override; 705 void handleError(NSError *error, 706 const char *message, 707 const char *file, 708 const char *function, 709 unsigned int line) override; 710 711 std::array<ClearUtils, angle::EnumSize<PixelType>()> mClearUtils; 712 713 std::array<ColorBlitUtils, angle::EnumSize<PixelType>()> mColorBlitUtils; 714 ColorBlitUtils mCopyTextureFloatToUIntUtils; 715 716 DepthStencilBlitUtils mDepthStencilBlitUtils; 717 IndexGeneratorUtils mIndexUtils; 718 VisibilityResultUtils mVisibilityResultUtils; 719 MipmapUtils mMipmapUtils; 720 std::array<CopyPixelsUtils, angle::EnumSize<PixelType>()> mCopyPixelsUtils; 721 VertexFormatConversionUtils mVertexFormatUtils; 722 }; 723 724 } // namespace mtl 725 } // namespace rx 726 727 #endif /* LIBANGLE_RENDERER_METAL_MTL_RENDER_UTILS_H_ */ 728