xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/metal/ContextMtl.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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