xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/ContextVk.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2016 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 // ContextVk.h:
7 //    Defines the class interface for ContextVk, implementing ContextImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
12 
13 #include <condition_variable>
14 
15 #include "common/PackedEnums.h"
16 #include "common/vulkan/vk_headers.h"
17 #include "image_util/loadimage.h"
18 #include "libANGLE/renderer/ContextImpl.h"
19 #include "libANGLE/renderer/renderer_utils.h"
20 #include "libANGLE/renderer/vulkan/DisplayVk.h"
21 #include "libANGLE/renderer/vulkan/OverlayVk.h"
22 #include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
23 #include "libANGLE/renderer/vulkan/ShareGroupVk.h"
24 #include "libANGLE/renderer/vulkan/vk_helpers.h"
25 #include "libANGLE/renderer/vulkan/vk_renderer.h"
26 
27 namespace angle
28 {
29 struct FeaturesVk;
30 }  // namespace angle
31 
32 namespace rx
33 {
34 namespace vk
35 {
36 class SyncHelper;
37 }  // namespace vk
38 
39 class ConversionBuffer;
40 class ProgramExecutableVk;
41 class WindowSurfaceVk;
42 class OffscreenSurfaceVk;
43 class ShareGroupVk;
44 
45 static constexpr uint32_t kMaxGpuEventNameLen = 32;
46 using EventName                               = std::array<char, kMaxGpuEventNameLen>;
47 
48 using ContextVkDescriptorSetList = angle::PackedEnumMap<PipelineType, uint32_t>;
49 using CounterPipelineTypeMap     = angle::PackedEnumMap<PipelineType, uint32_t>;
50 
51 enum class GraphicsEventCmdBuf
52 {
53     NotInQueryCmd              = 0,
54     InOutsideCmdBufQueryCmd    = 1,
55     InRenderPassCmdBufQueryCmd = 2,
56 
57     InvalidEnum = 3,
58     EnumCount   = 3,
59 };
60 
61 // Why depth/stencil feedback loop is being updated.  Based on whether it's due to a draw or clear,
62 // different GL state affect depth/stencil write.
63 enum class UpdateDepthFeedbackLoopReason
64 {
65     None,
66     Draw,
67     Clear,
68 };
69 
70 static constexpr GLbitfield kBufferMemoryBarrierBits =
71     GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
72     GL_COMMAND_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
73     GL_TRANSFORM_FEEDBACK_BARRIER_BIT | GL_ATOMIC_COUNTER_BARRIER_BIT |
74     GL_SHADER_STORAGE_BARRIER_BIT | GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
75 static constexpr GLbitfield kImageMemoryBarrierBits =
76     GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
77     GL_TEXTURE_UPDATE_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT;
78 
79 class ContextVk : public ContextImpl, public vk::Context, public MultisampleTextureInitializer
80 {
81   public:
82     ContextVk(const gl::State &state, gl::ErrorSet *errorSet, vk::Renderer *renderer);
83     ~ContextVk() override;
84 
85     angle::Result initialize(const angle::ImageLoadContext &imageLoadContext) override;
86 
87     void onDestroy(const gl::Context *context) override;
88 
89     // Flush and finish.
90     angle::Result flush(const gl::Context *context) override;
91     angle::Result finish(const gl::Context *context) override;
92 
93     // Drawing methods.
94     angle::Result drawArrays(const gl::Context *context,
95                              gl::PrimitiveMode mode,
96                              GLint first,
97                              GLsizei count) override;
98     angle::Result drawArraysInstanced(const gl::Context *context,
99                                       gl::PrimitiveMode mode,
100                                       GLint first,
101                                       GLsizei count,
102                                       GLsizei instanceCount) override;
103     angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
104                                                   gl::PrimitiveMode mode,
105                                                   GLint first,
106                                                   GLsizei count,
107                                                   GLsizei instanceCount,
108                                                   GLuint baseInstance) override;
109 
110     angle::Result drawElements(const gl::Context *context,
111                                gl::PrimitiveMode mode,
112                                GLsizei count,
113                                gl::DrawElementsType type,
114                                const void *indices) override;
115     angle::Result drawElementsBaseVertex(const gl::Context *context,
116                                          gl::PrimitiveMode mode,
117                                          GLsizei count,
118                                          gl::DrawElementsType type,
119                                          const void *indices,
120                                          GLint baseVertex) override;
121     angle::Result drawElementsInstanced(const gl::Context *context,
122                                         gl::PrimitiveMode mode,
123                                         GLsizei count,
124                                         gl::DrawElementsType type,
125                                         const void *indices,
126                                         GLsizei instanceCount) override;
127     angle::Result drawElementsInstancedBaseVertex(const gl::Context *context,
128                                                   gl::PrimitiveMode mode,
129                                                   GLsizei count,
130                                                   gl::DrawElementsType type,
131                                                   const void *indices,
132                                                   GLsizei instanceCount,
133                                                   GLint baseVertex) override;
134     angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
135                                                               gl::PrimitiveMode mode,
136                                                               GLsizei count,
137                                                               gl::DrawElementsType type,
138                                                               const void *indices,
139                                                               GLsizei instances,
140                                                               GLint baseVertex,
141                                                               GLuint baseInstance) override;
142     angle::Result drawRangeElements(const gl::Context *context,
143                                     gl::PrimitiveMode mode,
144                                     GLuint start,
145                                     GLuint end,
146                                     GLsizei count,
147                                     gl::DrawElementsType type,
148                                     const void *indices) override;
149     angle::Result drawRangeElementsBaseVertex(const gl::Context *context,
150                                               gl::PrimitiveMode mode,
151                                               GLuint start,
152                                               GLuint end,
153                                               GLsizei count,
154                                               gl::DrawElementsType type,
155                                               const void *indices,
156                                               GLint baseVertex) override;
157     angle::Result drawArraysIndirect(const gl::Context *context,
158                                      gl::PrimitiveMode mode,
159                                      const void *indirect) override;
160     angle::Result drawElementsIndirect(const gl::Context *context,
161                                        gl::PrimitiveMode mode,
162                                        gl::DrawElementsType type,
163                                        const void *indirect) override;
164 
165     angle::Result multiDrawArrays(const gl::Context *context,
166                                   gl::PrimitiveMode mode,
167                                   const GLint *firsts,
168                                   const GLsizei *counts,
169                                   GLsizei drawcount) override;
170     angle::Result multiDrawArraysInstanced(const gl::Context *context,
171                                            gl::PrimitiveMode mode,
172                                            const GLint *firsts,
173                                            const GLsizei *counts,
174                                            const GLsizei *instanceCounts,
175                                            GLsizei drawcount) override;
176     angle::Result multiDrawArraysIndirect(const gl::Context *context,
177                                           gl::PrimitiveMode mode,
178                                           const void *indirect,
179                                           GLsizei drawcount,
180                                           GLsizei stride) override;
181     angle::Result multiDrawElements(const gl::Context *context,
182                                     gl::PrimitiveMode mode,
183                                     const GLsizei *counts,
184                                     gl::DrawElementsType type,
185                                     const GLvoid *const *indices,
186                                     GLsizei drawcount) override;
187     angle::Result multiDrawElementsInstanced(const gl::Context *context,
188                                              gl::PrimitiveMode mode,
189                                              const GLsizei *counts,
190                                              gl::DrawElementsType type,
191                                              const GLvoid *const *indices,
192                                              const GLsizei *instanceCounts,
193                                              GLsizei drawcount) override;
194     angle::Result multiDrawElementsIndirect(const gl::Context *context,
195                                             gl::PrimitiveMode mode,
196                                             gl::DrawElementsType type,
197                                             const void *indirect,
198                                             GLsizei drawcount,
199                                             GLsizei stride) override;
200     angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
201                                                        gl::PrimitiveMode mode,
202                                                        const GLint *firsts,
203                                                        const GLsizei *counts,
204                                                        const GLsizei *instanceCounts,
205                                                        const GLuint *baseInstances,
206                                                        GLsizei drawcount) override;
207     angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
208                                                                    gl::PrimitiveMode mode,
209                                                                    const GLsizei *counts,
210                                                                    gl::DrawElementsType type,
211                                                                    const GLvoid *const *indices,
212                                                                    const GLsizei *instanceCounts,
213                                                                    const GLint *baseVertices,
214                                                                    const GLuint *baseInstances,
215                                                                    GLsizei drawcount) override;
216 
217     // MultiDrawIndirect helper functions
218     angle::Result multiDrawElementsIndirectHelper(const gl::Context *context,
219                                                   gl::PrimitiveMode mode,
220                                                   gl::DrawElementsType type,
221                                                   const void *indirect,
222                                                   GLsizei drawcount,
223                                                   GLsizei stride);
224     angle::Result multiDrawArraysIndirectHelper(const gl::Context *context,
225                                                 gl::PrimitiveMode mode,
226                                                 const void *indirect,
227                                                 GLsizei drawcount,
228                                                 GLsizei stride);
229 
230     // ShareGroup
getShareGroup()231     ShareGroupVk *getShareGroup() { return mShareGroupVk; }
getPipelineLayoutCache()232     PipelineLayoutCache &getPipelineLayoutCache()
233     {
234         return mShareGroupVk->getPipelineLayoutCache();
235     }
getDescriptorSetLayoutCache()236     DescriptorSetLayoutCache &getDescriptorSetLayoutCache()
237     {
238         return mShareGroupVk->getDescriptorSetLayoutCache();
239     }
getMetaDescriptorPools()240     vk::DescriptorSetArray<vk::MetaDescriptorPool> &getMetaDescriptorPools()
241     {
242         return mShareGroupVk->getMetaDescriptorPools();
243     }
244 
245     // Device loss
246     gl::GraphicsResetStatus getResetStatus() override;
247 
isDebugEnabled()248     bool isDebugEnabled()
249     {
250         return mRenderer->enableDebugUtils() || mRenderer->angleDebuggerMode();
251     }
252 
253     // EXT_debug_marker
254     angle::Result insertEventMarker(GLsizei length, const char *marker) override;
255     angle::Result pushGroupMarker(GLsizei length, const char *marker) override;
256     angle::Result popGroupMarker() override;
257 
258     void insertEventMarkerImpl(GLenum source, const char *marker);
259 
260     // KHR_debug
261     angle::Result pushDebugGroup(const gl::Context *context,
262                                  GLenum source,
263                                  GLuint id,
264                                  const std::string &message) override;
265     angle::Result popDebugGroup(const gl::Context *context) override;
266 
267     // Record GL API calls for debuggers
268     void logEvent(const char *eventString);
269     void endEventLog(angle::EntryPoint entryPoint, PipelineType pipelineType);
270     void endEventLogForClearOrQuery();
271 
272     bool isViewportFlipEnabledForDrawFBO() const;
273     bool isViewportFlipEnabledForReadFBO() const;
274     // When the device/surface is rotated such that the surface's aspect ratio is different than
275     // the native device (e.g. 90 degrees), the width and height of the viewport, scissor, and
276     // render area must be swapped.
277     bool isRotatedAspectRatioForDrawFBO() const;
278     bool isRotatedAspectRatioForReadFBO() const;
279     SurfaceRotation getRotationDrawFramebuffer() const;
280     SurfaceRotation getRotationReadFramebuffer() const;
281     SurfaceRotation getSurfaceRotationImpl(const gl::Framebuffer *framebuffer,
282                                            const egl::Surface *surface);
283 
284     // View port (x, y, w, h) will be determined by a combination of -
285     // 1. clip space origin
286     // 2. isViewportFlipEnabledForDrawFBO
287     // For userdefined FBOs it will be based on the value of isViewportFlipEnabledForDrawFBO.
288     // For default FBOs it will be XOR of ClipOrigin and isViewportFlipEnabledForDrawFBO.
289     // isYFlipEnabledForDrawFBO indicates the rendered image is upside-down.
isYFlipEnabledForDrawFBO()290     ANGLE_INLINE bool isYFlipEnabledForDrawFBO() const
291     {
292         return mState.getClipOrigin() == gl::ClipOrigin::UpperLeft
293                    ? !isViewportFlipEnabledForDrawFBO()
294                    : isViewportFlipEnabledForDrawFBO();
295     }
296 
297     // State sync with dirty bits.
298     angle::Result syncState(const gl::Context *context,
299                             const gl::state::DirtyBits dirtyBits,
300                             const gl::state::DirtyBits bitMask,
301                             const gl::state::ExtendedDirtyBits extendedDirtyBits,
302                             const gl::state::ExtendedDirtyBits extendedBitMask,
303                             gl::Command command) override;
304 
305     // Disjoint timer queries
306     GLint getGPUDisjoint() override;
307     GLint64 getTimestamp() override;
308 
309     // Context switching
310     angle::Result onMakeCurrent(const gl::Context *context) override;
311     angle::Result onUnMakeCurrent(const gl::Context *context) override;
312     angle::Result onSurfaceUnMakeCurrent(WindowSurfaceVk *surface);
313     angle::Result onSurfaceUnMakeCurrent(OffscreenSurfaceVk *surface);
314 
315     // Native capabilities, unmodified by gl::Context.
316     gl::Caps getNativeCaps() const override;
317     const gl::TextureCapsMap &getNativeTextureCaps() const override;
318     const gl::Extensions &getNativeExtensions() const override;
319     const gl::Limitations &getNativeLimitations() const override;
320     const ShPixelLocalStorageOptions &getNativePixelLocalStorageOptions() const override;
321 
322     // Shader creation
323     CompilerImpl *createCompiler() override;
324     ShaderImpl *createShader(const gl::ShaderState &state) override;
325     ProgramImpl *createProgram(const gl::ProgramState &state) override;
326     ProgramExecutableImpl *createProgramExecutable(
327         const gl::ProgramExecutable *executable) override;
328 
329     // Framebuffer creation
330     FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override;
331 
332     // Texture creation
333     TextureImpl *createTexture(const gl::TextureState &state) override;
334 
335     // Renderbuffer creation
336     RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override;
337 
338     // Buffer creation
339     BufferImpl *createBuffer(const gl::BufferState &state) override;
340 
341     // Vertex Array creation
342     VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override;
343 
344     // Query and Fence creation
345     QueryImpl *createQuery(gl::QueryType type) override;
346     FenceNVImpl *createFenceNV() override;
347     SyncImpl *createSync() override;
348 
349     // Transform Feedback creation
350     TransformFeedbackImpl *createTransformFeedback(
351         const gl::TransformFeedbackState &state) override;
352 
353     // Sampler object creation
354     SamplerImpl *createSampler(const gl::SamplerState &state) override;
355 
356     // Program Pipeline object creation
357     ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
358 
359     // Memory object creation.
360     MemoryObjectImpl *createMemoryObject() override;
361 
362     // Semaphore creation.
363     SemaphoreImpl *createSemaphore() override;
364 
365     // Overlay creation.
366     OverlayImpl *createOverlay(const gl::OverlayState &state) override;
367 
368     angle::Result dispatchCompute(const gl::Context *context,
369                                   GLuint numGroupsX,
370                                   GLuint numGroupsY,
371                                   GLuint numGroupsZ) override;
372     angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;
373 
374     angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
375     angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
376 
invalidateTexture(gl::TextureType target)377     ANGLE_INLINE void invalidateTexture(gl::TextureType target) override {}
378 
hasDisplayTextureShareGroup()379     bool hasDisplayTextureShareGroup() const { return mState.hasDisplayTextureShareGroup(); }
380 
381     // EXT_shader_framebuffer_fetch_non_coherent
382     void framebufferFetchBarrier() override;
383 
384     // KHR_blend_equation_advanced
385     void blendBarrier() override;
386 
387     // GL_ANGLE_vulkan_image
388     angle::Result acquireTextures(const gl::Context *context,
389                                   const gl::TextureBarrierVector &textureBarriers) override;
390     angle::Result releaseTextures(const gl::Context *context,
391                                   gl::TextureBarrierVector *textureBarriers) override;
392 
393     // Sets effective Context Priority. Changed by ShareGroupVk.
setPriority(egl::ContextPriority newPriority)394     void setPriority(egl::ContextPriority newPriority)
395     {
396         mContextPriority  = newPriority;
397         mDeviceQueueIndex = mRenderer->getDeviceQueueIndex(mContextPriority);
398     }
399 
400     VkDevice getDevice() const;
401     // Effective Context Priority
getPriority()402     egl::ContextPriority getPriority() const { return mContextPriority; }
getProtectionType()403     vk::ProtectionType getProtectionType() const { return mProtectionType; }
404 
getFeatures()405     ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); }
406 
invalidateVertexAndIndexBuffers()407     ANGLE_INLINE void invalidateVertexAndIndexBuffers()
408     {
409         mGraphicsDirtyBits |= kIndexAndVertexDirtyBits;
410     }
411 
412     angle::Result onVertexBufferChange(const vk::BufferHelper *vertexBuffer);
413 
414     angle::Result onVertexAttributeChange(size_t attribIndex,
415                                           GLuint stride,
416                                           GLuint divisor,
417                                           angle::FormatID format,
418                                           bool compressed,
419                                           GLuint relativeOffset,
420                                           const vk::BufferHelper *vertexBuffer);
421 
422     void invalidateDefaultAttribute(size_t attribIndex);
423     void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
424     angle::Result onFramebufferChange(FramebufferVk *framebufferVk, gl::Command command);
425     void onDrawFramebufferRenderPassDescChange(FramebufferVk *framebufferVk,
426                                                bool *renderPassDescChangedOut);
onHostVisibleBufferWrite()427     void onHostVisibleBufferWrite() { mIsAnyHostVisibleBufferWritten = true; }
428 
429     void invalidateCurrentTransformFeedbackBuffers();
430     void onTransformFeedbackStateChanged();
431     angle::Result onBeginTransformFeedback(
432         size_t bufferCount,
433         const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers,
434         const gl::TransformFeedbackBuffersArray<vk::BufferHelper> &counterBuffers);
435     void onEndTransformFeedback();
436     angle::Result onPauseTransformFeedback();
437     void pauseTransformFeedbackIfActiveUnpaused();
438 
onColorAccessChange()439     void onColorAccessChange() { mGraphicsDirtyBits |= kColorAccessChangeDirtyBits; }
onDepthStencilAccessChange()440     void onDepthStencilAccessChange() { mGraphicsDirtyBits |= kDepthStencilAccessChangeDirtyBits; }
441 
442     // When UtilsVk issues draw or dispatch calls, it binds a new pipeline and descriptor sets that
443     // the context is not aware of.  These functions are called to make sure the pipeline and
444     // affected descriptor set bindings are dirtied for the next application draw/dispatch call.
445     void invalidateGraphicsPipelineBinding();
446     void invalidateComputePipelineBinding();
447     void invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet);
448     void invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet);
449     void invalidateAllDynamicState();
450     angle::Result updateRenderPassDepthFeedbackLoopMode(
451         UpdateDepthFeedbackLoopReason depthReason,
452         UpdateDepthFeedbackLoopReason stencilReason);
453 
454     angle::Result optimizeRenderPassForPresent(vk::ImageViewHelper *colorImageView,
455                                                vk::ImageHelper *colorImage,
456                                                vk::ImageHelper *colorImageMS,
457                                                vk::PresentMode presentMode,
458                                                bool *imageResolved);
459 
460     vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);
461 
462     const VkClearValue &getClearColorValue() const;
463     const VkClearValue &getClearDepthStencilValue() const;
464     gl::BlendStateExt::ColorMaskStorage::Type getClearColorMasks() const;
getScissor()465     const VkRect2D &getScissor() const { return mScissor; }
466     angle::Result getIncompleteTexture(const gl::Context *context,
467                                        gl::TextureType type,
468                                        gl::SamplerFormat format,
469                                        gl::Texture **textureOut);
470     void updateColorMasks();
471     void updateBlendFuncsAndEquations();
472 
473     void handleError(VkResult errorCode,
474                      const char *file,
475                      const char *function,
476                      unsigned int line) override;
477 
478     angle::Result onIndexBufferChange(const vk::BufferHelper *currentIndexBuffer);
479 
480     angle::Result flushAndSubmitCommands(const vk::Semaphore *semaphore,
481                                          const vk::SharedExternalFence *externalFence,
482                                          RenderPassClosureReason renderPassClosureReason);
483 
484     angle::Result finishImpl(RenderPassClosureReason renderPassClosureReason);
485 
486     void addWaitSemaphore(VkSemaphore semaphore, VkPipelineStageFlags stageMask);
487 
488     template <typename T>
addGarbage(T * object)489     void addGarbage(T *object)
490     {
491         if (object->valid())
492         {
493             mCurrentGarbage.emplace_back(vk::GetGarbage(object));
494         }
495     }
496 
497     angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc,
498                                           const vk::RenderPass **renderPassOut);
499     angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc,
500                                        const vk::AttachmentOpsArray &ops,
501                                        const vk::RenderPass **renderPassOut);
502 
getShaderLibrary()503     vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; }
getUtils()504     UtilsVk &getUtils() { return mUtils; }
505 
506     angle::Result getTimestamp(uint64_t *timestampOut);
507 
508     // Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries.
509     // The events are queued until the query results are available.  Possible values for `phase`
510     // are TRACE_EVENT_PHASE_*
traceGpuEvent(vk::OutsideRenderPassCommandBuffer * commandBuffer,char phase,const EventName & name)511     ANGLE_INLINE angle::Result traceGpuEvent(vk::OutsideRenderPassCommandBuffer *commandBuffer,
512                                              char phase,
513                                              const EventName &name)
514     {
515         if (mGpuEventsEnabled)
516             return traceGpuEventImpl(commandBuffer, phase, name);
517         return angle::Result::Continue;
518     }
519 
getDebug()520     const gl::Debug &getDebug() const { return mState.getDebug(); }
getOverlay()521     const gl::OverlayType *getOverlay() const { return mState.getOverlay(); }
522 
523     angle::Result onBufferReleaseToExternal(const vk::BufferHelper &buffer);
524     angle::Result onImageReleaseToExternal(const vk::ImageHelper &image);
525 
onImageRenderPassRead(VkImageAspectFlags aspectFlags,vk::ImageLayout imageLayout,vk::ImageHelper * image)526     void onImageRenderPassRead(VkImageAspectFlags aspectFlags,
527                                vk::ImageLayout imageLayout,
528                                vk::ImageHelper *image)
529     {
530         ASSERT(mRenderPassCommands->started());
531         mRenderPassCommands->imageRead(this, aspectFlags, imageLayout, image);
532     }
533 
onImageRenderPassWrite(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,VkImageAspectFlags aspectFlags,vk::ImageLayout imageLayout,vk::ImageHelper * image)534     void onImageRenderPassWrite(gl::LevelIndex level,
535                                 uint32_t layerStart,
536                                 uint32_t layerCount,
537                                 VkImageAspectFlags aspectFlags,
538                                 vk::ImageLayout imageLayout,
539                                 vk::ImageHelper *image)
540     {
541         ASSERT(mRenderPassCommands->started());
542         mRenderPassCommands->imageWrite(this, level, layerStart, layerCount, aspectFlags,
543                                         imageLayout, image);
544     }
545 
onColorDraw(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,vk::ImageHelper * resolveImage,UniqueSerial imageSiblingSerial,vk::PackedAttachmentIndex packedAttachmentIndex)546     void onColorDraw(gl::LevelIndex level,
547                      uint32_t layerStart,
548                      uint32_t layerCount,
549                      vk::ImageHelper *image,
550                      vk::ImageHelper *resolveImage,
551                      UniqueSerial imageSiblingSerial,
552                      vk::PackedAttachmentIndex packedAttachmentIndex)
553     {
554         ASSERT(mRenderPassCommands->started());
555         mRenderPassCommands->colorImagesDraw(level, layerStart, layerCount, image, resolveImage,
556                                              imageSiblingSerial, packedAttachmentIndex);
557     }
onColorResolve(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,VkImageView view,UniqueSerial imageSiblingSerial,size_t colorIndexGL)558     void onColorResolve(gl::LevelIndex level,
559                         uint32_t layerStart,
560                         uint32_t layerCount,
561                         vk::ImageHelper *image,
562                         VkImageView view,
563                         UniqueSerial imageSiblingSerial,
564                         size_t colorIndexGL)
565     {
566         ASSERT(mRenderPassCommands->started());
567         mRenderPassCommands->addColorResolveAttachment(colorIndexGL, image, view, level, layerStart,
568                                                        layerCount, imageSiblingSerial);
569     }
onDepthStencilDraw(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,vk::ImageHelper * resolveImage,UniqueSerial imageSiblingSerial)570     void onDepthStencilDraw(gl::LevelIndex level,
571                             uint32_t layerStart,
572                             uint32_t layerCount,
573                             vk::ImageHelper *image,
574                             vk::ImageHelper *resolveImage,
575                             UniqueSerial imageSiblingSerial)
576     {
577         ASSERT(mRenderPassCommands->started());
578         mRenderPassCommands->depthStencilImagesDraw(level, layerStart, layerCount, image,
579                                                     resolveImage, imageSiblingSerial);
580     }
onDepthStencilResolve(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,VkImageAspectFlags aspects,vk::ImageHelper * image,VkImageView view,UniqueSerial imageSiblingSerial)581     void onDepthStencilResolve(gl::LevelIndex level,
582                                uint32_t layerStart,
583                                uint32_t layerCount,
584                                VkImageAspectFlags aspects,
585                                vk::ImageHelper *image,
586                                VkImageView view,
587                                UniqueSerial imageSiblingSerial)
588     {
589         ASSERT(mRenderPassCommands->started());
590         mRenderPassCommands->addDepthStencilResolveAttachment(
591             image, view, aspects, level, layerStart, layerCount, imageSiblingSerial);
592     }
593 
onFragmentShadingRateRead(vk::ImageHelper * image)594     void onFragmentShadingRateRead(vk::ImageHelper *image)
595     {
596         ASSERT(mRenderPassCommands->started());
597         mRenderPassCommands->fragmentShadingRateImageRead(image);
598     }
599 
finalizeImageLayout(const vk::ImageHelper * image,UniqueSerial imageSiblingSerial)600     void finalizeImageLayout(const vk::ImageHelper *image, UniqueSerial imageSiblingSerial)
601     {
602         if (mRenderPassCommands->started())
603         {
604             mRenderPassCommands->finalizeImageLayout(this, image, imageSiblingSerial);
605         }
606     }
607 
getOutsideRenderPassCommandBuffer(const vk::CommandBufferAccess & access,vk::OutsideRenderPassCommandBuffer ** commandBufferOut)608     angle::Result getOutsideRenderPassCommandBuffer(
609         const vk::CommandBufferAccess &access,
610         vk::OutsideRenderPassCommandBuffer **commandBufferOut)
611     {
612         ANGLE_TRY(onResourceAccess(access));
613         *commandBufferOut = &mOutsideRenderPassCommands->getCommandBuffer();
614         return angle::Result::Continue;
615     }
616 
getOutsideRenderPassCommandBufferHelper(const vk::CommandBufferAccess & access,vk::OutsideRenderPassCommandBufferHelper ** commandBufferHelperOut)617     angle::Result getOutsideRenderPassCommandBufferHelper(
618         const vk::CommandBufferAccess &access,
619         vk::OutsideRenderPassCommandBufferHelper **commandBufferHelperOut)
620     {
621         ANGLE_TRY(onResourceAccess(access));
622         *commandBufferHelperOut = mOutsideRenderPassCommands;
623         return angle::Result::Continue;
624     }
625 
trackImageWithOutsideRenderPassEvent(vk::ImageHelper * image)626     void trackImageWithOutsideRenderPassEvent(vk::ImageHelper *image)
627     {
628         if (mRenderer->getFeatures().useVkEventForImageBarrier.enabled)
629         {
630             mOutsideRenderPassCommands->trackImageWithEvent(this, image);
631         }
632     }
submitStagedTextureUpdates()633     angle::Result submitStagedTextureUpdates()
634     {
635         // Staged updates are recorded in outside RP cammand buffer, submit them.
636         return flushOutsideRenderPassCommands();
637     }
638 
onEGLImageQueueChange()639     angle::Result onEGLImageQueueChange()
640     {
641         // Flush the barrier inserted to change the queue and layout of an EGL image.  Another
642         // thread may start using this image without issuing a sync object.
643         return flushOutsideRenderPassCommands();
644     }
645 
646     angle::Result beginNewRenderPass(vk::RenderPassFramebuffer &&framebuffer,
647                                      const gl::Rectangle &renderArea,
648                                      const vk::RenderPassDesc &renderPassDesc,
649                                      const vk::AttachmentOpsArray &renderPassAttachmentOps,
650                                      const vk::PackedAttachmentCount colorAttachmentCount,
651                                      const vk::PackedAttachmentIndex depthStencilAttachmentIndex,
652                                      const vk::PackedClearValuesArray &clearValues,
653                                      vk::RenderPassCommandBuffer **commandBufferOut);
654 
disableRenderPassReactivation()655     void disableRenderPassReactivation() { mAllowRenderPassToReactivate = false; }
656 
657     // Only returns true if we have a started RP and we've run setupDraw.
hasActiveRenderPass()658     bool hasActiveRenderPass() const
659     {
660         // If mRenderPassCommandBuffer is not null, mRenderPassCommands must already started, we
661         // call this active render pass. A started render pass will have null
662         // mRenderPassCommandBuffer after onRenderPassFinished call, we call this state started but
663         // inactive.
664         ASSERT(mRenderPassCommandBuffer == nullptr || mRenderPassCommands->started());
665         // Checking mRenderPassCommandBuffer ensures we've called setupDraw.
666         return mRenderPassCommandBuffer != nullptr;
667     }
668 
hasStartedRenderPassWithQueueSerial(const QueueSerial & queueSerial)669     bool hasStartedRenderPassWithQueueSerial(const QueueSerial &queueSerial) const
670     {
671         return mRenderPassCommands->started() &&
672                mRenderPassCommands->getQueueSerial() == queueSerial;
673     }
hasStartedRenderPassWithDefaultFramebuffer()674     bool hasStartedRenderPassWithDefaultFramebuffer() const
675     {
676         // WindowSurfaceVk caches its own framebuffers and guarantees that render passes are not
677         // kept open between frames (including when a swapchain is recreated and framebuffer handles
678         // change).  It is therefore safe to verify an open render pass just by checking if it
679         // originated from the default framebuffer.
680         return mRenderPassCommands->started() && mRenderPassCommands->isDefault();
681     }
682 
isRenderPassStartedAndUsesBuffer(const vk::BufferHelper & buffer)683     bool isRenderPassStartedAndUsesBuffer(const vk::BufferHelper &buffer) const
684     {
685         return mRenderPassCommands->started() && mRenderPassCommands->usesBuffer(buffer);
686     }
687 
isRenderPassStartedAndUsesBufferForWrite(const vk::BufferHelper & buffer)688     bool isRenderPassStartedAndUsesBufferForWrite(const vk::BufferHelper &buffer) const
689     {
690         return mRenderPassCommands->started() && mRenderPassCommands->usesBufferForWrite(buffer);
691     }
692 
isRenderPassStartedAndUsesImage(const vk::ImageHelper & image)693     bool isRenderPassStartedAndUsesImage(const vk::ImageHelper &image) const
694     {
695         return mRenderPassCommands->started() && mRenderPassCommands->usesImage(image);
696     }
697 
getStartedRenderPassCommands()698     vk::RenderPassCommandBufferHelper &getStartedRenderPassCommands()
699     {
700         ASSERT(mRenderPassCommands->started());
701         return *mRenderPassCommands;
702     }
703 
704     uint32_t getCurrentSubpassIndex() const;
705     uint32_t getCurrentViewCount() const;
706 
707     // Initial Context Priority. Used for EGL_CONTEXT_PRIORITY_LEVEL_IMG attribute.
getContextPriority()708     egl::ContextPriority getContextPriority() const override { return mInitialContextPriority; }
709     angle::Result startRenderPass(gl::Rectangle renderArea,
710                                   vk::RenderPassCommandBuffer **commandBufferOut,
711                                   bool *renderPassDescChangedOut);
712     angle::Result startNextSubpass();
713     angle::Result flushCommandsAndEndRenderPass(RenderPassClosureReason reason);
714     angle::Result flushCommandsAndEndRenderPassWithoutSubmit(RenderPassClosureReason reason);
715     angle::Result flushAndSubmitOutsideRenderPassCommands();
716 
717     angle::Result syncExternalMemory();
718 
719     // Either issue a submission or defer it when a sync object is initialized.  If deferred, a
720     // submission will have to be incurred during client wait.
721     angle::Result onSyncObjectInit(vk::SyncHelper *syncHelper, SyncFenceScope scope);
722     // Called when a sync object is waited on while its submission was deffered in onSyncObjectInit.
723     // It's a no-op if this context doesn't have a pending submission.  Note that due to
724     // mHasDeferredFlush being set, flushing the render pass leads to a submission automatically.
725     angle::Result flushCommandsAndEndRenderPassIfDeferredSyncInit(RenderPassClosureReason reason);
726 
727     void addCommandBufferDiagnostics(const std::string &commandBufferDiagnostics);
728 
729     VkIndexType getVkIndexType(gl::DrawElementsType glIndexType) const;
730     size_t getVkIndexTypeSize(gl::DrawElementsType glIndexType) const;
731     bool shouldConvertUint8VkIndexType(gl::DrawElementsType glIndexType) const;
732 
733     bool isRobustResourceInitEnabled() const;
hasRobustAccess()734     bool hasRobustAccess() const { return mState.hasRobustAccess(); }
735 
736     // Queries that begin and end automatically with render pass start and end
737     angle::Result beginRenderPassQuery(QueryVk *queryVk);
738     angle::Result endRenderPassQuery(QueryVk *queryVk);
739     void pauseRenderPassQueriesIfActive();
740     angle::Result resumeRenderPassQueriesIfActive();
741     angle::Result resumeXfbRenderPassQueriesIfActive();
742     bool doesPrimitivesGeneratedQuerySupportRasterizerDiscard() const;
743     bool isEmulatingRasterizerDiscardDuringPrimitivesGeneratedQuery(
744         bool isPrimitivesGeneratedQueryActive) const;
745 
746     // Used by QueryVk to share query helpers between transform feedback queries.
747     QueryVk *getActiveRenderPassQuery(gl::QueryType queryType) const;
748 
749     void syncObjectPerfCounters(const angle::VulkanPerfCounters &commandQueuePerfCounters);
750     void updateOverlayOnPresent();
751     void addOverlayUsedBuffersCount(vk::CommandBufferHelperCommon *commandBuffer);
752 
753     // For testing only.
754     void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
755 
getEmptyBuffer()756     vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; }
757 
758     // Keeping track of the buffer copy size. Used to determine when to submit the outside command
759     // buffer.
760     angle::Result onCopyUpdate(VkDeviceSize size, bool *commandBufferWasFlushedOut);
761 
762     // Implementation of MultisampleTextureInitializer
763     angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
764                                                       gl::Texture *glTexture) override;
765 
766     // TODO(http://anglebug.com/42264159): rework updateActiveTextures(), createPipelineLayout(),
767     // handleDirtyGraphicsPipeline(), and ProgramPipelineVk::link().
resetCurrentGraphicsPipeline()768     void resetCurrentGraphicsPipeline()
769     {
770         mCurrentGraphicsPipeline        = nullptr;
771         mCurrentGraphicsPipelineShaders = nullptr;
772     }
773 
774     void onProgramExecutableReset(ProgramExecutableVk *executableVk);
775 
776     angle::Result handleGraphicsEventLog(GraphicsEventCmdBuf queryEventType);
777 
778     void flushDescriptorSetUpdates();
779 
getDefaultBufferPool(VkDeviceSize size,uint32_t memoryTypeIndex,BufferUsageType usageType)780     vk::BufferPool *getDefaultBufferPool(VkDeviceSize size,
781                                          uint32_t memoryTypeIndex,
782                                          BufferUsageType usageType)
783     {
784         return mShareGroupVk->getDefaultBufferPool(size, memoryTypeIndex, usageType);
785     }
786 
allocateStreamedVertexBuffer(size_t attribIndex,size_t bytesToAllocate,vk::BufferHelper ** vertexBufferOut)787     angle::Result allocateStreamedVertexBuffer(size_t attribIndex,
788                                                size_t bytesToAllocate,
789                                                vk::BufferHelper **vertexBufferOut)
790     {
791         bool newBufferOut;
792         ANGLE_TRY(mStreamedVertexBuffers[attribIndex].allocate(this, bytesToAllocate,
793                                                                vertexBufferOut, &newBufferOut));
794         if (newBufferOut)
795         {
796             mHasInFlightStreamedVertexBuffers.set(attribIndex);
797         }
798         return angle::Result::Continue;
799     }
800 
801     // Put the context in framebuffer fetch mode.  If the permanentlySwitchToFramebufferFetchMode
802     // feature is enabled, this is done on first encounter of framebuffer fetch, and makes the
803     // context use framebuffer-fetch-enabled render passes from here on.
804     angle::Result switchToColorFramebufferFetchMode(bool hasColorFramebufferFetch);
isInColorFramebufferFetchMode()805     bool isInColorFramebufferFetchMode() const
806     {
807         ASSERT(!getFeatures().preferDynamicRendering.enabled);
808         return mIsInColorFramebufferFetchMode;
809     }
810 
811     const angle::PerfMonitorCounterGroups &getPerfMonitorCounters() override;
812 
813     void resetPerFramePerfCounters();
814 
815     // Accumulate cache stats for a specific cache
accumulateCacheStats(VulkanCacheType cache,const CacheStats & stats)816     void accumulateCacheStats(VulkanCacheType cache, const CacheStats &stats)
817     {
818         mVulkanCacheStats[cache].accumulate(stats);
819     }
820 
821     // Whether VK_EXT_pipeline_robustness should be used to enable robust buffer access in the
822     // pipeline.
pipelineRobustness()823     vk::PipelineRobustness pipelineRobustness() const
824     {
825         return getFeatures().supportsPipelineRobustness.enabled && mState.hasRobustAccess()
826                    ? vk::PipelineRobustness::Robust
827                    : vk::PipelineRobustness::NonRobust;
828     }
829     // Whether VK_EXT_pipeline_protected_access should be used to restrict the pipeline to protected
830     // command buffers.  Note that when false, if the extension is supported, the pipeline can be
831     // restricted to unprotected command buffers.
pipelineProtectedAccess()832     vk::PipelineProtectedAccess pipelineProtectedAccess() const
833     {
834         return getFeatures().supportsPipelineProtectedAccess.enabled && mState.hasProtectedContent()
835                    ? vk::PipelineProtectedAccess::Protected
836                    : vk::PipelineProtectedAccess::Unprotected;
837     }
838 
getImageLoadContext()839     const angle::ImageLoadContext &getImageLoadContext() const { return mImageLoadContext; }
840 
841     bool hasUnsubmittedUse(const vk::ResourceUse &use) const;
hasUnsubmittedUse(const vk::Resource & resource)842     bool hasUnsubmittedUse(const vk::Resource &resource) const
843     {
844         return hasUnsubmittedUse(resource.getResourceUse());
845     }
hasUnsubmittedUse(const vk::ReadWriteResource & resource)846     bool hasUnsubmittedUse(const vk::ReadWriteResource &resource) const
847     {
848         return hasUnsubmittedUse(resource.getResourceUse());
849     }
850 
getLastSubmittedQueueSerial()851     const QueueSerial &getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; }
getSubmittedResourceUse()852     const vk::ResourceUse &getSubmittedResourceUse() const { return mSubmittedResourceUse; }
853 
854     // Uploading mutable mipmap textures is currently restricted to single-context applications.
isEligibleForMutableTextureFlush()855     bool isEligibleForMutableTextureFlush() const
856     {
857         return getFeatures().mutableMipmapTextureUpload.enabled && !hasDisplayTextureShareGroup() &&
858                mShareGroupVk->getContexts().size() == 1;
859     }
860 
getDepthStencilAttachmentFlags()861     vk::RenderPassUsageFlags getDepthStencilAttachmentFlags() const
862     {
863         return mDepthStencilAttachmentFlags;
864     }
865 
isDitherEnabled()866     bool isDitherEnabled() { return mState.isDitherEnabled(); }
867 
868     // The following functions try to allocate memory for buffers and images. If they fail due to
869     // OOM errors, they will try other options for memory allocation.
870     angle::Result initBufferAllocation(vk::BufferHelper *bufferHelper,
871                                        uint32_t memoryTypeIndex,
872                                        size_t allocationSize,
873                                        size_t alignment,
874                                        BufferUsageType bufferUsageType);
875     angle::Result initImageAllocation(vk::ImageHelper *imageHelper,
876                                       bool hasProtectedContent,
877                                       const vk::MemoryProperties &memoryProperties,
878                                       VkMemoryPropertyFlags flags,
879                                       vk::MemoryAllocationType allocationType);
880 
881     angle::Result releaseBufferAllocation(vk::BufferHelper *bufferHelper);
882 
883     // Helper functions to initialize a buffer for a specific usage
884     // Suballocate a host visible buffer with alignment good for copyBuffer.
885     angle::Result initBufferForBufferCopy(vk::BufferHelper *bufferHelper,
886                                           size_t size,
887                                           vk::MemoryCoherency coherency);
888     // Suballocate a host visible buffer with alignment good for copyImage.
889     angle::Result initBufferForImageCopy(vk::BufferHelper *bufferHelper,
890                                          size_t size,
891                                          vk::MemoryCoherency coherency,
892                                          angle::FormatID formatId,
893                                          VkDeviceSize *offset,
894                                          uint8_t **dataPtr);
895     // Suballocate a buffer with alignment good for shader storage or copyBuffer.
896     angle::Result initBufferForVertexConversion(ConversionBuffer *conversionBuffer,
897                                                 size_t size,
898                                                 vk::MemoryHostVisibility hostVisibility);
899 
900     // In the event of collecting too much garbage, we should flush the garbage so it can be freed.
901     void addToPendingImageGarbage(vk::ResourceUse use, VkDeviceSize size);
902 
903     bool hasExcessPendingGarbage() const;
904 
905     angle::Result onFramebufferBoundary(const gl::Context *contextGL);
906 
getCurrentFrameCount()907     uint32_t getCurrentFrameCount() const { return mShareGroupVk->getCurrentFrameCount(); }
908 
909   private:
910     // Dirty bits.
911     enum DirtyBitType : size_t
912     {
913         // Dirty bits that must be processed before the render pass is started.  The handlers for
914         // these dirty bits don't record any commands.
915 
916         // the AnySamplePassed render pass query has been ended.
917         DIRTY_BIT_ANY_SAMPLE_PASSED_QUERY_END,
918         // A glMemoryBarrier has been called and command buffers may need flushing.
919         DIRTY_BIT_MEMORY_BARRIER,
920         // Update default attribute buffers.
921         DIRTY_BIT_DEFAULT_ATTRIBS,
922         // The pipeline has changed and needs to be recreated.  This dirty bit may close the render
923         // pass.
924         DIRTY_BIT_PIPELINE_DESC,
925         // Support for depth/stencil read-only feedback loop.  When depth/stencil access changes,
926         // the render pass may need closing.
927         DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE,
928 
929         // Start the render pass.
930         DIRTY_BIT_RENDER_PASS,
931 
932         // Dirty bits that must be processed after the render pass is started.  Their handlers
933         // record commands.
934         DIRTY_BIT_EVENT_LOG,
935         // Update color and depth/stencil accesses in the render pass.
936         DIRTY_BIT_COLOR_ACCESS,
937         DIRTY_BIT_DEPTH_STENCIL_ACCESS,
938         // Pipeline needs to rebind because a new command buffer has been allocated, or UtilsVk has
939         // changed the binding.  The pipeline itself doesn't need to be recreated.
940         DIRTY_BIT_PIPELINE_BINDING,
941         DIRTY_BIT_TEXTURES,
942         DIRTY_BIT_VERTEX_BUFFERS,
943         DIRTY_BIT_INDEX_BUFFER,
944         DIRTY_BIT_UNIFORMS,
945         DIRTY_BIT_DRIVER_UNIFORMS,
946         // Shader resources excluding textures, which are handled separately.
947         DIRTY_BIT_SHADER_RESOURCES,
948         DIRTY_BIT_UNIFORM_BUFFERS,
949         DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
950         DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME,
951         DIRTY_BIT_DESCRIPTOR_SETS,
952         DIRTY_BIT_FRAMEBUFFER_FETCH_BARRIER,
953         DIRTY_BIT_BLEND_BARRIER,
954 
955         // Dynamic state
956         // - In core Vulkan 1.0
957         DIRTY_BIT_DYNAMIC_VIEWPORT,
958         DIRTY_BIT_DYNAMIC_SCISSOR,
959         DIRTY_BIT_DYNAMIC_LINE_WIDTH,
960         DIRTY_BIT_DYNAMIC_DEPTH_BIAS,
961         DIRTY_BIT_DYNAMIC_BLEND_CONSTANTS,
962         DIRTY_BIT_DYNAMIC_STENCIL_COMPARE_MASK,
963         DIRTY_BIT_DYNAMIC_STENCIL_WRITE_MASK,
964         DIRTY_BIT_DYNAMIC_STENCIL_REFERENCE,
965         // - In VK_EXT_extended_dynamic_state
966         DIRTY_BIT_DYNAMIC_CULL_MODE,
967         DIRTY_BIT_DYNAMIC_FRONT_FACE,
968         DIRTY_BIT_DYNAMIC_DEPTH_TEST_ENABLE,
969         DIRTY_BIT_DYNAMIC_DEPTH_WRITE_ENABLE,
970         DIRTY_BIT_DYNAMIC_DEPTH_COMPARE_OP,
971         DIRTY_BIT_DYNAMIC_STENCIL_TEST_ENABLE,
972         DIRTY_BIT_DYNAMIC_STENCIL_OP,
973         // - In VK_EXT_extended_dynamic_state2
974         DIRTY_BIT_DYNAMIC_RASTERIZER_DISCARD_ENABLE,
975         DIRTY_BIT_DYNAMIC_DEPTH_BIAS_ENABLE,
976         DIRTY_BIT_DYNAMIC_LOGIC_OP,
977         DIRTY_BIT_DYNAMIC_PRIMITIVE_RESTART_ENABLE,
978         // - In VK_KHR_fragment_shading_rate
979         DIRTY_BIT_DYNAMIC_FRAGMENT_SHADING_RATE,
980 
981         DIRTY_BIT_MAX,
982     };
983 
984     // Dirty bit handlers that can break the render pass must always be specified before
985     // DIRTY_BIT_RENDER_PASS.
986     static_assert(
987         DIRTY_BIT_ANY_SAMPLE_PASSED_QUERY_END < DIRTY_BIT_RENDER_PASS,
988         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
989     static_assert(
990         DIRTY_BIT_MEMORY_BARRIER < DIRTY_BIT_RENDER_PASS,
991         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
992     static_assert(
993         DIRTY_BIT_DEFAULT_ATTRIBS < DIRTY_BIT_RENDER_PASS,
994         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
995     static_assert(
996         DIRTY_BIT_PIPELINE_DESC < DIRTY_BIT_RENDER_PASS,
997         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
998     static_assert(
999         DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE < DIRTY_BIT_RENDER_PASS,
1000         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
1001 
1002     // Dirty bit handlers that record commands or otherwise expect to manipulate the render pass
1003     // that will be used for the draw call must be specified after DIRTY_BIT_RENDER_PASS.
1004     static_assert(DIRTY_BIT_EVENT_LOG > DIRTY_BIT_RENDER_PASS,
1005                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1006     static_assert(DIRTY_BIT_COLOR_ACCESS > DIRTY_BIT_RENDER_PASS,
1007                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1008     static_assert(DIRTY_BIT_DEPTH_STENCIL_ACCESS > DIRTY_BIT_RENDER_PASS,
1009                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1010     static_assert(DIRTY_BIT_PIPELINE_BINDING > DIRTY_BIT_RENDER_PASS,
1011                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1012     static_assert(DIRTY_BIT_TEXTURES > DIRTY_BIT_RENDER_PASS,
1013                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1014     static_assert(DIRTY_BIT_VERTEX_BUFFERS > DIRTY_BIT_RENDER_PASS,
1015                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1016     static_assert(DIRTY_BIT_INDEX_BUFFER > DIRTY_BIT_RENDER_PASS,
1017                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1018     static_assert(DIRTY_BIT_DRIVER_UNIFORMS > DIRTY_BIT_RENDER_PASS,
1019                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1020     static_assert(DIRTY_BIT_SHADER_RESOURCES > DIRTY_BIT_RENDER_PASS,
1021                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1022     static_assert(
1023         DIRTY_BIT_UNIFORM_BUFFERS > DIRTY_BIT_SHADER_RESOURCES,
1024         "Uniform buffer using dirty bit must be handled after the shader resource dirty bit");
1025     static_assert(DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS > DIRTY_BIT_RENDER_PASS,
1026                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1027     static_assert(DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME > DIRTY_BIT_RENDER_PASS,
1028                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1029     static_assert(DIRTY_BIT_DESCRIPTOR_SETS > DIRTY_BIT_RENDER_PASS,
1030                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1031     static_assert(DIRTY_BIT_UNIFORMS > DIRTY_BIT_RENDER_PASS,
1032                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1033     static_assert(DIRTY_BIT_FRAMEBUFFER_FETCH_BARRIER > DIRTY_BIT_RENDER_PASS,
1034                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1035     static_assert(DIRTY_BIT_BLEND_BARRIER > DIRTY_BIT_RENDER_PASS,
1036                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1037     static_assert(DIRTY_BIT_DYNAMIC_VIEWPORT > DIRTY_BIT_RENDER_PASS,
1038                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1039     static_assert(DIRTY_BIT_DYNAMIC_SCISSOR > DIRTY_BIT_RENDER_PASS,
1040                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1041     static_assert(DIRTY_BIT_DYNAMIC_LINE_WIDTH > DIRTY_BIT_RENDER_PASS,
1042                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1043     static_assert(DIRTY_BIT_DYNAMIC_DEPTH_BIAS > DIRTY_BIT_RENDER_PASS,
1044                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1045     static_assert(DIRTY_BIT_DYNAMIC_BLEND_CONSTANTS > DIRTY_BIT_RENDER_PASS,
1046                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1047     static_assert(DIRTY_BIT_DYNAMIC_STENCIL_COMPARE_MASK > DIRTY_BIT_RENDER_PASS,
1048                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1049     static_assert(DIRTY_BIT_DYNAMIC_STENCIL_WRITE_MASK > DIRTY_BIT_RENDER_PASS,
1050                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1051     static_assert(DIRTY_BIT_DYNAMIC_STENCIL_REFERENCE > DIRTY_BIT_RENDER_PASS,
1052                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1053     static_assert(DIRTY_BIT_DYNAMIC_CULL_MODE > DIRTY_BIT_RENDER_PASS,
1054                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1055     static_assert(DIRTY_BIT_DYNAMIC_FRONT_FACE > DIRTY_BIT_RENDER_PASS,
1056                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1057     static_assert(DIRTY_BIT_DYNAMIC_DEPTH_TEST_ENABLE > DIRTY_BIT_RENDER_PASS,
1058                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1059     static_assert(DIRTY_BIT_DYNAMIC_DEPTH_WRITE_ENABLE > DIRTY_BIT_RENDER_PASS,
1060                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1061     static_assert(DIRTY_BIT_DYNAMIC_DEPTH_COMPARE_OP > DIRTY_BIT_RENDER_PASS,
1062                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1063     static_assert(DIRTY_BIT_DYNAMIC_STENCIL_TEST_ENABLE > DIRTY_BIT_RENDER_PASS,
1064                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1065     static_assert(DIRTY_BIT_DYNAMIC_STENCIL_OP > DIRTY_BIT_RENDER_PASS,
1066                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1067     static_assert(DIRTY_BIT_DYNAMIC_RASTERIZER_DISCARD_ENABLE > DIRTY_BIT_RENDER_PASS,
1068                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1069     static_assert(DIRTY_BIT_DYNAMIC_DEPTH_BIAS_ENABLE > DIRTY_BIT_RENDER_PASS,
1070                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1071     static_assert(DIRTY_BIT_DYNAMIC_LOGIC_OP > DIRTY_BIT_RENDER_PASS,
1072                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1073     static_assert(DIRTY_BIT_DYNAMIC_PRIMITIVE_RESTART_ENABLE > DIRTY_BIT_RENDER_PASS,
1074                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1075     static_assert(DIRTY_BIT_DYNAMIC_FRAGMENT_SHADING_RATE > DIRTY_BIT_RENDER_PASS,
1076                   "Render pass using dirty bit must be handled after the render pass dirty bit");
1077 
1078     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
1079 
1080     using GraphicsDirtyBitHandler = angle::Result (
1081         ContextVk::*)(DirtyBits::Iterator *dirtyBitsIterator, DirtyBits dirtyBitMask);
1082     using ComputeDirtyBitHandler =
1083         angle::Result (ContextVk::*)(DirtyBits::Iterator *dirtyBitsIterator);
1084 
1085     // The GpuEventQuery struct holds together a timestamp query and enough data to create a
1086     // trace event based on that. Use traceGpuEvent to insert such queries.  They will be readback
1087     // when the results are available, without inserting a GPU bubble.
1088     //
1089     // - eventName will be the reported name of the event
1090     // - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event).
1091     //   See Google's "Trace Event Format":
1092     //   https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
1093     // - serial is the serial of the batch the query was submitted on.  Until the batch is
1094     //   submitted, the query is not checked to avoid incuring a flush.
1095     struct GpuEventQuery final
1096     {
1097         EventName name;
1098         char phase;
1099         vk::QueryHelper queryHelper;
1100     };
1101 
1102     // Once a query result is available, the timestamp is read and a GpuEvent object is kept until
1103     // the next clock sync, at which point the clock drift is compensated in the results before
1104     // handing them off to the application.
1105     struct GpuEvent final
1106     {
1107         uint64_t gpuTimestampCycles;
1108         std::array<char, kMaxGpuEventNameLen> name;
1109         char phase;
1110     };
1111 
1112     struct GpuClockSyncInfo
1113     {
1114         double gpuTimestampS;
1115         double cpuTimestampS;
1116     };
1117 
1118     class ScopedDescriptorSetUpdates;
1119 
1120     bool isSingleBufferedWindowCurrent() const;
1121     bool hasSomethingToFlush() const;
1122 
1123     angle::Result setupDraw(const gl::Context *context,
1124                             gl::PrimitiveMode mode,
1125                             GLint firstVertexOrInvalid,
1126                             GLsizei vertexOrIndexCount,
1127                             GLsizei instanceCount,
1128                             gl::DrawElementsType indexTypeOrInvalid,
1129                             const void *indices,
1130                             DirtyBits dirtyBitMask);
1131 
1132     angle::Result setupIndexedDraw(const gl::Context *context,
1133                                    gl::PrimitiveMode mode,
1134                                    GLsizei indexCount,
1135                                    GLsizei instanceCount,
1136                                    gl::DrawElementsType indexType,
1137                                    const void *indices);
1138     angle::Result setupIndirectDraw(const gl::Context *context,
1139                                     gl::PrimitiveMode mode,
1140                                     DirtyBits dirtyBitMask,
1141                                     vk::BufferHelper *indirectBuffer);
1142     angle::Result setupIndexedIndirectDraw(const gl::Context *context,
1143                                            gl::PrimitiveMode mode,
1144                                            gl::DrawElementsType indexType,
1145                                            vk::BufferHelper *indirectBuffer);
1146 
1147     angle::Result setupLineLoopIndexedIndirectDraw(const gl::Context *context,
1148                                                    gl::PrimitiveMode mode,
1149                                                    gl::DrawElementsType indexType,
1150                                                    vk::BufferHelper *srcIndexBuffer,
1151                                                    vk::BufferHelper *srcIndirectBuffer,
1152                                                    VkDeviceSize indirectBufferOffset,
1153                                                    vk::BufferHelper **indirectBufferOut);
1154     angle::Result setupLineLoopIndirectDraw(const gl::Context *context,
1155                                             gl::PrimitiveMode mode,
1156                                             vk::BufferHelper *indirectBuffer,
1157                                             VkDeviceSize indirectBufferOffset,
1158                                             vk::BufferHelper **indirectBufferOut);
1159 
1160     angle::Result setupLineLoopDraw(const gl::Context *context,
1161                                     gl::PrimitiveMode mode,
1162                                     GLint firstVertex,
1163                                     GLsizei vertexOrIndexCount,
1164                                     gl::DrawElementsType indexTypeOrInvalid,
1165                                     const void *indices,
1166                                     uint32_t *numIndicesOut);
1167 
1168     angle::Result setupDispatch(const gl::Context *context);
1169 
1170     gl::Rectangle getCorrectedViewport(const gl::Rectangle &viewport) const;
1171     void updateViewport(FramebufferVk *framebufferVk,
1172                         const gl::Rectangle &viewport,
1173                         float nearPlane,
1174                         float farPlane);
1175     void updateFrontFace();
1176     void updateDepthRange(float nearPlane, float farPlane);
1177     void updateMissingOutputsMask();
1178     void updateSampleMaskWithRasterizationSamples(const uint32_t rasterizationSamples);
1179     void updateAlphaToCoverageWithRasterizationSamples(const uint32_t rasterizationSamples);
1180     void updateFrameBufferFetchSamples(const uint32_t prevSamples, const uint32_t curSamples);
1181     void updateFlipViewportDrawFramebuffer(const gl::State &glState);
1182     void updateFlipViewportReadFramebuffer(const gl::State &glState);
1183     void updateSurfaceRotationDrawFramebuffer(const gl::State &glState,
1184                                               const egl::Surface *currentDrawSurface);
1185     void updateSurfaceRotationReadFramebuffer(const gl::State &glState,
1186                                               const egl::Surface *currentReadSurface);
1187 
1188     angle::Result updateActiveTextures(const gl::Context *context, gl::Command command);
1189     template <typename CommandBufferHelperT>
1190     angle::Result updateActiveImages(CommandBufferHelperT *commandBufferHelper);
1191 
invalidateCurrentGraphicsPipeline()1192     ANGLE_INLINE void invalidateCurrentGraphicsPipeline()
1193     {
1194         // Note: DIRTY_BIT_PIPELINE_BINDING will be automatically set if pipeline bind is necessary.
1195         mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE_DESC);
1196     }
1197 
invalidateCurrentComputePipeline()1198     ANGLE_INLINE void invalidateCurrentComputePipeline()
1199     {
1200         mComputeDirtyBits |= kPipelineDescAndBindingDirtyBits;
1201         mCurrentComputePipeline = nullptr;
1202     }
1203 
1204     angle::Result invalidateProgramExecutableHelper(const gl::Context *context);
1205 
1206     void invalidateCurrentDefaultUniforms();
1207     angle::Result invalidateCurrentTextures(const gl::Context *context, gl::Command command);
1208     angle::Result invalidateCurrentShaderResources(gl::Command command);
1209     angle::Result invalidateCurrentShaderUniformBuffers(gl::Command command);
1210     void invalidateGraphicsDriverUniforms();
1211     void invalidateDriverUniforms();
1212 
1213     angle::Result handleNoopDrawEvent() override;
1214 
1215     // Handlers for graphics pipeline dirty bits.
1216     angle::Result handleDirtyGraphicsMemoryBarrier(DirtyBits::Iterator *dirtyBitsIterator,
1217                                                    DirtyBits dirtyBitMask);
1218     angle::Result handleDirtyGraphicsDefaultAttribs(DirtyBits::Iterator *dirtyBitsIterator,
1219                                                     DirtyBits dirtyBitMask);
1220     angle::Result handleDirtyGraphicsPipelineDesc(DirtyBits::Iterator *dirtyBitsIterator,
1221                                                   DirtyBits dirtyBitMask);
1222     angle::Result handleDirtyGraphicsReadOnlyDepthFeedbackLoopMode(
1223         DirtyBits::Iterator *dirtyBitsIterator,
1224         DirtyBits dirtyBitMask);
1225     angle::Result handleDirtyAnySamplePassedQueryEnd(DirtyBits::Iterator *dirtyBitsIterator,
1226                                                      DirtyBits dirtyBitMask);
1227     angle::Result handleDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
1228                                                 DirtyBits dirtyBitMask);
1229     angle::Result handleDirtyGraphicsEventLog(DirtyBits::Iterator *dirtyBitsIterator,
1230                                               DirtyBits dirtyBitMask);
1231     angle::Result handleDirtyGraphicsColorAccess(DirtyBits::Iterator *dirtyBitsIterator,
1232                                                  DirtyBits dirtyBitMask);
1233     angle::Result handleDirtyGraphicsDepthStencilAccess(DirtyBits::Iterator *dirtyBitsIterator,
1234                                                         DirtyBits dirtyBitMask);
1235     angle::Result handleDirtyGraphicsPipelineBinding(DirtyBits::Iterator *dirtyBitsIterator,
1236                                                      DirtyBits dirtyBitMask);
1237     angle::Result handleDirtyGraphicsTextures(DirtyBits::Iterator *dirtyBitsIterator,
1238                                               DirtyBits dirtyBitMask);
1239     angle::Result handleDirtyGraphicsVertexBuffers(DirtyBits::Iterator *dirtyBitsIterator,
1240                                                    DirtyBits dirtyBitMask);
1241     angle::Result handleDirtyGraphicsIndexBuffer(DirtyBits::Iterator *dirtyBitsIterator,
1242                                                  DirtyBits dirtyBitMask);
1243     angle::Result handleDirtyGraphicsDriverUniforms(DirtyBits::Iterator *dirtyBitsIterator,
1244                                                     DirtyBits dirtyBitMask);
1245     angle::Result handleDirtyGraphicsShaderResources(DirtyBits::Iterator *dirtyBitsIterator,
1246                                                      DirtyBits dirtyBitMask);
1247     angle::Result handleDirtyGraphicsUniformBuffers(DirtyBits::Iterator *dirtyBitsIterator,
1248                                                     DirtyBits dirtyBitMask);
1249     angle::Result handleDirtyGraphicsFramebufferFetchBarrier(DirtyBits::Iterator *dirtyBitsIterator,
1250                                                              DirtyBits dirtyBitMask);
1251     angle::Result handleDirtyGraphicsBlendBarrier(DirtyBits::Iterator *dirtyBitsIterator,
1252                                                   DirtyBits dirtyBitMask);
1253     angle::Result handleDirtyGraphicsTransformFeedbackBuffersEmulation(
1254         DirtyBits::Iterator *dirtyBitsIterator,
1255         DirtyBits dirtyBitMask);
1256     angle::Result handleDirtyGraphicsTransformFeedbackBuffersExtension(
1257         DirtyBits::Iterator *dirtyBitsIterator,
1258         DirtyBits dirtyBitMask);
1259     angle::Result handleDirtyGraphicsTransformFeedbackResume(DirtyBits::Iterator *dirtyBitsIterator,
1260                                                              DirtyBits dirtyBitMask);
1261     angle::Result handleDirtyGraphicsDescriptorSets(DirtyBits::Iterator *dirtyBitsIterator,
1262                                                     DirtyBits dirtyBitMask);
1263     angle::Result handleDirtyGraphicsUniforms(DirtyBits::Iterator *dirtyBitsIterator,
1264                                               DirtyBits dirtyBitMask);
1265     angle::Result handleDirtyGraphicsDynamicViewport(DirtyBits::Iterator *dirtyBitsIterator,
1266                                                      DirtyBits dirtyBitMask);
1267     angle::Result handleDirtyGraphicsDynamicScissor(DirtyBits::Iterator *dirtyBitsIterator,
1268                                                     DirtyBits dirtyBitMask);
1269     angle::Result handleDirtyGraphicsDynamicLineWidth(DirtyBits::Iterator *dirtyBitsIterator,
1270                                                       DirtyBits dirtyBitMask);
1271     angle::Result handleDirtyGraphicsDynamicDepthBias(DirtyBits::Iterator *dirtyBitsIterator,
1272                                                       DirtyBits dirtyBitMask);
1273     angle::Result handleDirtyGraphicsDynamicBlendConstants(DirtyBits::Iterator *dirtyBitsIterator,
1274                                                            DirtyBits dirtyBitMask);
1275     angle::Result handleDirtyGraphicsDynamicStencilCompareMask(
1276         DirtyBits::Iterator *dirtyBitsIterator,
1277         DirtyBits dirtyBitMask);
1278     angle::Result handleDirtyGraphicsDynamicStencilWriteMask(DirtyBits::Iterator *dirtyBitsIterator,
1279                                                              DirtyBits dirtyBitMask);
1280     angle::Result handleDirtyGraphicsDynamicStencilReference(DirtyBits::Iterator *dirtyBitsIterator,
1281                                                              DirtyBits dirtyBitMask);
1282     angle::Result handleDirtyGraphicsDynamicCullMode(DirtyBits::Iterator *dirtyBitsIterator,
1283                                                      DirtyBits dirtyBitMask);
1284     angle::Result handleDirtyGraphicsDynamicFrontFace(DirtyBits::Iterator *dirtyBitsIterator,
1285                                                       DirtyBits dirtyBitMask);
1286     angle::Result handleDirtyGraphicsDynamicDepthTestEnable(DirtyBits::Iterator *dirtyBitsIterator,
1287                                                             DirtyBits dirtyBitMask);
1288     angle::Result handleDirtyGraphicsDynamicDepthWriteEnable(DirtyBits::Iterator *dirtyBitsIterator,
1289                                                              DirtyBits dirtyBitMask);
1290     angle::Result handleDirtyGraphicsDynamicDepthCompareOp(DirtyBits::Iterator *dirtyBitsIterator,
1291                                                            DirtyBits dirtyBitMask);
1292     angle::Result handleDirtyGraphicsDynamicStencilTestEnable(
1293         DirtyBits::Iterator *dirtyBitsIterator,
1294         DirtyBits dirtyBitMask);
1295     angle::Result handleDirtyGraphicsDynamicStencilOp(DirtyBits::Iterator *dirtyBitsIterator,
1296                                                       DirtyBits dirtyBitMask);
1297     angle::Result handleDirtyGraphicsDynamicRasterizerDiscardEnable(
1298         DirtyBits::Iterator *dirtyBitsIterator,
1299         DirtyBits dirtyBitMask);
1300     angle::Result handleDirtyGraphicsDynamicDepthBiasEnable(DirtyBits::Iterator *dirtyBitsIterator,
1301                                                             DirtyBits dirtyBitMask);
1302     angle::Result handleDirtyGraphicsDynamicLogicOp(DirtyBits::Iterator *dirtyBitsIterator,
1303                                                     DirtyBits dirtyBitMask);
1304     angle::Result handleDirtyGraphicsDynamicPrimitiveRestartEnable(
1305         DirtyBits::Iterator *dirtyBitsIterator,
1306         DirtyBits dirtyBitMask);
1307     angle::Result handleDirtyGraphicsDynamicFragmentShadingRate(
1308         DirtyBits::Iterator *dirtyBitsIterator,
1309         DirtyBits dirtyBitMask);
1310 
1311     // Handlers for compute pipeline dirty bits.
1312     angle::Result handleDirtyComputeMemoryBarrier(DirtyBits::Iterator *dirtyBitsIterator);
1313     angle::Result handleDirtyComputeEventLog(DirtyBits::Iterator *dirtyBitsIterator);
1314     angle::Result handleDirtyComputePipelineDesc(DirtyBits::Iterator *dirtyBitsIterator);
1315     angle::Result handleDirtyComputePipelineBinding(DirtyBits::Iterator *dirtyBitsIterator);
1316     angle::Result handleDirtyComputeTextures(DirtyBits::Iterator *dirtyBitsIterator);
1317     angle::Result handleDirtyComputeDriverUniforms(DirtyBits::Iterator *dirtyBitsIterator);
1318     angle::Result handleDirtyComputeShaderResources(DirtyBits::Iterator *dirtyBitsIterator);
1319     angle::Result handleDirtyComputeUniformBuffers(DirtyBits::Iterator *dirtyBitsIterator);
1320     angle::Result handleDirtyComputeDescriptorSets(DirtyBits::Iterator *dirtyBitsIterator);
1321     angle::Result handleDirtyComputeUniforms(DirtyBits::Iterator *dirtyBitsIterator);
1322 
1323     // Common parts of the common dirty bit handlers.
1324     angle::Result handleDirtyUniformsImpl(DirtyBits::Iterator *dirtyBitsIterator);
1325     angle::Result handleDirtyMemoryBarrierImpl(DirtyBits::Iterator *dirtyBitsIterator,
1326                                                DirtyBits dirtyBitMask);
1327     template <typename CommandBufferT>
1328     angle::Result handleDirtyEventLogImpl(CommandBufferT *commandBuffer);
1329     template <typename CommandBufferHelperT>
1330     angle::Result handleDirtyTexturesImpl(CommandBufferHelperT *commandBufferHelper,
1331                                           PipelineType pipelineType);
1332     template <typename CommandBufferHelperT>
1333     angle::Result handleDirtyShaderResourcesImpl(CommandBufferHelperT *commandBufferHelper,
1334                                                  PipelineType pipelineType,
1335                                                  DirtyBits::Iterator *dirtyBitsIterator);
1336     template <typename CommandBufferHelperT>
1337     angle::Result handleDirtyUniformBuffersImpl(CommandBufferHelperT *commandBufferHelper);
1338     template <typename CommandBufferHelperT>
1339     angle::Result handleDirtyDescriptorSetsImpl(CommandBufferHelperT *commandBufferHelper,
1340                                                 PipelineType pipelineType);
1341     void handleDirtyGraphicsDynamicScissorImpl(bool isPrimitivesGeneratedQueryActive);
1342 
1343     void writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOut, size_t offsetsSize);
1344 
1345     enum class Submit
1346     {
1347         OutsideRenderPassCommandsOnly,
1348         AllCommands,
1349     };
1350 
1351     angle::Result submitCommands(const vk::Semaphore *signalSemaphore,
1352                                  const vk::SharedExternalFence *externalFence,
1353                                  Submit submission);
1354     angle::Result flushImpl(const gl::Context *context);
1355 
1356     angle::Result synchronizeCpuGpuTime();
1357     angle::Result traceGpuEventImpl(vk::OutsideRenderPassCommandBuffer *commandBuffer,
1358                                     char phase,
1359                                     const EventName &name);
1360     angle::Result checkCompletedGpuEvents();
1361     void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS);
1362     void handleDeviceLost();
1363     bool shouldEmulateSeamfulCubeMapSampling() const;
1364     void clearAllGarbage();
1365     void dumpCommandStreamDiagnostics();
1366     angle::Result flushOutsideRenderPassCommands();
1367     // Flush commands and end render pass without setting any dirty bits.
1368     // flushCommandsAndEndRenderPass() and flushDirtyGraphicsRenderPass() will set the dirty bits
1369     // directly or through the iterator respectively.  Outside those two functions, this shouldn't
1370     // be called directly.
1371     angle::Result flushDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
1372                                                DirtyBits dirtyBitMask,
1373                                                RenderPassClosureReason reason);
1374 
1375     // Mark the render pass to be closed on the next draw call.  The render pass is not actually
1376     // closed and can be restored with restoreFinishedRenderPass if necessary, for example to append
1377     // a resolve attachment.
1378     void onRenderPassFinished(RenderPassClosureReason reason);
1379 
1380     void initIndexTypeMap();
1381 
1382     VertexArrayVk *getVertexArray() const;
1383     FramebufferVk *getDrawFramebuffer() const;
1384 
1385     // Read-after-write hazards are generally handled with |glMemoryBarrier| when the source of
1386     // write is storage output.  When the write is outside render pass, the natural placement of the
1387     // render pass after the current outside render pass commands ensures that the memory barriers
1388     // and image layout transitions automatically take care of such synchronizations.
1389     //
1390     // There are a number of read-after-write cases that require breaking the render pass however to
1391     // preserve the order of operations:
1392     //
1393     // - Transform feedback write (in render pass), then vertex/index read (in render pass)
1394     // - Transform feedback write (in render pass), then ubo read (outside render pass)
1395     // - Framebuffer attachment write (in render pass), then texture sample (outside render pass)
1396     //   * Note that texture sampling inside render pass would cause a feedback loop
1397     //
1398     angle::Result endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper *buffer);
1399     angle::Result endRenderPassIfComputeReadAfterTransformFeedbackWrite();
1400     angle::Result endRenderPassIfComputeAccessAfterGraphicsImageAccess();
1401 
1402     // Update read-only depth feedback loop mode.  Typically called from
1403     // handleDirtyGraphicsReadOnlyDepthFeedbackLoopMode, but can be called from UtilsVk in functions
1404     // that don't necessarily break the render pass.
1405     angle::Result switchOutReadOnlyDepthStencilMode(DirtyBits::Iterator *dirtyBitsIterator,
1406                                                     DirtyBits dirtyBitMask,
1407                                                     UpdateDepthFeedbackLoopReason depthReason,
1408                                                     UpdateDepthFeedbackLoopReason stencilReason);
1409     angle::Result switchToReadOnlyDepthStencilMode(gl::Texture *texture,
1410                                                    gl::Command command,
1411                                                    FramebufferVk *drawFramebuffer,
1412                                                    bool isStencilTexture);
1413 
1414     angle::Result onResourceAccess(const vk::CommandBufferAccess &access);
1415     angle::Result flushCommandBuffersIfNecessary(const vk::CommandBufferAccess &access);
1416     bool renderPassUsesStorageResources() const;
1417 
1418     angle::Result pushDebugGroupImpl(GLenum source, GLuint id, const char *message);
1419     angle::Result popDebugGroupImpl();
1420 
1421     void updateScissor(const gl::State &glState);
1422 
1423     void updateDepthStencil(const gl::State &glState);
1424     void updateDepthTestEnabled(const gl::State &glState);
1425     void updateDepthWriteEnabled(const gl::State &glState);
1426     void updateDepthFunc(const gl::State &glState);
1427     void updateStencilTestEnabled(const gl::State &glState);
1428 
1429     void updateSampleShadingWithRasterizationSamples(const uint32_t rasterizationSamples);
1430     void updateRasterizationSamples(const uint32_t rasterizationSamples);
1431     void updateRasterizerDiscardEnabled(bool isPrimitivesGeneratedQueryActive);
1432 
1433     void updateAdvancedBlendEquations(const gl::ProgramExecutable *executable);
1434 
1435     void updateDither();
1436 
1437     // For dynamic rendering only, mark the current render pass as being in framebuffer fetch mode.
1438     // In this mode, the FramebufferVk object and its render pass description are unaffected by
1439     // framebuffer fetch use, and the context needs to just configure the command buffer for
1440     // framebuffer fetch.
1441     void onFramebufferFetchUse(vk::FramebufferFetchMode framebufferFetchMode);
1442 
1443     // When the useNonZeroStencilWriteMaskStaticState workaround is enabled, the static state for
1444     // stencil should be non-zero despite the state being dynamic.  This is done when:
1445     //
1446     // - The shader includes discard, or
1447     // - Alpha-to-coverage is enabled.
1448     //
1449     // An alternative could have been to set the static state unconditionally to non-zero.  This is
1450     // avoided however, as on the affected driver that would disable certain optimizations.
1451     void updateStencilWriteWorkaround();
1452 
1453     void updateShaderResourcesWithSharedCacheKey(
1454         const vk::SharedDescriptorSetCacheKey &sharedCacheKey);
1455 
1456     angle::Result createGraphicsPipeline();
1457 
1458     angle::Result allocateQueueSerialIndex();
1459     void releaseQueueSerialIndex();
1460 
1461     void generateOutsideRenderPassCommandsQueueSerial();
1462     void generateRenderPassCommandsQueueSerial(QueueSerial *queueSerialOut);
1463 
1464     angle::Result ensureInterfacePipelineCache();
1465 
1466     angle::ImageLoadContext mImageLoadContext;
1467 
1468     std::array<GraphicsDirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
1469     std::array<ComputeDirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;
1470 
1471     vk::RenderPassCommandBuffer *mRenderPassCommandBuffer;
1472 
1473     vk::PipelineHelper *mCurrentGraphicsPipeline;
1474     vk::PipelineHelper *mCurrentGraphicsPipelineShaders;
1475     vk::PipelineHelper *mCurrentGraphicsPipelineVertexInput;
1476     vk::PipelineHelper *mCurrentGraphicsPipelineFragmentOutput;
1477     vk::PipelineHelper *mCurrentComputePipeline;
1478     gl::PrimitiveMode mCurrentDrawMode;
1479 
1480     WindowSurfaceVk *mCurrentWindowSurface;
1481     // Records the current rotation of the surface (draw/read) framebuffer, derived from
1482     // mCurrentWindowSurface->getPreTransform().
1483     SurfaceRotation mCurrentRotationDrawFramebuffer;
1484     SurfaceRotation mCurrentRotationReadFramebuffer;
1485 
1486     // Tracks if we are in depth/stencil *read-only* or feedback loop mode. The read only is
1487     // specially allowed as both usages attachment and texture are read-only. When switching away
1488     // from read-only mode, the render pass is broken is to accommodate the new writable layout.
1489     vk::RenderPassUsageFlags mDepthStencilAttachmentFlags;
1490 
1491     // Keep a cached pipeline description structure that can be used to query the pipeline cache.
1492     // Kept in a pointer so allocations can be aligned, and structs can be portably packed.
1493     std::unique_ptr<vk::GraphicsPipelineDesc> mGraphicsPipelineDesc;
1494     // Transition bits indicating which state has changed since last pipeline recreation.  It is
1495     // used to look up pipelines in the cache without iterating over the entire key as a performance
1496     // optimization.
1497     //
1498     // |mGraphicsPipelineTransition| tracks transition bits since the last complete pipeline
1499     // creation/retrieval.  |mGraphicsPipelineLibraryTransition| tracks the same but for the case
1500     // where the pipeline is created through libraries.  The latter accumulates
1501     // |mGraphicsPipelineTransition| while the caches are hit, so that the bits are not lost if a
1502     // partial library needs to be created in the future.
1503     vk::GraphicsPipelineTransitionBits mGraphicsPipelineTransition;
1504     vk::GraphicsPipelineTransitionBits mGraphicsPipelineLibraryTransition;
1505 
1506     // A pipeline cache specifically used for vertex input and fragment output pipelines, when there
1507     // is no blob reuse between libraries and monolithic pipelines.  In that case, there's no point
1508     // in making monolithic pipelines be stored in the same cache as these partial pipelines.
1509     //
1510     // Note additionally that applications only create a handful of vertex input and fragment output
1511     // pipelines, which is also s fast operation, so this cache is both small and ephemeral (i.e.
1512     // not cached to disk).
1513     vk::PipelineCache mInterfacePipelinesCache;
1514 
1515     // These pools are externally synchronized, so cannot be accessed from different
1516     // threads simultaneously. Hence, we keep them in the ContextVk instead of the vk::Renderer.
1517     // Note that this implementation would need to change in shared resource scenarios. Likely
1518     // we'd instead share a single set of pools between the share groups.
1519     gl::QueryTypeMap<vk::DynamicQueryPool> mQueryPools;
1520 
1521     // Queries that need to be closed and reopened with the render pass:
1522     //
1523     // - Occlusion queries
1524     // - Transform feedback queries, if not emulated
1525     gl::QueryTypeMap<QueryVk *> mActiveRenderPassQueries;
1526 
1527     // Dirty bits.
1528     DirtyBits mGraphicsDirtyBits;
1529     DirtyBits mComputeDirtyBits;
1530     DirtyBits mNonIndexedDirtyBitsMask;
1531     DirtyBits mIndexedDirtyBitsMask;
1532     DirtyBits mNewGraphicsCommandBufferDirtyBits;
1533     DirtyBits mNewComputeCommandBufferDirtyBits;
1534     DirtyBits mDynamicStateDirtyBits;
1535     DirtyBits mPersistentGraphicsDirtyBits;
1536     static constexpr DirtyBits kColorAccessChangeDirtyBits{DIRTY_BIT_COLOR_ACCESS};
1537     static constexpr DirtyBits kDepthStencilAccessChangeDirtyBits{
1538         DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE, DIRTY_BIT_DEPTH_STENCIL_ACCESS};
1539     static constexpr DirtyBits kIndexAndVertexDirtyBits{DIRTY_BIT_VERTEX_BUFFERS,
1540                                                         DIRTY_BIT_INDEX_BUFFER};
1541     static constexpr DirtyBits kPipelineDescAndBindingDirtyBits{DIRTY_BIT_PIPELINE_DESC,
1542                                                                 DIRTY_BIT_PIPELINE_BINDING};
1543     static constexpr DirtyBits kTexturesAndDescSetDirtyBits{DIRTY_BIT_TEXTURES,
1544                                                             DIRTY_BIT_DESCRIPTOR_SETS};
1545     static constexpr DirtyBits kResourcesAndDescSetDirtyBits{DIRTY_BIT_SHADER_RESOURCES,
1546                                                              DIRTY_BIT_DESCRIPTOR_SETS};
1547     static constexpr DirtyBits kUniformBuffersAndDescSetDirtyBits{DIRTY_BIT_UNIFORM_BUFFERS,
1548                                                                   DIRTY_BIT_DESCRIPTOR_SETS};
1549     static constexpr DirtyBits kXfbBuffersAndDescSetDirtyBits{DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
1550                                                               DIRTY_BIT_DESCRIPTOR_SETS};
1551 
1552     // The offset we had the last time we bound the index buffer.
1553     const GLvoid *mLastIndexBufferOffset;
1554     vk::BufferHelper *mCurrentIndexBuffer;
1555     VkDeviceSize mCurrentIndexBufferOffset;
1556     gl::DrawElementsType mCurrentDrawElementsType;
1557     angle::PackedEnumMap<gl::DrawElementsType, VkIndexType> mIndexTypeMap;
1558 
1559     // Cache the current draw call's firstVertex to be passed to
1560     // TransformFeedbackVk::getBufferOffsets.  Unfortunately, gl_BaseVertex support in Vulkan is
1561     // not yet ubiquitous, which would have otherwise removed the need for this value to be passed
1562     // as a uniform.
1563     GLint mXfbBaseVertex;
1564     // Cache the current draw call's vertex count as well to support instanced draw calls
1565     GLuint mXfbVertexCountPerInstance;
1566 
1567     // Cached clear value/mask for color and depth/stencil.
1568     VkClearValue mClearColorValue;
1569     VkClearValue mClearDepthStencilValue;
1570     gl::BlendStateExt::ColorMaskStorage::Type mClearColorMasks;
1571 
1572     // The unprocessed bits passed in from the previous glMemoryBarrier call
1573     GLbitfield mDeferredMemoryBarriers;
1574 
1575     IncompleteTextureSet mIncompleteTextures;
1576 
1577     // If the current surface bound to this context wants to have all rendering flipped vertically.
1578     // Updated on calls to onMakeCurrent.
1579     bool mFlipYForCurrentSurface;
1580     bool mFlipViewportForDrawFramebuffer;
1581     bool mFlipViewportForReadFramebuffer;
1582 
1583     // If any host-visible buffer is written by the GPU since last submission, a barrier is inserted
1584     // at the end of the command buffer to make that write available to the host.
1585     bool mIsAnyHostVisibleBufferWritten;
1586 
1587     // This info is used in the descriptor update step.
1588     gl::ActiveTextureArray<TextureVk *> mActiveTextures;
1589 
1590     vk::DescriptorSetDescBuilder mShaderBuffersDescriptorDesc;
1591     // The WriteDescriptorDescs from ProgramExecutableVk with InputAttachment update.
1592     vk::WriteDescriptorDescs mShaderBufferWriteDescriptorDescs;
1593 
1594     gl::ActiveTextureArray<TextureVk *> mActiveImages;
1595 
1596     // "Current Value" aka default vertex attribute state.
1597     gl::AttributesMask mDirtyDefaultAttribsMask;
1598 
1599     // DynamicBuffers for streaming vertex data from client memory pointer as well as for default
1600     // attributes. mHasInFlightStreamedVertexBuffers indicates if the dynamic buffer has any
1601     // in-flight buffer or not that we need to release at submission time.
1602     gl::AttribArray<vk::DynamicBuffer> mStreamedVertexBuffers;
1603     gl::AttributesMask mHasInFlightStreamedVertexBuffers;
1604 
1605     // We use a single pool for recording commands. We also keep a free list for pool recycling.
1606     vk::SecondaryCommandPools mCommandPools;
1607 
1608     // Per context queue serial
1609     SerialIndex mCurrentQueueSerialIndex;
1610     QueueSerial mLastFlushedQueueSerial;
1611     QueueSerial mLastSubmittedQueueSerial;
1612     // All submitted queue serials over the life time of this context.
1613     vk::ResourceUse mSubmittedResourceUse;
1614     // Current active transform feedback buffer queue serial. Invalid if TF not active.
1615     QueueSerial mCurrentTransformFeedbackQueueSerial;
1616 
1617     // The garbage list for single context use objects. The list will be GPU tracked by next
1618     // submission queueSerial. Note: Resource based shared object should always be added to
1619     // renderer's mSharedGarbageList.
1620     vk::GarbageObjects mCurrentGarbage;
1621 
1622     RenderPassCache mRenderPassCache;
1623     // Used with dynamic rendering as it doesn't use render passes.
1624     vk::RenderPass mNullRenderPass;
1625 
1626     vk::OutsideRenderPassCommandBufferHelper *mOutsideRenderPassCommands;
1627     vk::RenderPassCommandBufferHelper *mRenderPassCommands;
1628 
1629     // Allocators for the render pass command buffers. They are utilized only when shared ring
1630     // buffer allocators are being used.
1631     vk::SecondaryCommandMemoryAllocator mOutsideRenderPassCommandsAllocator;
1632     vk::SecondaryCommandMemoryAllocator mRenderPassCommandsAllocator;
1633 
1634     // The following is used when creating debug-util markers for graphics debuggers (e.g. AGI).  A
1635     // given gl{Begin|End}Query command may result in commands being submitted to the outside or
1636     // render-pass command buffer.  The ContextVk::handleGraphicsEventLog() method records the
1637     // appropriate command buffer for use by ContextVk::endEventLogForQuery().  The knowledge of
1638     // which command buffer to use depends on the particular type of query (e.g. samples
1639     // vs. timestamp), and is only known by the query code, which is what calls
1640     // ContextVk::handleGraphicsEventLog().  After all back-end processing of the gl*Query command
1641     // is complete, the front-end calls ContextVk::endEventLogForQuery(), which needs to know which
1642     // command buffer to call endDebugUtilsLabelEXT() for.
1643     GraphicsEventCmdBuf mQueryEventType;
1644 
1645     // Internal shader library.
1646     vk::ShaderLibrary mShaderLibrary;
1647     UtilsVk mUtils;
1648 
1649     bool mGpuEventsEnabled;
1650     vk::DynamicQueryPool mGpuEventQueryPool;
1651     // A list of queries that have yet to be turned into an event (their result is not yet
1652     // available).
1653     std::vector<GpuEventQuery> mInFlightGpuEventQueries;
1654     // A list of gpu events since the last clock sync.
1655     std::vector<GpuEvent> mGpuEvents;
1656     // The current frame index, used to generate a submission-encompassing event tagged with it.
1657     uint32_t mPrimaryBufferEventCounter;
1658 
1659     // Cached value of the color attachment mask of the current draw framebuffer.  This is used to
1660     // know which attachment indices have their blend state set in |mGraphicsPipelineDesc|, and
1661     // subsequently is used to clear the blend state for attachments that no longer exist when a new
1662     // framebuffer is bound.
1663     gl::DrawBufferMask mCachedDrawFramebufferColorAttachmentMask;
1664 
1665     // Whether a flush was requested, but is deferred as an optimization to avoid breaking the
1666     // render pass.
1667     bool mHasDeferredFlush;
1668 
1669     // Whether this context has produced any commands so far.  While the renderer already skips
1670     // vkQueueSubmit when there is no command recorded, this variable allows glFlush itself to be
1671     // entirely skipped.  This is particularly needed for an optimization where the Surface is in
1672     // shared-present mode, and the app is unnecessarily calling eglSwapBuffers (which equates
1673     // glFlush in that mode).
1674     bool mHasAnyCommandsPendingSubmission;
1675 
1676     // Whether color framebuffer fetch is active.  When the permanentlySwitchToFramebufferFetchMode
1677     // feature is enabled, if any program uses framebuffer fetch, rendering switches to assuming
1678     // framebuffer fetch could happen in any render pass.  This incurs a potential cost due to usage
1679     // of the GENERAL layout instead of COLOR_ATTACHMENT_OPTIMAL, but has definite benefits of
1680     // avoiding render pass breaks when a framebuffer fetch program is used mid render pass.
1681     //
1682     // This only applies to legacy render passes (i.e. when dynamic rendering is NOT used).  In the
1683     // case of dynamic rendering, every render pass starts with the assumption of not needing input
1684     // attachments and switches later if it needs to with no penalty.
1685     //
1686     // Note that depth/stencil framebuffer fetch does not need this sort of tracking because it is
1687     // only enabled with dynamic rendering.
1688     bool mIsInColorFramebufferFetchMode;
1689 
1690     // True if current started render pass is allowed to reactivate.
1691     bool mAllowRenderPassToReactivate;
1692 
1693     // The size of copy commands issued between buffers and images. Used to submit the command
1694     // buffer for the outside render pass.
1695     VkDeviceSize mTotalBufferToImageCopySize;
1696     VkDeviceSize mEstimatedPendingImageGarbageSize;
1697 
1698     // Semaphores that must be flushed before the current commands. Flushed semaphores will be
1699     // waited on in the next submission.
1700     std::vector<VkSemaphore> mWaitSemaphores;
1701     std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks;
1702     // Whether this context has wait semaphores (flushed and unflushed) that must be submitted.
1703     bool mHasWaitSemaphoresPendingSubmission;
1704 
1705     // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
1706     GpuClockSyncInfo mGpuClockSync;
1707 
1708     // The very first timestamp queried for a GPU event is used as origin, so event timestamps would
1709     // have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to
1710     // double.
1711     uint64_t mGpuEventTimestampOrigin;
1712 
1713     // A mix of per-frame and per-run counters.
1714     angle::PerfMonitorCounterGroups mPerfMonitorCounters;
1715 
1716     gl::state::DirtyBits mPipelineDirtyBitsMask;
1717 
1718     egl::ContextPriority mInitialContextPriority;
1719     egl::ContextPriority mContextPriority;
1720     vk::ProtectionType mProtectionType;
1721 
1722     ShareGroupVk *mShareGroupVk;
1723 
1724     // This is a special "empty" placeholder buffer for use when we just need a placeholder buffer
1725     // but not the data. Examples are shader that has no uniform or doesn't use all slots in the
1726     // atomic counter buffer array, or places where there is no vertex buffer since Vulkan does not
1727     // allow binding a null vertex buffer.
1728     vk::BufferHelper mEmptyBuffer;
1729 
1730     // Storage for default uniforms of ProgramVks and ProgramPipelineVks.
1731     vk::DynamicBuffer mDefaultUniformStorage;
1732 
1733     std::vector<std::string> mCommandBufferDiagnostics;
1734 
1735     // Record GL API calls for debuggers
1736     std::vector<std::string> mEventLog;
1737 
1738     // Viewport and scissor are handled as dynamic state.
1739     VkViewport mViewport;
1740     VkRect2D mScissor;
1741 
1742     VulkanCacheStats mVulkanCacheStats;
1743 
1744     RangedSerialFactory mOutsideRenderPassSerialFactory;
1745 };
1746 
endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper * buffer)1747 ANGLE_INLINE angle::Result ContextVk::endRenderPassIfTransformFeedbackBuffer(
1748     const vk::BufferHelper *buffer)
1749 {
1750     if (!mCurrentTransformFeedbackQueueSerial.valid() || !buffer ||
1751         !buffer->writtenByCommandBuffer(mCurrentTransformFeedbackQueueSerial))
1752     {
1753         return angle::Result::Continue;
1754     }
1755 
1756     return flushCommandsAndEndRenderPass(RenderPassClosureReason::XfbWriteThenVertexIndexBuffer);
1757 }
1758 
onIndexBufferChange(const vk::BufferHelper * currentIndexBuffer)1759 ANGLE_INLINE angle::Result ContextVk::onIndexBufferChange(
1760     const vk::BufferHelper *currentIndexBuffer)
1761 {
1762     mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
1763     mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer);
1764     return endRenderPassIfTransformFeedbackBuffer(currentIndexBuffer);
1765 }
1766 
onVertexBufferChange(const vk::BufferHelper * vertexBuffer)1767 ANGLE_INLINE angle::Result ContextVk::onVertexBufferChange(const vk::BufferHelper *vertexBuffer)
1768 {
1769     mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
1770     return endRenderPassIfTransformFeedbackBuffer(vertexBuffer);
1771 }
1772 
onVertexAttributeChange(size_t attribIndex,GLuint stride,GLuint divisor,angle::FormatID format,bool compressed,GLuint relativeOffset,const vk::BufferHelper * vertexBuffer)1773 ANGLE_INLINE angle::Result ContextVk::onVertexAttributeChange(size_t attribIndex,
1774                                                               GLuint stride,
1775                                                               GLuint divisor,
1776                                                               angle::FormatID format,
1777                                                               bool compressed,
1778                                                               GLuint relativeOffset,
1779                                                               const vk::BufferHelper *vertexBuffer)
1780 {
1781     const GLuint staticStride =
1782         mRenderer->getFeatures().useVertexInputBindingStrideDynamicState.enabled ? 0 : stride;
1783 
1784     if (!getFeatures().supportsVertexInputDynamicState.enabled)
1785     {
1786         invalidateCurrentGraphicsPipeline();
1787 
1788         // Set divisor to 1 for attribs with emulated divisor
1789         mGraphicsPipelineDesc->updateVertexInput(
1790             this, &mGraphicsPipelineTransition, static_cast<uint32_t>(attribIndex), staticStride,
1791             divisor > mRenderer->getMaxVertexAttribDivisor() ? 1 : divisor, format, compressed,
1792             relativeOffset);
1793     }
1794     return onVertexBufferChange(vertexBuffer);
1795 }
1796 
hasUnsubmittedUse(const vk::ResourceUse & use)1797 ANGLE_INLINE bool ContextVk::hasUnsubmittedUse(const vk::ResourceUse &use) const
1798 {
1799     return mCurrentQueueSerialIndex != kInvalidQueueSerialIndex &&
1800            use > QueueSerial(mCurrentQueueSerialIndex,
1801                              mRenderer->getLastSubmittedSerial(mCurrentQueueSerialIndex));
1802 }
1803 
UseLineRaster(const ContextVk * contextVk,gl::PrimitiveMode mode)1804 ANGLE_INLINE bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
1805 {
1806     return gl::IsLineMode(mode);
1807 }
1808 
1809 uint32_t GetDriverUniformSize(vk::Context *context, PipelineType pipelineType);
1810 }  // namespace rx
1811 
1812 // Generate a perf warning, and insert an event marker in the command buffer.
1813 #define ANGLE_VK_PERF_WARNING(contextVk, severity, ...)                             \
1814     do                                                                              \
1815     {                                                                               \
1816         ANGLE_PERF_WARNING(contextVk->getDebug(), severity, __VA_ARGS__);           \
1817         if (contextVk->isDebugEnabled())                                            \
1818         {                                                                           \
1819             char ANGLE_MESSAGE[200];                                                \
1820             snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__);            \
1821             contextVk->insertEventMarkerImpl(GL_DEBUG_SOURCE_OTHER, ANGLE_MESSAGE); \
1822         }                                                                           \
1823     } while (0)
1824 
1825 // Generate a trace event for graphics profiler, and insert an event marker in the command buffer.
1826 #define ANGLE_VK_TRACE_EVENT_AND_MARKER(contextVk, ...)                         \
1827     do                                                                          \
1828     {                                                                           \
1829         char ANGLE_MESSAGE[200];                                                \
1830         snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__);            \
1831         ANGLE_TRACE_EVENT0("gpu.angle", ANGLE_MESSAGE);                         \
1832                                                                                 \
1833         contextVk->insertEventMarkerImpl(GL_DEBUG_SOURCE_OTHER, ANGLE_MESSAGE); \
1834     } while (0)
1835 
1836 #endif  // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
1837