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