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