• 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_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