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 // ContextMtl.h: 7 // Defines the class interface for ContextMtl, implementing ContextImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_METAL_CONTEXTMTL_H_ 11 #define LIBANGLE_RENDERER_METAL_CONTEXTMTL_H_ 12 13 #import <Metal/Metal.h> 14 #import <mach/mach_types.h> 15 16 #include "common/Optional.h" 17 #include "libANGLE/Context.h" 18 #include "libANGLE/renderer/ContextImpl.h" 19 #include "libANGLE/renderer/metal/ProvokingVertexHelper.h" 20 #include "libANGLE/renderer/metal/mtl_buffer_manager.h" 21 #include "libANGLE/renderer/metal/mtl_buffer_pool.h" 22 #include "libANGLE/renderer/metal/mtl_command_buffer.h" 23 #include "libANGLE/renderer/metal/mtl_context_device.h" 24 #include "libANGLE/renderer/metal/mtl_occlusion_query_pool.h" 25 #include "libANGLE/renderer/metal/mtl_pipeline_cache.h" 26 #include "libANGLE/renderer/metal/mtl_resources.h" 27 #include "libANGLE/renderer/metal/mtl_state_cache.h" 28 #include "libANGLE/renderer/metal/mtl_utils.h" 29 namespace rx 30 { 31 class DisplayMtl; 32 class FramebufferMtl; 33 class VertexArrayMtl; 34 class ProgramMtl; 35 class RenderTargetMtl; 36 class WindowSurfaceMtl; 37 class TransformFeedbackMtl; 38 39 class ContextMtl : public ContextImpl, public mtl::Context 40 { 41 public: 42 ContextMtl(const gl::State &state, 43 gl::ErrorSet *errorSet, 44 const egl::AttributeMap &attribs, 45 DisplayMtl *display); 46 ~ContextMtl() override; 47 48 angle::Result initialize() override; 49 50 void onDestroy(const gl::Context *context) override; 51 52 // Flush and finish. 53 angle::Result flush(const gl::Context *context) override; 54 angle::Result finish(const gl::Context *context) override; 55 56 // Drawing methods. 57 angle::Result drawArrays(const gl::Context *context, 58 gl::PrimitiveMode mode, 59 GLint first, 60 GLsizei count) override; 61 angle::Result drawArraysInstanced(const gl::Context *context, 62 gl::PrimitiveMode mode, 63 GLint first, 64 GLsizei count, 65 GLsizei instanceCount) override; 66 angle::Result drawArraysInstancedBaseInstance(const gl::Context *context, 67 gl::PrimitiveMode mode, 68 GLint first, 69 GLsizei count, 70 GLsizei instanceCount, 71 GLuint baseInstance) override; 72 73 angle::Result drawElements(const gl::Context *context, 74 gl::PrimitiveMode mode, 75 GLsizei count, 76 gl::DrawElementsType type, 77 const void *indices) override; 78 angle::Result drawElementsBaseVertex(const gl::Context *context, 79 gl::PrimitiveMode mode, 80 GLsizei count, 81 gl::DrawElementsType type, 82 const void *indices, 83 GLint baseVertex) override; 84 angle::Result drawElementsInstanced(const gl::Context *context, 85 gl::PrimitiveMode mode, 86 GLsizei count, 87 gl::DrawElementsType type, 88 const void *indices, 89 GLsizei instanceCount) override; 90 angle::Result drawElementsInstancedBaseVertex(const gl::Context *context, 91 gl::PrimitiveMode mode, 92 GLsizei count, 93 gl::DrawElementsType type, 94 const void *indices, 95 GLsizei instanceCount, 96 GLint baseVertex) override; 97 angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, 98 gl::PrimitiveMode mode, 99 GLsizei count, 100 gl::DrawElementsType type, 101 const void *indices, 102 GLsizei instances, 103 GLint baseVertex, 104 GLuint baseInstance) override; 105 angle::Result drawRangeElements(const gl::Context *context, 106 gl::PrimitiveMode mode, 107 GLuint start, 108 GLuint end, 109 GLsizei count, 110 gl::DrawElementsType type, 111 const void *indices) override; 112 angle::Result drawRangeElementsBaseVertex(const gl::Context *context, 113 gl::PrimitiveMode mode, 114 GLuint start, 115 GLuint end, 116 GLsizei count, 117 gl::DrawElementsType type, 118 const void *indices, 119 GLint baseVertex) override; 120 angle::Result drawArraysIndirect(const gl::Context *context, 121 gl::PrimitiveMode mode, 122 const void *indirect) override; 123 angle::Result drawElementsIndirect(const gl::Context *context, 124 gl::PrimitiveMode mode, 125 gl::DrawElementsType type, 126 const void *indirect) override; 127 angle::Result multiDrawArrays(const gl::Context *context, 128 gl::PrimitiveMode mode, 129 const GLint *firsts, 130 const GLsizei *counts, 131 GLsizei drawcount) override; 132 angle::Result multiDrawArraysInstanced(const gl::Context *context, 133 gl::PrimitiveMode mode, 134 const GLint *firsts, 135 const GLsizei *counts, 136 const GLsizei *instanceCounts, 137 GLsizei drawcount) override; 138 angle::Result multiDrawArraysIndirect(const gl::Context *context, 139 gl::PrimitiveMode mode, 140 const void *indirect, 141 GLsizei drawcount, 142 GLsizei stride) override; 143 angle::Result multiDrawElements(const gl::Context *context, 144 gl::PrimitiveMode mode, 145 const GLsizei *counts, 146 gl::DrawElementsType type, 147 const GLvoid *const *indices, 148 GLsizei drawcount) override; 149 angle::Result multiDrawElementsInstanced(const gl::Context *context, 150 gl::PrimitiveMode mode, 151 const GLsizei *counts, 152 gl::DrawElementsType type, 153 const GLvoid *const *indices, 154 const GLsizei *instanceCounts, 155 GLsizei drawcount) override; 156 angle::Result multiDrawElementsIndirect(const gl::Context *context, 157 gl::PrimitiveMode mode, 158 gl::DrawElementsType type, 159 const void *indirect, 160 GLsizei drawcount, 161 GLsizei stride) override; 162 angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context, 163 gl::PrimitiveMode mode, 164 const GLint *firsts, 165 const GLsizei *counts, 166 const GLsizei *instanceCounts, 167 const GLuint *baseInstances, 168 GLsizei drawcount) override; 169 angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, 170 gl::PrimitiveMode mode, 171 const GLsizei *counts, 172 gl::DrawElementsType type, 173 const GLvoid *const *indices, 174 const GLsizei *instanceCounts, 175 const GLint *baseVertices, 176 const GLuint *baseInstances, 177 GLsizei drawcount) override; 178 // Device loss 179 gl::GraphicsResetStatus getResetStatus() override; 180 181 // EXT_debug_marker 182 angle::Result insertEventMarker(GLsizei length, const char *marker) override; 183 angle::Result pushGroupMarker(GLsizei length, const char *marker) override; 184 angle::Result popGroupMarker() override; 185 186 // KHR_debug 187 angle::Result pushDebugGroup(const gl::Context *context, 188 GLenum source, 189 GLuint id, 190 const std::string &message) override; 191 angle::Result popDebugGroup(const gl::Context *context) override; 192 193 // State sync with dirty bits. 194 angle::Result syncState(const gl::Context *context, 195 const gl::state::DirtyBits dirtyBits, 196 const gl::state::DirtyBits bitMask, 197 const gl::state::ExtendedDirtyBits extendedDirtyBits, 198 const gl::state::ExtendedDirtyBits extendedBitMask, 199 gl::Command command) override; 200 201 // Disjoint timer queries 202 GLint getGPUDisjoint() override; 203 GLint64 getTimestamp() override; 204 205 // Context switching 206 angle::Result onMakeCurrent(const gl::Context *context) override; 207 angle::Result onUnMakeCurrent(const gl::Context *context) override; 208 209 // Native capabilities, unmodified by gl::Context. 210 gl::Caps getNativeCaps() const override; 211 const gl::TextureCapsMap &getNativeTextureCaps() const override; 212 const gl::Extensions &getNativeExtensions() const override; 213 const gl::Limitations &getNativeLimitations() const override; 214 const ShPixelLocalStorageOptions &getNativePixelLocalStorageOptions() const override; 215 getProgram()216 const ProgramMtl *getProgram() const { return mProgram; } 217 218 // Shader creation 219 CompilerImpl *createCompiler() override; 220 ShaderImpl *createShader(const gl::ShaderState &state) override; 221 ProgramImpl *createProgram(const gl::ProgramState &state) override; 222 223 // Framebuffer creation 224 FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override; 225 226 // Texture creation 227 TextureImpl *createTexture(const gl::TextureState &state) override; 228 229 // Renderbuffer creation 230 RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override; 231 232 // Buffer creation 233 BufferImpl *createBuffer(const gl::BufferState &state) override; 234 235 // Vertex Array creation 236 VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override; 237 238 // Query and Fence creation 239 QueryImpl *createQuery(gl::QueryType type) override; 240 FenceNVImpl *createFenceNV() override; 241 SyncImpl *createSync() override; 242 243 // Transform Feedback creation 244 TransformFeedbackImpl *createTransformFeedback( 245 const gl::TransformFeedbackState &state) override; 246 247 // Sampler object creation 248 SamplerImpl *createSampler(const gl::SamplerState &state) override; 249 250 // Program Pipeline object creation 251 ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; 252 253 // Memory object creation. 254 MemoryObjectImpl *createMemoryObject() override; 255 256 // Semaphore creation. 257 SemaphoreImpl *createSemaphore() override; 258 259 // Overlay creation. 260 OverlayImpl *createOverlay(const gl::OverlayState &state) override; 261 262 angle::Result dispatchCompute(const gl::Context *context, 263 GLuint numGroupsX, 264 GLuint numGroupsY, 265 GLuint numGroupsZ) override; 266 angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override; 267 268 angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override; 269 angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override; 270 271 // override mtl::ErrorHandler 272 void handleError(GLenum error, 273 const char *message, 274 const char *file, 275 const char *function, 276 unsigned int line) override; 277 void handleError(NSError *error, 278 const char *message, 279 const char *file, 280 const char *function, 281 unsigned int line) override; 282 283 using ContextImpl::handleError; 284 285 void invalidateState(const gl::Context *context); 286 void invalidateDefaultAttribute(size_t attribIndex); 287 void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask); 288 void invalidateCurrentTextures(); 289 void invalidateDriverUniforms(); 290 void invalidateRenderPipeline(); 291 292 // Call this to notify ContextMtl whenever FramebufferMtl's state changed 293 void onDrawFrameBufferChangedState(const gl::Context *context, 294 FramebufferMtl *framebuffer, 295 bool renderPassChanged); 296 void onBackbufferResized(const gl::Context *context, WindowSurfaceMtl *backbuffer); 297 298 // Invoke by QueryMtl 299 angle::Result onOcclusionQueryBegin(const gl::Context *context, QueryMtl *query); 300 void onOcclusionQueryEnd(const gl::Context *context, QueryMtl *query); 301 void onOcclusionQueryDestroy(const gl::Context *context, QueryMtl *query); 302 303 // Useful for temporarily pause then restart occlusion query during clear/blit with draw. hasActiveOcclusionQuery()304 bool hasActiveOcclusionQuery() const { return mOcclusionQuery; } 305 // Disable the occlusion query in the current render pass. 306 // The render pass must already started. 307 void disableActiveOcclusionQueryInRenderPass(); 308 // Re-enable the occlusion query in the current render pass. 309 // The render pass must already started. 310 // NOTE: the old query's result will be retained and combined with the new result. 311 angle::Result restartActiveOcclusionQueryInRenderPass(); 312 313 // Invoke by TransformFeedbackMtl 314 void onTransformFeedbackActive(const gl::Context *context, TransformFeedbackMtl *xfb); 315 void onTransformFeedbackInactive(const gl::Context *context, TransformFeedbackMtl *xfb); 316 317 // Invoke by mtl::Sync 318 void queueEventSignal(const mtl::SharedEventRef &event, uint64_t value); 319 void serverWaitEvent(const mtl::SharedEventRef &event, uint64_t value); 320 321 const mtl::ClearColorValue &getClearColorValue() const; 322 const mtl::WriteMaskArray &getWriteMaskArray() const; 323 float getClearDepthValue() const; 324 uint32_t getClearStencilValue() const; 325 // Return front facing stencil write mask 326 uint32_t getStencilMask() const; 327 bool getDepthMask() const; 328 329 const mtl::Format &getPixelFormat(angle::FormatID angleFormatId) const; 330 const mtl::FormatCaps &getNativeFormatCaps(MTLPixelFormat mtlFormat) const; 331 // See mtl::FormatTable::getVertexFormat() 332 const mtl::VertexFormat &getVertexFormat(angle::FormatID angleFormatId, 333 bool tightlyPacked) const; 334 335 angle::Result getIncompleteTexture(const gl::Context *context, 336 gl::TextureType type, 337 gl::Texture **textureOut); 338 339 // Recommended to call these methods to end encoding instead of invoking the encoder's 340 // endEncoding() directly. 341 void endRenderEncoding(mtl::RenderCommandEncoder *encoder); 342 // Ends any active command encoder 343 void endEncoding(bool forceSaveRenderPassContent); 344 345 void flushCommandBuffer(mtl::CommandBufferFinishOperation operation); 346 void present(const gl::Context *context, id<CAMetalDrawable> presentationDrawable); 347 angle::Result finishCommandBuffer(); 348 349 // Check whether compatible render pass has been started. Compatible render pass is a render 350 // pass having the same attachments, and possibly having different load/store options. 351 bool hasStartedRenderPass(const mtl::RenderPassDesc &desc); 352 353 // Get current render encoder. May be nullptr if no render pass has been started. 354 mtl::RenderCommandEncoder *getRenderCommandEncoder(); 355 356 // Will end current command encoder if it is valid, then start new encoder. 357 // Unless hasStartedRenderPass(desc) returns true. 358 // Note: passing a compatible render pass with different load/store options won't end the 359 // current render pass. If a new render pass is desired, call endEncoding() prior to this. 360 mtl::RenderCommandEncoder *getRenderPassCommandEncoder(const mtl::RenderPassDesc &desc); 361 362 // Utilities to quickly create render command encoder to a specific texture: 363 // The previous content of texture will be loaded 364 mtl::RenderCommandEncoder *getTextureRenderCommandEncoder(const mtl::TextureRef &textureTarget, 365 const mtl::ImageNativeIndex &index); 366 // The previous content of texture will be loaded if clearColor is not provided 367 mtl::RenderCommandEncoder *getRenderTargetCommandEncoderWithClear( 368 const RenderTargetMtl &renderTarget, 369 const Optional<MTLClearColor> &clearColor); 370 // The previous content of texture will be loaded 371 mtl::RenderCommandEncoder *getRenderTargetCommandEncoder(const RenderTargetMtl &renderTarget); 372 373 // Will end current command encoder and start new blit command encoder. Unless a blit comamnd 374 // encoder is already started. 375 mtl::BlitCommandEncoder *getBlitCommandEncoder(); 376 377 // Will end current command encoder and start new compute command encoder. Unless a compute 378 // command encoder is already started. 379 mtl::ComputeCommandEncoder *getComputeCommandEncoder(); 380 381 // Because this backend uses an intermediate representation for the rendering 382 // commands, a render encoder can coexist with blit/compute command encoders. 383 mtl::BlitCommandEncoder *getBlitCommandEncoderWithoutEndingRenderEncoder(); 384 mtl::ComputeCommandEncoder *getComputeCommandEncoderWithoutEndingRenderEncoder(); 385 386 // Get the provoking vertex command encoder. 387 mtl::ComputeCommandEncoder *getIndexPreprocessingCommandEncoder(); 388 389 bool isCurrentRenderEncoderSerial(uint64_t serial); 390 getMetalDevice()391 const mtl::ContextDevice &getMetalDevice() const { return mContextDevice; } 392 393 angle::Result copy2DTextureSlice0Level0ToWorkTexture(const mtl::TextureRef &srcTexture); getWorkTexture()394 const mtl::TextureRef &getWorkTexture() const { return mWorkTexture; } 395 angle::Result copyTextureSliceLevelToWorkBuffer(const gl::Context *context, 396 const mtl::TextureRef &srcTexture, 397 const mtl::MipmapNativeLevel &mipNativeLevel, 398 uint32_t layerIndex); getWorkBuffer()399 const mtl::BufferRef &getWorkBuffer() const { return mWorkBuffer; } getBufferManager()400 mtl::BufferManager &getBufferManager() { return mBufferManager; } 401 getPipelineCache()402 mtl::PipelineCache &getPipelineCache() { return mPipelineCache; } 403 404 angle::ImageLoadContext getImageLoadContext() const; 405 406 private: 407 void ensureCommandBufferReady(); 408 void endBlitAndComputeEncoding(); 409 angle::Result setupDraw(const gl::Context *context, 410 gl::PrimitiveMode mode, 411 GLint firstVertex, 412 GLsizei vertexOrIndexCount, 413 GLsizei instanceCount, 414 gl::DrawElementsType indexTypeOrNone, 415 const void *indices, 416 bool xfbPass, 417 bool *isNoOp); 418 419 angle::Result setupDrawImpl(const gl::Context *context, 420 gl::PrimitiveMode mode, 421 GLint firstVertex, 422 GLsizei vertexOrIndexCount, 423 GLsizei instanceCount, 424 gl::DrawElementsType indexTypeOrNone, 425 const void *indices, 426 bool xfbPass, 427 bool *isNoOp); 428 429 angle::Result drawTriFanArrays(const gl::Context *context, 430 GLint first, 431 GLsizei count, 432 GLsizei instances, 433 GLuint baseInstance); 434 angle::Result drawTriFanArraysWithBaseVertex(const gl::Context *context, 435 GLint first, 436 GLsizei count, 437 GLsizei instances, 438 GLuint baseInstance); 439 angle::Result drawTriFanArraysLegacy(const gl::Context *context, 440 GLint first, 441 GLsizei count, 442 GLsizei instances); 443 angle::Result drawTriFanElements(const gl::Context *context, 444 GLsizei count, 445 gl::DrawElementsType type, 446 const void *indices, 447 GLsizei instances, 448 GLint baseVertex, 449 GLuint baseInstance); 450 451 angle::Result drawLineLoopArraysNonInstanced(const gl::Context *context, 452 GLint first, 453 GLsizei count); 454 angle::Result drawLineLoopArrays(const gl::Context *context, 455 GLint first, 456 GLsizei count, 457 GLsizei instances, 458 GLuint baseInstance); 459 angle::Result drawLineLoopElementsNonInstancedNoPrimitiveRestart(const gl::Context *context, 460 GLsizei count, 461 gl::DrawElementsType type, 462 const void *indices); 463 angle::Result drawLineLoopElements(const gl::Context *context, 464 GLsizei count, 465 gl::DrawElementsType type, 466 const void *indices, 467 GLsizei instances, 468 GLint baseVertex, 469 GLuint baseInstance); 470 471 angle::Result drawArraysProvokingVertexImpl(const gl::Context *context, 472 gl::PrimitiveMode mode, 473 GLsizei first, 474 GLsizei count, 475 GLsizei instances, 476 GLuint baseInstance); 477 478 angle::Result drawArraysImpl(const gl::Context *context, 479 gl::PrimitiveMode mode, 480 GLint first, 481 GLsizei count, 482 GLsizei instanceCount, 483 GLuint baseInstance); 484 485 angle::Result drawElementsImpl(const gl::Context *context, 486 gl::PrimitiveMode mode, 487 GLsizei count, 488 gl::DrawElementsType type, 489 const void *indices, 490 GLsizei instanceCount, 491 GLint baseVertex, 492 GLuint baseInstance); 493 void flushCommandBufferIfNeeded(); 494 void updateExtendedState(const gl::State &glState, 495 const gl::state::ExtendedDirtyBits extendedDirtyBits); 496 497 void updateViewport(FramebufferMtl *framebufferMtl, 498 const gl::Rectangle &viewport, 499 float nearPlane, 500 float farPlane); 501 void updateDepthRange(float nearPlane, float farPlane); 502 void updateBlendDescArray(const gl::BlendStateExt &blendStateExt); 503 void updateScissor(const gl::State &glState); 504 void updateCullMode(const gl::State &glState); 505 void updateFrontFace(const gl::State &glState); 506 void updateDrawFrameBufferBinding(const gl::Context *context); 507 void updateProgramExecutable(const gl::Context *context); 508 void updateVertexArray(const gl::Context *context); 509 bool requiresIndexRewrite(const gl::State &state, gl::PrimitiveMode mode); 510 angle::Result updateDefaultAttribute(size_t attribIndex); 511 void filterOutXFBOnlyDirtyBits(const gl::Context *context); 512 angle::Result handleDirtyActiveTextures(const gl::Context *context); 513 angle::Result handleDirtyDefaultAttribs(const gl::Context *context); 514 angle::Result handleDirtyDriverUniforms(const gl::Context *context, 515 GLint drawCallFirstVertex, 516 uint32_t verticesPerInstance); 517 angle::Result fillDriverXFBUniforms(GLint drawCallFirstVertex, 518 uint32_t verticesPerInstance, 519 uint32_t skippedInstances); 520 angle::Result handleDirtyDepthStencilState(const gl::Context *context); 521 angle::Result handleDirtyDepthBias(const gl::Context *context); 522 angle::Result handleDirtyRenderPass(const gl::Context *context); 523 angle::Result checkIfPipelineChanged(const gl::Context *context, 524 gl::PrimitiveMode primitiveMode, 525 bool xfbPass, 526 bool *pipelineDescChanged); 527 528 angle::Result startOcclusionQueryInRenderPass(QueryMtl *query, bool clearOldValue); 529 530 // Dirty bits. 531 enum DirtyBitType : size_t 532 { 533 DIRTY_BIT_DEFAULT_ATTRIBS, 534 DIRTY_BIT_TEXTURES, 535 DIRTY_BIT_DRIVER_UNIFORMS, 536 DIRTY_BIT_DEPTH_STENCIL_DESC, 537 DIRTY_BIT_DEPTH_BIAS, 538 DIRTY_BIT_DEPTH_CLIP_MODE, 539 DIRTY_BIT_STENCIL_REF, 540 DIRTY_BIT_BLEND_COLOR, 541 DIRTY_BIT_VIEWPORT, 542 DIRTY_BIT_SCISSOR, 543 DIRTY_BIT_DRAW_FRAMEBUFFER, 544 DIRTY_BIT_CULL_MODE, 545 DIRTY_BIT_FILL_MODE, 546 DIRTY_BIT_WINDING, 547 DIRTY_BIT_RENDER_PIPELINE, 548 DIRTY_BIT_UNIFORM_BUFFERS_BINDING, 549 DIRTY_BIT_RASTERIZER_DISCARD, 550 551 DIRTY_BIT_INVALID, 552 DIRTY_BIT_MAX = DIRTY_BIT_INVALID, 553 }; 554 555 // Must keep this in sync with DriverUniform::createUniformFields in: 556 // src/compiler/translator/tree_util/DriverUniform.cpp 557 // and DriverUniformMetal::createUniformFields in: 558 // src/compiler/translator/DriverUniformMetal.cpp 559 struct DriverUniforms 560 { 561 uint32_t acbBufferOffsets[2]; 562 float depthRange[2]; 563 uint32_t renderArea; 564 uint32_t flipXY; 565 uint32_t unused; 566 uint32_t misc; 567 568 int32_t xfbBufferOffsets[4]; 569 int32_t xfbVerticesPerInstance; 570 uint32_t coverageMask; // Metal specific 571 uint32_t unused2[2]; 572 }; 573 static_assert(sizeof(DriverUniforms) % (sizeof(uint32_t) * 4) == 0, 574 "DriverUniforms should be 16 bytes aligned"); 575 576 struct DefaultAttribute 577 { 578 uint8_t values[sizeof(float) * 4]; 579 }; 580 581 mtl::OcclusionQueryPool mOcclusionQueryPool; 582 583 mtl::CommandBuffer mCmdBuffer; 584 mtl::RenderCommandEncoder mRenderEncoder; 585 mtl::BlitCommandEncoder mBlitEncoder; 586 mtl::ComputeCommandEncoder mComputeEncoder; 587 bool mHasMetalSharedEvents = false; 588 589 mtl::PipelineCache mPipelineCache; 590 591 // Cached back-end objects 592 FramebufferMtl *mDrawFramebuffer = nullptr; 593 VertexArrayMtl *mVertexArray = nullptr; 594 ProgramMtl *mProgram = nullptr; 595 QueryMtl *mOcclusionQuery = nullptr; 596 mtl::TextureRef mWorkTexture; 597 mtl::BufferRef mWorkBuffer; 598 599 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>; 600 601 gl::AttributesMask mDirtyDefaultAttribsMask; 602 DirtyBits mDirtyBits; 603 604 uint32_t mRenderPassesSinceFlush = 0; 605 606 // State 607 mtl::RenderPipelineDesc mRenderPipelineDesc; 608 mtl::DepthStencilDesc mDepthStencilDesc; 609 mtl::BlendDescArray mBlendDescArray; 610 mtl::WriteMaskArray mWriteMaskArray; 611 mtl::ClearColorValue mClearColor; 612 uint32_t mClearStencil = 0; 613 uint32_t mStencilRefFront = 0; 614 uint32_t mStencilRefBack = 0; 615 MTLViewport mViewport; 616 MTLScissorRect mScissorRect; 617 MTLWinding mWinding; 618 MTLCullMode mCullMode; 619 bool mCullAllPolygons = false; 620 621 mtl::BufferManager mBufferManager; 622 623 // Lineloop and TriFan index buffer 624 mtl::BufferPool mLineLoopIndexBuffer; 625 mtl::BufferPool mLineLoopLastSegmentIndexBuffer; 626 mtl::BufferPool mTriFanIndexBuffer; 627 // one buffer can be reused for any starting vertex in DrawArrays() 628 mtl::BufferRef mTriFanArraysIndexBuffer; 629 630 // Dummy texture to be used for transform feedback only pass. 631 mtl::TextureRef mDummyXFBRenderTexture; 632 633 DriverUniforms mDriverUniforms; 634 635 DefaultAttribute mDefaultAttributes[mtl::kMaxVertexAttribs]; 636 637 IncompleteTextureSet mIncompleteTextures; 638 ProvokingVertexHelper mProvokingVertexHelper; 639 640 mtl::ContextDevice mContextDevice; 641 }; 642 643 } // namespace rx 644 645 #endif /* LIBANGLE_RENDERER_METAL_CONTEXTMTL_H_ */ 646