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 ClearUtils(const ClearUtils &src); 200 201 void onDestroy(); 202 203 // Clear current framebuffer 204 angle::Result clearWithDraw(const gl::Context *context, 205 RenderCommandEncoder *cmdEncoder, 206 const ClearRectParams ¶ms); 207 208 private: 209 void ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, uint32_t numColorAttachments); 210 211 angle::Result setupClearWithDraw(const gl::Context *context, 212 RenderCommandEncoder *cmdEncoder, 213 const ClearRectParams ¶ms); 214 id<MTLDepthStencilState> getClearDepthStencilState(const gl::Context *context, 215 const ClearRectParams ¶ms); 216 id<MTLRenderPipelineState> getClearRenderPipelineState(const gl::Context *context, 217 RenderCommandEncoder *cmdEncoder, 218 const ClearRectParams ¶ms); 219 220 const std::string mFragmentShaderName; 221 222 // Render pipeline cache for clear with draw: 223 std::array<RenderPipelineCache, kMaxRenderTargets + 1> mClearRenderPipelineCache; 224 }; 225 226 class ColorBlitUtils final : angle::NonCopyable 227 { 228 public: 229 ColorBlitUtils() = delete; 230 ColorBlitUtils(const std::string &fragmentShaderName); 231 ColorBlitUtils(const ColorBlitUtils &src); 232 233 void onDestroy(); 234 235 // Blit texture data to current framebuffer 236 angle::Result blitColorWithDraw(const gl::Context *context, 237 RenderCommandEncoder *cmdEncoder, 238 const ColorBlitParams ¶ms); 239 240 private: 241 void ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, 242 uint32_t numColorAttachments, 243 int alphaPremultiplyType, 244 int sourceTextureType, 245 RenderPipelineCache *cacheOut); 246 247 angle::Result setupColorBlitWithDraw(const gl::Context *context, 248 RenderCommandEncoder *cmdEncoder, 249 const ColorBlitParams ¶ms); 250 251 id<MTLRenderPipelineState> getColorBlitRenderPipelineState(const gl::Context *context, 252 RenderCommandEncoder *cmdEncoder, 253 const ColorBlitParams ¶ms); 254 255 const std::string mFragmentShaderName; 256 257 // Blit with draw pipeline caches: 258 // First array dimension: number of outputs. 259 // Second array dimension: source texture type (2d, ms, array, 3d, etc) 260 using ColorBlitRenderPipelineCacheArray = 261 std::array<std::array<RenderPipelineCache, mtl_shader::kTextureTypeCount>, 262 kMaxRenderTargets>; 263 ColorBlitRenderPipelineCacheArray mBlitRenderPipelineCache; 264 ColorBlitRenderPipelineCacheArray mBlitPremultiplyAlphaRenderPipelineCache; 265 ColorBlitRenderPipelineCacheArray mBlitUnmultiplyAlphaRenderPipelineCache; 266 }; 267 268 class DepthStencilBlitUtils final : angle::NonCopyable 269 { 270 public: 271 void onDestroy(); 272 273 angle::Result blitDepthStencilWithDraw(const gl::Context *context, 274 RenderCommandEncoder *cmdEncoder, 275 const DepthStencilBlitParams ¶ms); 276 277 // Blit stencil data using intermediate buffer. This function is used on devices with no 278 // support for direct stencil write in shader. Thus an intermediate buffer storing copied 279 // stencil data is needed. 280 // NOTE: this function shares the params struct with depth & stencil blit, but depth texture 281 // parameter is not used. This function will break existing render pass. 282 angle::Result blitStencilViaCopyBuffer(const gl::Context *context, 283 const StencilBlitViaBufferParams ¶ms); 284 285 private: 286 void ensureRenderPipelineStateCacheInitialized(ContextMtl *ctx, 287 int sourceDepthTextureType, 288 int sourceStencilTextureType, 289 RenderPipelineCache *cacheOut); 290 291 angle::Result setupDepthStencilBlitWithDraw(const gl::Context *context, 292 RenderCommandEncoder *cmdEncoder, 293 const DepthStencilBlitParams ¶ms); 294 295 id<MTLRenderPipelineState> getDepthStencilBlitRenderPipelineState( 296 const gl::Context *context, 297 RenderCommandEncoder *cmdEncoder, 298 const DepthStencilBlitParams ¶ms); 299 300 id<MTLComputePipelineState> getStencilToBufferComputePipelineState( 301 ContextMtl *ctx, 302 const StencilBlitViaBufferParams ¶ms); 303 304 std::array<RenderPipelineCache, mtl_shader::kTextureTypeCount> mDepthBlitRenderPipelineCache; 305 std::array<RenderPipelineCache, mtl_shader::kTextureTypeCount> mStencilBlitRenderPipelineCache; 306 std::array<std::array<RenderPipelineCache, mtl_shader::kTextureTypeCount>, 307 mtl_shader::kTextureTypeCount> 308 mDepthStencilBlitRenderPipelineCache; 309 310 std::array<AutoObjCPtr<id<MTLComputePipelineState>>, mtl_shader::kTextureTypeCount> 311 mStencilBlitToBufferComPipelineCache; 312 313 // Intermediate buffer for storing copied stencil data. Used when device doesn't support 314 // writing stencil in shader. 315 BufferRef mStencilCopyBuffer; 316 }; 317 318 // util class for generating index buffer 319 class IndexGeneratorUtils final : angle::NonCopyable 320 { 321 public: 322 void onDestroy(); 323 324 angle::Result convertIndexBufferGPU(ContextMtl *contextMtl, 325 const IndexConversionParams ¶ms); 326 angle::Result generateTriFanBufferFromArrays(ContextMtl *contextMtl, 327 const TriFanOrLineLoopFromArrayParams ¶ms); 328 // Generate triangle fan index buffer for glDrawElements(). 329 angle::Result generateTriFanBufferFromElementsArray(ContextMtl *contextMtl, 330 const IndexGenerationParams ¶ms, 331 uint32_t *indicesGenerated); 332 333 angle::Result generateLineLoopBufferFromArrays(ContextMtl *contextMtl, 334 const TriFanOrLineLoopFromArrayParams ¶ms); 335 angle::Result generateLineLoopLastSegment(ContextMtl *contextMtl, 336 uint32_t firstVertex, 337 uint32_t lastVertex, 338 const BufferRef &dstBuffer, 339 uint32_t dstOffset); 340 // Generate line loop index buffer for glDrawElements(). 341 // Destination buffer must have at least 2x the number of original indices if primitive restart 342 // is enabled. 343 angle::Result generateLineLoopBufferFromElementsArray(ContextMtl *contextMtl, 344 const IndexGenerationParams ¶ms, 345 uint32_t *indicesGenerated); 346 // Generate line loop's last segment index buffer for glDrawElements(). 347 // NOTE: this function assumes primitive restart is not enabled. 348 angle::Result generateLineLoopLastSegmentFromElementsArray(ContextMtl *contextMtl, 349 const IndexGenerationParams ¶ms); 350 351 angle::Result generatePrimitiveRestartPointsBuffer(ContextMtl *contextMtl, 352 const IndexGenerationParams ¶ms, 353 size_t *indicesGenerated); 354 355 angle::Result generatePrimitiveRestartLinesBuffer(ContextMtl *contextMtl, 356 const IndexGenerationParams ¶ms, 357 size_t *indicesGenerated); 358 359 angle::Result generatePrimitiveRestartTrianglesBuffer(ContextMtl *contextMtl, 360 const IndexGenerationParams ¶ms, 361 size_t *indicesGenerated); 362 363 private: 364 // Index generator compute pipelines: 365 // - First dimension: index type. 366 // - second dimension: source buffer's offset is aligned or not. 367 using IndexConversionPipelineArray = 368 std::array<std::array<AutoObjCPtr<id<MTLComputePipelineState>>, 2>, 369 angle::EnumSize<gl::DrawElementsType>()>; 370 371 AutoObjCPtr<id<MTLComputePipelineState>> getIndexConversionPipeline( 372 ContextMtl *contextMtl, 373 gl::DrawElementsType srcType, 374 uint32_t srcOffset); 375 // Get compute pipeline to generate tri fan/line loop index for glDrawElements(). 376 AutoObjCPtr<id<MTLComputePipelineState>> getIndicesFromElemArrayGeneratorPipeline( 377 ContextMtl *contextMtl, 378 gl::DrawElementsType srcType, 379 uint32_t srcOffset, 380 NSString *shaderName, 381 IndexConversionPipelineArray *pipelineCacheArray); 382 // Defer loading of compute pipeline to generate tri fan index for glDrawArrays(). 383 void ensureTriFanFromArrayGeneratorInitialized(ContextMtl *contextMtl); 384 // Defer loading of compute pipeline to generate line loop index for glDrawArrays(). 385 void ensureLineLoopFromArrayGeneratorInitialized(ContextMtl *contextMtl); 386 387 angle::Result generateTriFanBufferFromElementsArrayGPU( 388 ContextMtl *contextMtl, 389 gl::DrawElementsType srcType, 390 uint32_t indexCount, 391 const BufferRef &srcBuffer, 392 uint32_t srcOffset, 393 const BufferRef &dstBuffer, 394 // Must be multiples of kIndexBufferOffsetAlignment 395 uint32_t dstOffset); 396 angle::Result generateTriFanBufferFromElementsArrayCPU(ContextMtl *contextMtl, 397 const IndexGenerationParams ¶ms, 398 uint32_t *indicesGenerated); 399 400 angle::Result generateLineLoopBufferFromElementsArrayGPU( 401 ContextMtl *contextMtl, 402 gl::DrawElementsType srcType, 403 uint32_t indexCount, 404 const BufferRef &srcBuffer, 405 uint32_t srcOffset, 406 const BufferRef &dstBuffer, 407 // Must be multiples of kIndexBufferOffsetAlignment 408 uint32_t dstOffset); 409 angle::Result generateLineLoopBufferFromElementsArrayCPU(ContextMtl *contextMtl, 410 const IndexGenerationParams ¶ms, 411 uint32_t *indicesGenerated); 412 angle::Result generateLineLoopLastSegmentFromElementsArrayCPU( 413 ContextMtl *contextMtl, 414 const IndexGenerationParams ¶ms); 415 416 angle::Result generatePrimitiveRestartBuffer(ContextMtl *contextMtl, 417 unsigned numVerticesPerPrimitive, 418 const IndexGenerationParams ¶ms, 419 size_t *indicesGenerated); 420 421 IndexConversionPipelineArray mIndexConversionPipelineCaches; 422 423 IndexConversionPipelineArray mTriFanFromElemArrayGeneratorPipelineCaches; 424 AutoObjCPtr<id<MTLComputePipelineState>> mTriFanFromArraysGeneratorPipeline; 425 426 IndexConversionPipelineArray mLineLoopFromElemArrayGeneratorPipelineCaches; 427 AutoObjCPtr<id<MTLComputePipelineState>> mLineLoopFromArraysGeneratorPipeline; 428 }; 429 430 // Util class for handling visibility query result 431 class VisibilityResultUtils final : angle::NonCopyable 432 { 433 public: 434 void onDestroy(); 435 436 void combineVisibilityResult(ContextMtl *contextMtl, 437 bool keepOldValue, 438 const VisibilityBufferOffsetsMtl &renderPassResultBufOffsets, 439 const BufferRef &renderPassResultBuf, 440 const BufferRef &finalResultBuf); 441 442 private: 443 AutoObjCPtr<id<MTLComputePipelineState>> getVisibilityResultCombPipeline(ContextMtl *contextMtl, 444 bool keepOldValue); 445 // Visibility combination compute pipeline: 446 // - 0: This compute pipeline only combine the new values and discard old value. 447 // - 1: This compute pipeline keep the old value and combine with new values. 448 std::array<AutoObjCPtr<id<MTLComputePipelineState>>, 2> mVisibilityResultCombPipelines; 449 }; 450 451 // Util class for handling mipmap generation 452 class MipmapUtils final : angle::NonCopyable 453 { 454 public: 455 void onDestroy(); 456 457 // Compute based mipmap generation. 458 angle::Result generateMipmapCS(ContextMtl *contextMtl, 459 const TextureRef &srcTexture, 460 bool sRGBMipmap, 461 NativeTexLevelArray *mipmapOutputViews); 462 463 private: 464 void ensure3DMipGeneratorPipelineInitialized(ContextMtl *contextMtl); 465 void ensure2DMipGeneratorPipelineInitialized(ContextMtl *contextMtl); 466 void ensure2DArrayMipGeneratorPipelineInitialized(ContextMtl *contextMtl); 467 void ensureCubeMipGeneratorPipelineInitialized(ContextMtl *contextMtl); 468 469 // Mipmaps generating compute pipeline: 470 AutoObjCPtr<id<MTLComputePipelineState>> m3DMipGeneratorPipeline; 471 AutoObjCPtr<id<MTLComputePipelineState>> m2DMipGeneratorPipeline; 472 AutoObjCPtr<id<MTLComputePipelineState>> m2DArrayMipGeneratorPipeline; 473 AutoObjCPtr<id<MTLComputePipelineState>> mCubeMipGeneratorPipeline; 474 }; 475 476 // Util class for handling pixels copy between buffers and textures 477 class CopyPixelsUtils final : angle::NonCopyable 478 { 479 public: 480 CopyPixelsUtils() = default; 481 CopyPixelsUtils(const std::string &readShaderName, const std::string &writeShaderName); 482 CopyPixelsUtils(const CopyPixelsUtils &src); 483 484 void onDestroy(); 485 486 angle::Result unpackPixelsFromBufferToTexture(ContextMtl *contextMtl, 487 const angle::Format &srcAngleFormat, 488 const CopyPixelsFromBufferParams ¶ms); 489 angle::Result packPixelsFromTextureToBuffer(ContextMtl *contextMtl, 490 const angle::Format &dstAngleFormat, 491 const CopyPixelsToBufferParams ¶ms); 492 493 private: 494 AutoObjCPtr<id<MTLComputePipelineState>> getPixelsCopyPipeline(ContextMtl *contextMtl, 495 const angle::Format &angleFormat, 496 const TextureRef &texture, 497 bool bufferWrite); 498 // Copy pixels between buffer and texture compute pipelines: 499 // - First dimension: pixel format. 500 // - Second dimension: texture type * (buffer read/write flag) 501 using PixelsCopyPipelineArray = std::array< 502 std::array<AutoObjCPtr<id<MTLComputePipelineState>>, mtl_shader::kTextureTypeCount * 2>, 503 angle::kNumANGLEFormats>; 504 PixelsCopyPipelineArray mPixelsCopyPipelineCaches; 505 506 const std::string mReadShaderName; 507 const std::string mWriteShaderName; 508 }; 509 510 // Util class for handling vertex format conversion on GPU 511 class VertexFormatConversionUtils final : angle::NonCopyable 512 { 513 public: 514 void onDestroy(); 515 516 // Convert vertex format to float. Compute shader version. 517 angle::Result convertVertexFormatToFloatCS(ContextMtl *contextMtl, 518 const angle::Format &srcAngleFormat, 519 const VertexFormatConvertParams ¶ms); 520 // Convert vertex format to float. Vertex shader version. This version should be used if 521 // a render pass is active and we don't want to break it. Explicit memory barrier must be 522 // supported. 523 angle::Result convertVertexFormatToFloatVS(const gl::Context *context, 524 RenderCommandEncoder *renderEncoder, 525 const angle::Format &srcAngleFormat, 526 const VertexFormatConvertParams ¶ms); 527 // Expand number of components per vertex's attribute (or just simply copy components between 528 // buffers with different stride and offset) 529 angle::Result expandVertexFormatComponentsCS(ContextMtl *contextMtl, 530 const angle::Format &srcAngleFormat, 531 const VertexFormatConvertParams ¶ms); 532 angle::Result expandVertexFormatComponentsVS(const gl::Context *context, 533 RenderCommandEncoder *renderEncoder, 534 const angle::Format &srcAngleFormat, 535 const VertexFormatConvertParams ¶ms); 536 537 private: 538 void ensureComponentsExpandComputePipelineCreated(ContextMtl *contextMtl); 539 AutoObjCPtr<id<MTLRenderPipelineState>> getComponentsExpandRenderPipeline( 540 ContextMtl *contextMtl, 541 RenderCommandEncoder *renderEncoder); 542 543 AutoObjCPtr<id<MTLComputePipelineState>> getFloatConverstionComputePipeline( 544 ContextMtl *contextMtl, 545 const angle::Format &srcAngleFormat); 546 547 AutoObjCPtr<id<MTLRenderPipelineState>> getFloatConverstionRenderPipeline( 548 ContextMtl *contextMtl, 549 RenderCommandEncoder *renderEncoder, 550 const angle::Format &srcAngleFormat); 551 552 template <typename EncoderType, typename PipelineType> 553 angle::Result setupCommonConvertVertexFormatToFloat(ContextMtl *contextMtl, 554 EncoderType cmdEncoder, 555 const PipelineType &pipeline, 556 const angle::Format &srcAngleFormat, 557 const VertexFormatConvertParams ¶ms); 558 template <typename EncoderType, typename PipelineType> 559 angle::Result setupCommonExpandVertexFormatComponents(ContextMtl *contextMtl, 560 EncoderType cmdEncoder, 561 const PipelineType &pipeline, 562 const angle::Format &srcAngleFormat, 563 const VertexFormatConvertParams ¶ms); 564 565 using ConvertToFloatCompPipelineArray = 566 std::array<AutoObjCPtr<id<MTLComputePipelineState>>, angle::kNumANGLEFormats>; 567 using ConvertToFloatRenderPipelineArray = 568 std::array<RenderPipelineCache, angle::kNumANGLEFormats>; 569 570 ConvertToFloatCompPipelineArray mConvertToFloatCompPipelineCaches; 571 ConvertToFloatRenderPipelineArray mConvertToFloatRenderPipelineCaches; 572 573 AutoObjCPtr<id<MTLComputePipelineState>> mComponentsExpandCompPipeline; 574 RenderPipelineCache mComponentsExpandRenderPipelineCache; 575 }; 576 577 // RenderUtils: container class of various util classes above 578 class RenderUtils : public Context, angle::NonCopyable 579 { 580 public: 581 RenderUtils(DisplayMtl *display); 582 ~RenderUtils() override; 583 584 angle::Result initialize(); 585 void onDestroy(); 586 587 // Clear current framebuffer 588 angle::Result clearWithDraw(const gl::Context *context, 589 RenderCommandEncoder *cmdEncoder, 590 const ClearRectParams ¶ms); 591 // Blit texture data to current framebuffer 592 angle::Result blitColorWithDraw(const gl::Context *context, 593 RenderCommandEncoder *cmdEncoder, 594 const angle::Format &srcAngleFormat, 595 const ColorBlitParams ¶ms); 596 // Same as above but blit the whole texture to the whole of current framebuffer. 597 // This function assumes the framebuffer and the source texture have same size. 598 angle::Result blitColorWithDraw(const gl::Context *context, 599 RenderCommandEncoder *cmdEncoder, 600 const angle::Format &srcAngleFormat, 601 const TextureRef &srcTexture); 602 angle::Result copyTextureWithDraw(const gl::Context *context, 603 RenderCommandEncoder *cmdEncoder, 604 const angle::Format &srcAngleFormat, 605 const angle::Format &dstAngleFormat, 606 const ColorBlitParams ¶ms); 607 608 angle::Result blitDepthStencilWithDraw(const gl::Context *context, 609 RenderCommandEncoder *cmdEncoder, 610 const DepthStencilBlitParams ¶ms); 611 // See DepthStencilBlitUtils::blitStencilViaCopyBuffer() 612 angle::Result blitStencilViaCopyBuffer(const gl::Context *context, 613 const StencilBlitViaBufferParams ¶ms); 614 615 // See IndexGeneratorUtils 616 angle::Result convertIndexBufferGPU(ContextMtl *contextMtl, 617 const IndexConversionParams ¶ms); 618 angle::Result generateTriFanBufferFromArrays(ContextMtl *contextMtl, 619 const TriFanOrLineLoopFromArrayParams ¶ms); 620 angle::Result generateTriFanBufferFromElementsArray(ContextMtl *contextMtl, 621 const IndexGenerationParams ¶ms, 622 uint32_t *indicesGenerated); 623 624 angle::Result generateLineLoopBufferFromArrays(ContextMtl *contextMtl, 625 const TriFanOrLineLoopFromArrayParams ¶ms); 626 angle::Result generateLineLoopLastSegment(ContextMtl *contextMtl, 627 uint32_t firstVertex, 628 uint32_t lastVertex, 629 const BufferRef &dstBuffer, 630 uint32_t dstOffset); 631 angle::Result generateLineLoopBufferFromElementsArray(ContextMtl *contextMtl, 632 const IndexGenerationParams ¶ms, 633 uint32_t *indicesGenerated); 634 angle::Result generateLineLoopLastSegmentFromElementsArray(ContextMtl *contextMtl, 635 const IndexGenerationParams ¶ms); 636 637 void combineVisibilityResult(ContextMtl *contextMtl, 638 bool keepOldValue, 639 const VisibilityBufferOffsetsMtl &renderPassResultBufOffsets, 640 const BufferRef &renderPassResultBuf, 641 const BufferRef &finalResultBuf); 642 643 // Compute based mipmap generation. Only possible for 3D texture for now. 644 angle::Result generateMipmapCS(ContextMtl *contextMtl, 645 const TextureRef &srcTexture, 646 bool sRGBMipmap, 647 NativeTexLevelArray *mipmapOutputViews); 648 649 angle::Result unpackPixelsFromBufferToTexture(ContextMtl *contextMtl, 650 const angle::Format &srcAngleFormat, 651 const CopyPixelsFromBufferParams ¶ms); 652 angle::Result packPixelsFromTextureToBuffer(ContextMtl *contextMtl, 653 const angle::Format &dstAngleFormat, 654 const CopyPixelsToBufferParams ¶ms); 655 656 // See VertexFormatConversionUtils::convertVertexFormatToFloatCS() 657 angle::Result convertVertexFormatToFloatCS(ContextMtl *contextMtl, 658 const angle::Format &srcAngleFormat, 659 const VertexFormatConvertParams ¶ms); 660 // See VertexFormatConversionUtils::convertVertexFormatToFloatVS() 661 angle::Result convertVertexFormatToFloatVS(const gl::Context *context, 662 RenderCommandEncoder *renderEncoder, 663 const angle::Format &srcAngleFormat, 664 const VertexFormatConvertParams ¶ms); 665 // See VertexFormatConversionUtils::expandVertexFormatComponentsCS() 666 angle::Result expandVertexFormatComponentsCS(ContextMtl *contextMtl, 667 const angle::Format &srcAngleFormat, 668 const VertexFormatConvertParams ¶ms); 669 // See VertexFormatConversionUtils::expandVertexFormatComponentsVS() 670 angle::Result expandVertexFormatComponentsVS(const gl::Context *context, 671 RenderCommandEncoder *renderEncoder, 672 const angle::Format &srcAngleFormat, 673 const VertexFormatConvertParams ¶ms); 674 675 angle::Result generatePrimitiveRestartPointsBuffer(ContextMtl *contextMtl, 676 const IndexGenerationParams ¶ms, 677 size_t *indicesGenerated); 678 angle::Result generatePrimitiveRestartLinesBuffer(ContextMtl *contextMtl, 679 const IndexGenerationParams ¶ms, 680 size_t *indicesGenerated); 681 angle::Result generatePrimitiveRestartTrianglesBuffer(ContextMtl *contextMtl, 682 const IndexGenerationParams ¶ms, 683 size_t *indicesGenerated); 684 685 private: 686 // override ErrorHandler 687 void handleError(GLenum error, 688 const char *file, 689 const char *function, 690 unsigned int line) override; 691 void handleError(NSError *error, 692 const char *file, 693 const char *function, 694 unsigned int line) override; 695 696 std::array<ClearUtils, angle::EnumSize<PixelType>()> mClearUtils; 697 698 std::array<ColorBlitUtils, angle::EnumSize<PixelType>()> mColorBlitUtils; 699 ColorBlitUtils mCopyTextureFloatToUIntUtils; 700 701 DepthStencilBlitUtils mDepthStencilBlitUtils; 702 IndexGeneratorUtils mIndexUtils; 703 VisibilityResultUtils mVisibilityResultUtils; 704 MipmapUtils mMipmapUtils; 705 std::array<CopyPixelsUtils, angle::EnumSize<PixelType>()> mCopyPixelsUtils; 706 VertexFormatConversionUtils mVertexFormatUtils; 707 }; 708 709 } // namespace mtl 710 } // namespace rx 711 712 #endif /* LIBANGLE_RENDERER_METAL_MTL_RENDER_UTILS_H_ */ 713