• 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 "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 
282     using ContextImpl::handleError;
283 
284     void invalidateState(const gl::Context *context);
285     void invalidateDefaultAttribute(size_t attribIndex);
286     void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
287     void invalidateCurrentTextures();
288     void invalidateDriverUniforms();
289     void invalidateRenderPipeline();
290 
291     void updateIncompatibleAttachments(const gl::State &glState);
292 
293     // Call this to notify ContextMtl whenever FramebufferMtl's state changed
294     void onDrawFrameBufferChangedState(const gl::Context *context,
295                                        FramebufferMtl *framebuffer,
296                                        bool renderPassChanged);
297     void onBackbufferResized(const gl::Context *context, WindowSurfaceMtl *backbuffer);
298 
299     // Invoke by QueryMtl
300     angle::Result onOcclusionQueryBegin(const gl::Context *context, QueryMtl *query);
301     void onOcclusionQueryEnd(const gl::Context *context, QueryMtl *query);
302     void onOcclusionQueryDestroy(const gl::Context *context, QueryMtl *query);
303 
304     // Useful for temporarily pause then restart occlusion query during clear/blit with draw.
hasActiveOcclusionQuery()305     bool hasActiveOcclusionQuery() const { return mOcclusionQuery; }
306     // Disable the occlusion query in the current render pass.
307     // The render pass must already started.
308     void disableActiveOcclusionQueryInRenderPass();
309     // Re-enable the occlusion query in the current render pass.
310     // The render pass must already started.
311     // NOTE: the old query's result will be retained and combined with the new result.
312     angle::Result restartActiveOcclusionQueryInRenderPass();
313 
314     // Invoke by TransformFeedbackMtl
315     void onTransformFeedbackActive(const gl::Context *context, TransformFeedbackMtl *xfb);
316     void onTransformFeedbackInactive(const gl::Context *context, TransformFeedbackMtl *xfb);
317 
318     // Invoked by multiple classes in SyncMtl.mm
319     // Enqueue an event and return the command queue serial that the event was or will be placed in.
320     uint64_t queueEventSignal(id<MTLEvent> event, uint64_t value);
321     void serverWaitEvent(id<MTLEvent> event, uint64_t value);
322 
323     const mtl::ClearColorValue &getClearColorValue() const;
324     const mtl::WriteMaskArray &getWriteMaskArray() const;
325     float getClearDepthValue() const;
326     uint32_t getClearStencilValue() const;
327     // Return front facing stencil write mask
328     uint32_t getStencilMask() const;
329     bool getDepthMask() const;
330 
331     const mtl::Format &getPixelFormat(angle::FormatID angleFormatId) const;
332     const mtl::FormatCaps &getNativeFormatCaps(MTLPixelFormat mtlFormat) const;
333     // See mtl::FormatTable::getVertexFormat()
334     const mtl::VertexFormat &getVertexFormat(angle::FormatID angleFormatId,
335                                              bool tightlyPacked) const;
336 
337     angle::Result getIncompleteTexture(const gl::Context *context,
338                                        gl::TextureType type,
339                                        gl::SamplerFormat format,
340                                        gl::Texture **textureOut);
341 
342     // Recommended to call these methods to end encoding instead of invoking the encoder's
343     // endEncoding() directly.
344     void endRenderEncoding(mtl::RenderCommandEncoder *encoder);
345     // Ends any active command encoder
346     void endEncoding(bool forceSaveRenderPassContent);
347 
348     void flushCommandBuffer(mtl::CommandBufferFinishOperation operation);
349     void present(const gl::Context *context, id<CAMetalDrawable> presentationDrawable);
350     angle::Result finishCommandBuffer();
351 
352     // Check whether compatible render pass has been started. Compatible render pass is a render
353     // pass having the same attachments, and possibly having different load/store options.
354     bool hasStartedRenderPass(const mtl::RenderPassDesc &desc);
355 
356     // Get current render encoder. May be nullptr if no render pass has been started.
357     mtl::RenderCommandEncoder *getRenderCommandEncoder();
358 
359     // Will end current command encoder if it is valid, then start new encoder.
360     // Unless hasStartedRenderPass(desc) returns true.
361     // Note: passing a compatible render pass with different load/store options won't end the
362     // current render pass. If a new render pass is desired, call endEncoding() prior to this.
363     mtl::RenderCommandEncoder *getRenderPassCommandEncoder(const mtl::RenderPassDesc &desc);
364 
365     // Utilities to quickly create render command encoder to a specific texture:
366     // The previous content of texture will be loaded
367     mtl::RenderCommandEncoder *getTextureRenderCommandEncoder(const mtl::TextureRef &textureTarget,
368                                                               const mtl::ImageNativeIndex &index);
369     // The previous content of texture will be loaded if clearColor is not provided
370     mtl::RenderCommandEncoder *getRenderTargetCommandEncoderWithClear(
371         const RenderTargetMtl &renderTarget,
372         const Optional<MTLClearColor> &clearColor);
373     // The previous content of texture will be loaded
374     mtl::RenderCommandEncoder *getRenderTargetCommandEncoder(const RenderTargetMtl &renderTarget);
375 
376     // Will end current command encoder and start new blit command encoder. Unless a blit comamnd
377     // encoder is already started.
378     mtl::BlitCommandEncoder *getBlitCommandEncoder();
379 
380     // Will end current command encoder and start new compute command encoder. Unless a compute
381     // command encoder is already started.
382     mtl::ComputeCommandEncoder *getComputeCommandEncoder();
383 
384     // Because this backend uses an intermediate representation for the rendering
385     // commands, a render encoder can coexist with blit/compute command encoders.
386     // Note: the blit/compute commands will run before the pending render commands.
387     mtl::BlitCommandEncoder *getBlitCommandEncoderWithoutEndingRenderEncoder();
388     mtl::ComputeCommandEncoder *getComputeCommandEncoderWithoutEndingRenderEncoder();
389 
390     // Get the provoking vertex command encoder.
391     mtl::ComputeCommandEncoder *getIndexPreprocessingCommandEncoder();
392 
393     bool isCurrentRenderEncoderSerial(uint64_t serial);
394 
getMetalDevice()395     const mtl::ContextDevice &getMetalDevice() const { return mContextDevice; }
396 
getBufferManager()397     mtl::BufferManager &getBufferManager() { return mBufferManager; }
398 
getPipelineCache()399     mtl::PipelineCache &getPipelineCache() { return mPipelineCache; }
400 
getImageLoadContext()401     const angle::ImageLoadContext &getImageLoadContext() const { return mImageLoadContext; }
402 
getForceResyncDrawFramebuffer()403     bool getForceResyncDrawFramebuffer() const { return mForceResyncDrawFramebuffer; }
getIncompatibleAttachments()404     gl::DrawBufferMask getIncompatibleAttachments() const { return mIncompatibleAttachments; }
405 
406   private:
407     void ensureCommandBufferReady();
408     void endBlitAndComputeEncoding();
409     angle::Result resyncDrawFramebufferIfNeeded(const gl::Context *context);
410     angle::Result setupDraw(const gl::Context *context,
411                             gl::PrimitiveMode mode,
412                             GLint firstVertex,
413                             GLsizei vertexOrIndexCount,
414                             GLsizei instanceCount,
415                             gl::DrawElementsType indexTypeOrNone,
416                             const void *indices,
417                             bool xfbPass,
418                             bool *isNoOp);
419 
420     angle::Result setupDrawImpl(const gl::Context *context,
421                                 gl::PrimitiveMode mode,
422                                 GLint firstVertex,
423                                 GLsizei vertexOrIndexCount,
424                                 GLsizei instanceCount,
425                                 gl::DrawElementsType indexTypeOrNone,
426                                 const void *indices,
427                                 bool xfbPass,
428                                 bool *isNoOp);
429 
430     angle::Result drawTriFanArrays(const gl::Context *context,
431                                    GLint first,
432                                    GLsizei count,
433                                    GLsizei instances,
434                                    GLuint baseInstance);
435     angle::Result drawTriFanArraysWithBaseVertex(const gl::Context *context,
436                                                  GLint first,
437                                                  GLsizei count,
438                                                  GLsizei instances,
439                                                  GLuint baseInstance);
440     angle::Result drawTriFanArraysLegacy(const gl::Context *context,
441                                          GLint first,
442                                          GLsizei count,
443                                          GLsizei instances);
444     angle::Result drawTriFanElements(const gl::Context *context,
445                                      GLsizei count,
446                                      gl::DrawElementsType type,
447                                      const void *indices,
448                                      GLsizei instances,
449                                      GLint baseVertex,
450                                      GLuint baseInstance);
451 
452     angle::Result drawLineLoopArraysNonInstanced(const gl::Context *context,
453                                                  GLint first,
454                                                  GLsizei count);
455     angle::Result drawLineLoopArrays(const gl::Context *context,
456                                      GLint first,
457                                      GLsizei count,
458                                      GLsizei instances,
459                                      GLuint baseInstance);
460     angle::Result drawLineLoopElementsNonInstancedNoPrimitiveRestart(const gl::Context *context,
461                                                                      GLsizei count,
462                                                                      gl::DrawElementsType type,
463                                                                      const void *indices);
464     angle::Result drawLineLoopElements(const gl::Context *context,
465                                        GLsizei count,
466                                        gl::DrawElementsType type,
467                                        const void *indices,
468                                        GLsizei instances,
469                                        GLint baseVertex,
470                                        GLuint baseInstance);
471 
472     angle::Result drawArraysProvokingVertexImpl(const gl::Context *context,
473                                                 gl::PrimitiveMode mode,
474                                                 GLsizei first,
475                                                 GLsizei count,
476                                                 GLsizei instances,
477                                                 GLuint baseInstance);
478 
479     angle::Result drawArraysImpl(const gl::Context *context,
480                                  gl::PrimitiveMode mode,
481                                  GLint first,
482                                  GLsizei count,
483                                  GLsizei instanceCount,
484                                  GLuint baseInstance);
485 
486     angle::Result drawElementsImpl(const gl::Context *context,
487                                    gl::PrimitiveMode mode,
488                                    GLsizei count,
489                                    gl::DrawElementsType type,
490                                    const void *indices,
491                                    GLsizei instanceCount,
492                                    GLint baseVertex,
493                                    GLuint baseInstance);
494     void flushCommandBufferIfNeeded();
495     void updateExtendedState(const gl::State &glState,
496                              const gl::state::ExtendedDirtyBits extendedDirtyBits);
497 
498     void updateViewport(FramebufferMtl *framebufferMtl,
499                         const gl::Rectangle &viewport,
500                         float nearPlane,
501                         float farPlane);
502     void updateDepthRange(float nearPlane, float farPlane);
503     void updateBlendDescArray(const gl::BlendStateExt &blendStateExt);
504     void updateScissor(const gl::State &glState);
505     void updateCullMode(const gl::State &glState);
506     void updateFrontFace(const gl::State &glState);
507     void updateDrawFrameBufferBinding(const gl::Context *context);
508     void updateProgramExecutable(const gl::Context *context);
509     void updateVertexArray(const gl::Context *context);
510     bool requiresIndexRewrite(const gl::State &state, gl::PrimitiveMode mode);
511     angle::Result updateDefaultAttribute(size_t attribIndex);
512     void filterOutXFBOnlyDirtyBits(const gl::Context *context);
513     angle::Result handleDirtyActiveTextures(const gl::Context *context);
514     angle::Result handleDirtyDefaultAttribs(const gl::Context *context);
515     angle::Result handleDirtyDriverUniforms(const gl::Context *context,
516                                             GLint drawCallFirstVertex,
517                                             uint32_t verticesPerInstance);
518     angle::Result fillDriverXFBUniforms(GLint drawCallFirstVertex,
519                                         uint32_t verticesPerInstance,
520                                         uint32_t skippedInstances);
521     angle::Result handleDirtyDepthStencilState(const gl::Context *context);
522     angle::Result handleDirtyDepthBias(const gl::Context *context);
523     angle::Result handleDirtyRenderPass(const gl::Context *context);
524     angle::Result checkIfPipelineChanged(const gl::Context *context,
525                                          gl::PrimitiveMode primitiveMode,
526                                          bool xfbPass,
527                                          bool *pipelineDescChanged);
528 
529     angle::Result startOcclusionQueryInRenderPass(QueryMtl *query, bool clearOldValue);
530 
531     angle::Result checkCommandBufferError();
532 
533     // Dirty bits.
534     enum DirtyBitType : size_t
535     {
536         DIRTY_BIT_DEFAULT_ATTRIBS,
537         DIRTY_BIT_TEXTURES,
538         DIRTY_BIT_DRIVER_UNIFORMS,
539         DIRTY_BIT_DEPTH_STENCIL_DESC,
540         DIRTY_BIT_DEPTH_BIAS,
541         DIRTY_BIT_DEPTH_CLIP_MODE,
542         DIRTY_BIT_STENCIL_REF,
543         DIRTY_BIT_BLEND_COLOR,
544         DIRTY_BIT_VIEWPORT,
545         DIRTY_BIT_SCISSOR,
546         DIRTY_BIT_DRAW_FRAMEBUFFER,
547         DIRTY_BIT_CULL_MODE,
548         DIRTY_BIT_FILL_MODE,
549         DIRTY_BIT_WINDING,
550         DIRTY_BIT_RENDER_PIPELINE,
551         DIRTY_BIT_UNIFORM_BUFFERS_BINDING,
552         DIRTY_BIT_RASTERIZER_DISCARD,
553 
554         DIRTY_BIT_INVALID,
555         DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
556     };
557 
558     // Must keep this in sync with DriverUniform::createUniformFields in:
559     // src/compiler/translator/tree_util/DriverUniform.cpp
560     // and DriverUniformMetal::createUniformFields in:
561     // src/compiler/translator/DriverUniformMetal.cpp
562     struct DriverUniforms
563     {
564         uint32_t acbBufferOffsets[2];
565         float depthRange[2];
566         uint32_t renderArea;
567         uint32_t flipXY;
568         uint32_t unused;
569         uint32_t misc;
570 
571         int32_t xfbBufferOffsets[4];
572         int32_t xfbVerticesPerInstance;
573         uint32_t coverageMask;  // Metal specific
574         uint32_t unused2[2];
575     };
576     static_assert(sizeof(DriverUniforms) % (sizeof(uint32_t) * 4) == 0,
577                   "DriverUniforms should be 16 bytes aligned");
578 
579     struct DefaultAttribute
580     {
581         uint8_t values[sizeof(float) * 4];
582     };
583 
584     angle::ImageLoadContext mImageLoadContext;
585 
586     mtl::OcclusionQueryPool mOcclusionQueryPool;
587 
588     mtl::CommandBuffer mCmdBuffer;
589     mtl::RenderCommandEncoder mRenderEncoder;
590     mtl::BlitCommandEncoder mBlitEncoder;
591     mtl::ComputeCommandEncoder mComputeEncoder;
592 
593     mtl::PipelineCache mPipelineCache;
594 
595     // Cached back-end objects
596     FramebufferMtl *mDrawFramebuffer  = nullptr;
597     VertexArrayMtl *mVertexArray      = nullptr;
598     ProgramExecutableMtl *mExecutable = nullptr;
599     QueryMtl *mOcclusionQuery         = nullptr;
600 
601     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
602 
603     gl::AttributesMask mDirtyDefaultAttribsMask;
604     DirtyBits mDirtyBits;
605 
606     uint32_t mRenderPassesSinceFlush = 0;
607 
608     // State
609     mtl::RenderPipelineDesc mRenderPipelineDesc;
610     mtl::DepthStencilDesc mDepthStencilDesc;
611     mtl::BlendDescArray mBlendDescArray;
612     mtl::WriteMaskArray mWriteMaskArray;
613     mtl::ClearColorValue mClearColor;
614     uint32_t mClearStencil    = 0;
615     uint32_t mStencilRefFront = 0;
616     uint32_t mStencilRefBack  = 0;
617     MTLViewport mViewport;
618     MTLScissorRect mScissorRect;
619     MTLWinding mWinding;
620     MTLCullMode mCullMode;
621     bool mCullAllPolygons = false;
622 
623     // Cached state to handle attachments incompatible with the current program
624     bool mForceResyncDrawFramebuffer = false;
625     gl::DrawBufferMask mIncompatibleAttachments;
626 
627     mtl::BufferManager mBufferManager;
628 
629     // Lineloop and TriFan index buffer
630     mtl::BufferPool mLineLoopIndexBuffer;
631     mtl::BufferPool mLineLoopLastSegmentIndexBuffer;
632     mtl::BufferPool mTriFanIndexBuffer;
633     // one buffer can be reused for any starting vertex in DrawArrays()
634     mtl::BufferRef mTriFanArraysIndexBuffer;
635 
636     // Dummy texture to be used for transform feedback only pass.
637     mtl::TextureRef mDummyXFBRenderTexture;
638 
639     DriverUniforms mDriverUniforms;
640 
641     DefaultAttribute mDefaultAttributes[mtl::kMaxVertexAttribs];
642 
643     IncompleteTextureSet mIncompleteTextures;
644     ProvokingVertexHelper mProvokingVertexHelper;
645 
646     mtl::ContextDevice mContextDevice;
647 };
648 
649 }  // namespace rx
650 
651 #endif /* LIBANGLE_RENDERER_METAL_CONTEXTMTL_H_ */
652