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