• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "libANGLE/renderer/ContextImpl.h"
18 #include "libANGLE/renderer/renderer_utils.h"
19 #include "libANGLE/renderer/vulkan/DisplayVk.h"
20 #include "libANGLE/renderer/vulkan/OverlayVk.h"
21 #include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
22 #include "libANGLE/renderer/vulkan/RendererVk.h"
23 #include "libANGLE/renderer/vulkan/vk_helpers.h"
24 
25 namespace angle
26 {
27 struct FeaturesVk;
28 }  // namespace angle
29 
30 namespace rx
31 {
32 class ProgramExecutableVk;
33 class RendererVk;
34 class WindowSurfaceVk;
35 class ShareGroupVk;
36 
37 static constexpr uint32_t kMaxGpuEventNameLen = 32;
38 using EventName                               = std::array<char, kMaxGpuEventNameLen>;
39 
40 // If the total size of copyBufferToImage commands in the outside command buffer reaches the
41 // threshold below, the latter is flushed.
42 static constexpr VkDeviceSize kMaxBufferToImageCopySize = 1 << 28;
43 
44 using ContextVkDescriptorSetList = angle::PackedEnumMap<PipelineType, uint32_t>;
45 
46 enum class GraphicsEventCmdBuf
47 {
48     NotInQueryCmd              = 0,
49     InOutsideCmdBufQueryCmd    = 1,
50     InRenderPassCmdBufQueryCmd = 2,
51 
52     InvalidEnum = 3,
53     EnumCount   = 3,
54 };
55 
56 enum class QueueSubmitType
57 {
58     PerformQueueSubmit,
59     SkipQueueSubmit,
60 };
61 
62 class UpdateDescriptorSetsBuilder final : angle::NonCopyable
63 {
64   public:
65     UpdateDescriptorSetsBuilder();
66     ~UpdateDescriptorSetsBuilder();
67 
68     VkDescriptorBufferInfo *allocDescriptorBufferInfos(size_t count);
69     VkDescriptorImageInfo *allocDescriptorImageInfos(size_t count);
70     VkWriteDescriptorSet *allocWriteDescriptorSets(size_t count);
71 
allocDescriptorBufferInfo()72     VkDescriptorBufferInfo &allocDescriptorBufferInfo() { return *allocDescriptorBufferInfos(1); }
allocDescriptorImageInfo()73     VkDescriptorImageInfo &allocDescriptorImageInfo() { return *allocDescriptorImageInfos(1); }
allocWriteDescriptorSet()74     VkWriteDescriptorSet &allocWriteDescriptorSet() { return *allocWriteDescriptorSets(1); }
75 
76     // Returns the number of written descriptor sets.
77     uint32_t flushDescriptorSetUpdates(VkDevice device);
78 
79   private:
80     template <typename T, const T *VkWriteDescriptorSet::*pInfo>
81     T *allocDescriptorInfos(std::vector<T> *descriptorVector, size_t count);
82     template <typename T, const T *VkWriteDescriptorSet::*pInfo>
83     void growDescriptorCapacity(std::vector<T> *descriptorVector, size_t newSize);
84 
85     std::vector<VkDescriptorBufferInfo> mDescriptorBufferInfos;
86     std::vector<VkDescriptorImageInfo> mDescriptorImageInfos;
87     std::vector<VkWriteDescriptorSet> mWriteDescriptorSets;
88 };
89 
90 // Why depth/stencil feedback loop is being updated.  Based on whether it's due to a draw or clear,
91 // different GL state affect depth/stencil write.
92 enum class UpdateDepthFeedbackLoopReason
93 {
94     None,
95     Draw,
96     Clear,
97 };
98 
99 class ContextVk : public ContextImpl, public vk::Context, public MultisampleTextureInitializer
100 {
101   public:
102     ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk *renderer);
103     ~ContextVk() override;
104 
105     angle::Result initialize() override;
106 
107     void onDestroy(const gl::Context *context) override;
108 
109     // Flush and finish.
110     angle::Result flush(const gl::Context *context) override;
111     angle::Result finish(const gl::Context *context) override;
112 
113     // Drawing methods.
114     angle::Result drawArrays(const gl::Context *context,
115                              gl::PrimitiveMode mode,
116                              GLint first,
117                              GLsizei count) override;
118     angle::Result drawArraysInstanced(const gl::Context *context,
119                                       gl::PrimitiveMode mode,
120                                       GLint first,
121                                       GLsizei count,
122                                       GLsizei instanceCount) override;
123     angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
124                                                   gl::PrimitiveMode mode,
125                                                   GLint first,
126                                                   GLsizei count,
127                                                   GLsizei instanceCount,
128                                                   GLuint baseInstance) override;
129 
130     angle::Result drawElements(const gl::Context *context,
131                                gl::PrimitiveMode mode,
132                                GLsizei count,
133                                gl::DrawElementsType type,
134                                const void *indices) override;
135     angle::Result drawElementsBaseVertex(const gl::Context *context,
136                                          gl::PrimitiveMode mode,
137                                          GLsizei count,
138                                          gl::DrawElementsType type,
139                                          const void *indices,
140                                          GLint baseVertex) override;
141     angle::Result drawElementsInstanced(const gl::Context *context,
142                                         gl::PrimitiveMode mode,
143                                         GLsizei count,
144                                         gl::DrawElementsType type,
145                                         const void *indices,
146                                         GLsizei instanceCount) override;
147     angle::Result drawElementsInstancedBaseVertex(const gl::Context *context,
148                                                   gl::PrimitiveMode mode,
149                                                   GLsizei count,
150                                                   gl::DrawElementsType type,
151                                                   const void *indices,
152                                                   GLsizei instanceCount,
153                                                   GLint baseVertex) override;
154     angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
155                                                               gl::PrimitiveMode mode,
156                                                               GLsizei count,
157                                                               gl::DrawElementsType type,
158                                                               const void *indices,
159                                                               GLsizei instances,
160                                                               GLint baseVertex,
161                                                               GLuint baseInstance) override;
162     angle::Result drawRangeElements(const gl::Context *context,
163                                     gl::PrimitiveMode mode,
164                                     GLuint start,
165                                     GLuint end,
166                                     GLsizei count,
167                                     gl::DrawElementsType type,
168                                     const void *indices) override;
169     angle::Result drawRangeElementsBaseVertex(const gl::Context *context,
170                                               gl::PrimitiveMode mode,
171                                               GLuint start,
172                                               GLuint end,
173                                               GLsizei count,
174                                               gl::DrawElementsType type,
175                                               const void *indices,
176                                               GLint baseVertex) override;
177     angle::Result drawArraysIndirect(const gl::Context *context,
178                                      gl::PrimitiveMode mode,
179                                      const void *indirect) override;
180     angle::Result drawElementsIndirect(const gl::Context *context,
181                                        gl::PrimitiveMode mode,
182                                        gl::DrawElementsType type,
183                                        const void *indirect) override;
184 
185     angle::Result multiDrawArrays(const gl::Context *context,
186                                   gl::PrimitiveMode mode,
187                                   const GLint *firsts,
188                                   const GLsizei *counts,
189                                   GLsizei drawcount) override;
190     angle::Result multiDrawArraysInstanced(const gl::Context *context,
191                                            gl::PrimitiveMode mode,
192                                            const GLint *firsts,
193                                            const GLsizei *counts,
194                                            const GLsizei *instanceCounts,
195                                            GLsizei drawcount) override;
196     angle::Result multiDrawArraysIndirect(const gl::Context *context,
197                                           gl::PrimitiveMode mode,
198                                           const void *indirect,
199                                           GLsizei drawcount,
200                                           GLsizei stride) override;
201     angle::Result multiDrawElements(const gl::Context *context,
202                                     gl::PrimitiveMode mode,
203                                     const GLsizei *counts,
204                                     gl::DrawElementsType type,
205                                     const GLvoid *const *indices,
206                                     GLsizei drawcount) override;
207     angle::Result multiDrawElementsInstanced(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                                              GLsizei drawcount) override;
214     angle::Result multiDrawElementsIndirect(const gl::Context *context,
215                                             gl::PrimitiveMode mode,
216                                             gl::DrawElementsType type,
217                                             const void *indirect,
218                                             GLsizei drawcount,
219                                             GLsizei stride) override;
220     angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
221                                                        gl::PrimitiveMode mode,
222                                                        const GLint *firsts,
223                                                        const GLsizei *counts,
224                                                        const GLsizei *instanceCounts,
225                                                        const GLuint *baseInstances,
226                                                        GLsizei drawcount) override;
227     angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
228                                                                    gl::PrimitiveMode mode,
229                                                                    const GLsizei *counts,
230                                                                    gl::DrawElementsType type,
231                                                                    const GLvoid *const *indices,
232                                                                    const GLsizei *instanceCounts,
233                                                                    const GLint *baseVertices,
234                                                                    const GLuint *baseInstances,
235                                                                    GLsizei drawcount) override;
236 
237     // MultiDrawIndirect helper functions
238     angle::Result multiDrawElementsIndirectHelper(const gl::Context *context,
239                                                   gl::PrimitiveMode mode,
240                                                   gl::DrawElementsType type,
241                                                   const void *indirect,
242                                                   GLsizei drawcount,
243                                                   GLsizei stride);
244     angle::Result multiDrawArraysIndirectHelper(const gl::Context *context,
245                                                 gl::PrimitiveMode mode,
246                                                 const void *indirect,
247                                                 GLsizei drawcount,
248                                                 GLsizei stride);
249 
250     // ShareGroup
getShareGroupVk()251     ShareGroupVk *getShareGroupVk() { return mShareGroupVk; }
getPipelineLayoutCache()252     PipelineLayoutCache &getPipelineLayoutCache()
253     {
254         return mShareGroupVk->getPipelineLayoutCache();
255     }
getDescriptorSetLayoutCache()256     DescriptorSetLayoutCache &getDescriptorSetLayoutCache()
257     {
258         return mShareGroupVk->getDescriptorSetLayoutCache();
259     }
260 
261     // Device loss
262     gl::GraphicsResetStatus getResetStatus() override;
263 
264     // EXT_debug_marker
265     angle::Result insertEventMarker(GLsizei length, const char *marker) override;
266     angle::Result pushGroupMarker(GLsizei length, const char *marker) override;
267     angle::Result popGroupMarker() override;
268 
269     void insertEventMarkerImpl(GLenum source, const char *marker);
270 
271     // KHR_debug
272     angle::Result pushDebugGroup(const gl::Context *context,
273                                  GLenum source,
274                                  GLuint id,
275                                  const std::string &message) override;
276     angle::Result popDebugGroup(const gl::Context *context) override;
277 
278     // Record GL API calls for debuggers
279     void logEvent(const char *eventString);
280     void endEventLog(angle::EntryPoint entryPoint, PipelineType pipelineType);
281     void endEventLogForClearOrQuery();
282 
283     bool isViewportFlipEnabledForDrawFBO() const;
284     bool isViewportFlipEnabledForReadFBO() const;
285     // When the device/surface is rotated such that the surface's aspect ratio is different than
286     // the native device (e.g. 90 degrees), the width and height of the viewport, scissor, and
287     // render area must be swapped.
288     bool isRotatedAspectRatioForDrawFBO() const;
289     bool isRotatedAspectRatioForReadFBO() const;
290     SurfaceRotation getRotationDrawFramebuffer() const;
291     SurfaceRotation getRotationReadFramebuffer() const;
292 
293     // View port (x, y, w, h) will be determined by a combination of -
294     // 1. clip space origin
295     // 2. isViewportFlipEnabledForDrawFBO
296     // For userdefined FBOs it will be based on the value of isViewportFlipEnabledForDrawFBO.
297     // For default FBOs it will be XOR of ClipOrigin and isViewportFlipEnabledForDrawFBO.
298     // isYFlipEnabledForDrawFBO indicates the rendered image is upside-down.
isYFlipEnabledForDrawFBO()299     ANGLE_INLINE bool isYFlipEnabledForDrawFBO() const
300     {
301         return mState.getClipSpaceOrigin() == gl::ClipSpaceOrigin::UpperLeft
302                    ? !isViewportFlipEnabledForDrawFBO()
303                    : isViewportFlipEnabledForDrawFBO();
304     }
305 
306     // State sync with dirty bits.
307     angle::Result syncState(const gl::Context *context,
308                             const gl::State::DirtyBits &dirtyBits,
309                             const gl::State::DirtyBits &bitMask,
310                             gl::Command command) override;
311 
312     // Disjoint timer queries
313     GLint getGPUDisjoint() override;
314     GLint64 getTimestamp() override;
315 
316     // Context switching
317     angle::Result onMakeCurrent(const gl::Context *context) override;
318     angle::Result onUnMakeCurrent(const gl::Context *context) override;
319 
320     // Native capabilities, unmodified by gl::Context.
321     gl::Caps getNativeCaps() const override;
322     const gl::TextureCapsMap &getNativeTextureCaps() const override;
323     const gl::Extensions &getNativeExtensions() const override;
324     const gl::Limitations &getNativeLimitations() const override;
325 
326     // Shader creation
327     CompilerImpl *createCompiler() override;
328     ShaderImpl *createShader(const gl::ShaderState &state) override;
329     ProgramImpl *createProgram(const gl::ProgramState &state) override;
330 
331     // Framebuffer creation
332     FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override;
333 
334     // Texture creation
335     TextureImpl *createTexture(const gl::TextureState &state) override;
336 
337     // Renderbuffer creation
338     RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override;
339 
340     // Buffer creation
341     BufferImpl *createBuffer(const gl::BufferState &state) override;
342 
343     // Vertex Array creation
344     VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override;
345 
346     // Query and Fence creation
347     QueryImpl *createQuery(gl::QueryType type) override;
348     FenceNVImpl *createFenceNV() override;
349     SyncImpl *createSync() override;
350 
351     // Transform Feedback creation
352     TransformFeedbackImpl *createTransformFeedback(
353         const gl::TransformFeedbackState &state) override;
354 
355     // Sampler object creation
356     SamplerImpl *createSampler(const gl::SamplerState &state) override;
357 
358     // Program Pipeline object creation
359     ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
360 
361     // Memory object creation.
362     MemoryObjectImpl *createMemoryObject() override;
363 
364     // Semaphore creation.
365     SemaphoreImpl *createSemaphore() override;
366 
367     // Overlay creation.
368     OverlayImpl *createOverlay(const gl::OverlayState &state) override;
369 
370     angle::Result dispatchCompute(const gl::Context *context,
371                                   GLuint numGroupsX,
372                                   GLuint numGroupsY,
373                                   GLuint numGroupsZ) override;
374     angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;
375 
376     angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
377     angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
378 
invalidateTexture(gl::TextureType target)379     ANGLE_INLINE void invalidateTexture(gl::TextureType target) override {}
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     VkDevice getDevice() const;
getPriority()394     egl::ContextPriority getPriority() const { return mContextPriority; }
hasProtectedContent()395     bool hasProtectedContent() const { return mState.hasProtectedContent(); }
396 
getFeatures()397     ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); }
398 
invalidateVertexAndIndexBuffers()399     ANGLE_INLINE void invalidateVertexAndIndexBuffers()
400     {
401         mGraphicsDirtyBits |= kIndexAndVertexDirtyBits;
402     }
403 
404     angle::Result onVertexBufferChange(const vk::BufferHelper *vertexBuffer);
405 
406     angle::Result onVertexAttributeChange(size_t attribIndex,
407                                           GLuint stride,
408                                           GLuint divisor,
409                                           angle::FormatID format,
410                                           bool compressed,
411                                           GLuint relativeOffset,
412                                           const vk::BufferHelper *vertexBuffer);
413 
414     void invalidateDefaultAttribute(size_t attribIndex);
415     void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
416     angle::Result onFramebufferChange(FramebufferVk *framebufferVk, gl::Command command);
417     void onDrawFramebufferRenderPassDescChange(FramebufferVk *framebufferVk,
418                                                bool *renderPassDescChangedOut);
onHostVisibleBufferWrite()419     void onHostVisibleBufferWrite() { mIsAnyHostVisibleBufferWritten = true; }
420 
421     void invalidateCurrentTransformFeedbackBuffers();
422     void onTransformFeedbackStateChanged();
423     angle::Result onBeginTransformFeedback(
424         size_t bufferCount,
425         const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers,
426         const gl::TransformFeedbackBuffersArray<vk::BufferHelper> &counterBuffers);
427     void onEndTransformFeedback();
428     angle::Result onPauseTransformFeedback();
429     void pauseTransformFeedbackIfActiveUnpaused();
430 
onColorAccessChange()431     void onColorAccessChange() { mGraphicsDirtyBits |= kColorAccessChangeDirtyBits; }
onDepthStencilAccessChange()432     void onDepthStencilAccessChange() { mGraphicsDirtyBits |= kDepthStencilAccessChangeDirtyBits; }
433 
434     // When UtilsVk issues draw or dispatch calls, it binds a new pipeline and descriptor sets that
435     // the context is not aware of.  These functions are called to make sure the pipeline and
436     // affected descriptor set bindings are dirtied for the next application draw/dispatch call.
437     void invalidateGraphicsPipelineBinding();
438     void invalidateComputePipelineBinding();
439     void invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet);
440     void invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet);
441     void invalidateViewportAndScissor();
442     angle::Result updateRenderPassDepthFeedbackLoopMode(
443         UpdateDepthFeedbackLoopReason depthReason,
444         UpdateDepthFeedbackLoopReason stencilReason);
445 
446     angle::Result optimizeRenderPassForPresent(VkFramebuffer framebufferHandle,
447                                                vk::ImageViewHelper *colorImageView,
448                                                vk::ImageHelper *colorImage,
449                                                vk::ImageHelper *colorImageMS,
450                                                VkPresentModeKHR presentMode,
451                                                bool *imageResolved);
452 
453     vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);
454 
455     const VkClearValue &getClearColorValue() const;
456     const VkClearValue &getClearDepthStencilValue() const;
457     gl::BlendStateExt::ColorMaskStorage::Type getClearColorMasks() const;
getScissor()458     const VkRect2D &getScissor() const { return mScissor; }
459     angle::Result getIncompleteTexture(const gl::Context *context,
460                                        gl::TextureType type,
461                                        gl::SamplerFormat format,
462                                        gl::Texture **textureOut);
463     void updateColorMasks();
464     void updateBlendFuncsAndEquations();
465     void updateSampleMaskWithRasterizationSamples(const uint32_t rasterizationSamples);
466 
467     void handleError(VkResult errorCode,
468                      const char *file,
469                      const char *function,
470                      unsigned int line) override;
getActiveTextures()471     const gl::ActiveTextureArray<vk::TextureUnit> &getActiveTextures() const
472     {
473         return mActiveTextures;
474     }
getActiveImages()475     const gl::ActiveTextureArray<TextureVk *> &getActiveImages() const { return mActiveImages; }
476 
477     angle::Result onIndexBufferChange(const vk::BufferHelper *currentIndexBuffer);
478 
479     angle::Result flushImpl(const vk::Semaphore *semaphore,
480                             RenderPassClosureReason renderPassClosureReason);
481     angle::Result flushAndGetSerial(const vk::Semaphore *semaphore,
482                                     Serial *submitSerialOut,
483                                     RenderPassClosureReason renderPassClosureReason);
484     angle::Result finishImpl(RenderPassClosureReason renderPassClosureReason);
485 
486     void addWaitSemaphore(VkSemaphore semaphore, VkPipelineStageFlags stageMask);
487 
getLastCompletedQueueSerial()488     Serial getLastCompletedQueueSerial() const { return mRenderer->getLastCompletedQueueSerial(); }
489 
490     bool isSerialInUse(Serial serial) const;
491 
492     template <typename T>
addGarbage(T * object)493     void addGarbage(T *object)
494     {
495         if (object->valid())
496         {
497             mCurrentGarbage.emplace_back(vk::GetGarbage(object));
498         }
499     }
500 
501     // It would be nice if we didn't have to expose this for QueryVk::getResult.
502     angle::Result checkCompletedCommands();
503 
504     // Wait for completion of batches until (at least) batch with given serial is finished.
505     angle::Result finishToSerial(Serial serial);
506 
507     angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc,
508                                           vk::RenderPass **renderPassOut);
509     angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc,
510                                        const vk::AttachmentOpsArray &ops,
511                                        vk::RenderPass **renderPassOut);
512 
getShaderLibrary()513     vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; }
getUtils()514     UtilsVk &getUtils() { return mUtils; }
515 
516     angle::Result getTimestamp(uint64_t *timestampOut);
517 
518     // Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries.
519     // The events are queued until the query results are available.  Possible values for `phase`
520     // are TRACE_EVENT_PHASE_*
traceGpuEvent(vk::OutsideRenderPassCommandBuffer * commandBuffer,char phase,const EventName & name)521     ANGLE_INLINE angle::Result traceGpuEvent(vk::OutsideRenderPassCommandBuffer *commandBuffer,
522                                              char phase,
523                                              const EventName &name)
524     {
525         if (mGpuEventsEnabled)
526             return traceGpuEventImpl(commandBuffer, phase, name);
527         return angle::Result::Continue;
528     }
529 
getRenderPassCache()530     RenderPassCache &getRenderPassCache() { return mRenderPassCache; }
531 
532     vk::DescriptorSetLayoutDesc getDriverUniformsDescriptorSetDesc() const;
533 
534     void updateScissor(const gl::State &glState);
535 
536     void updateDepthStencil(const gl::State &glState);
537 
emulateSeamfulCubeMapSampling()538     bool emulateSeamfulCubeMapSampling() const { return mEmulateSeamfulCubeMapSampling; }
539 
getDebug()540     const gl::Debug &getDebug() const { return mState.getDebug(); }
getOverlay()541     const gl::OverlayType *getOverlay() const { return mState.getOverlay(); }
542 
getResourceUseList()543     vk::ResourceUseList &getResourceUseList() { return mResourceUseList; }
544 
545     angle::Result onBufferReleaseToExternal(const vk::BufferHelper &buffer);
546     angle::Result onImageReleaseToExternal(const vk::ImageHelper &image);
547 
onImageRenderPassRead(VkImageAspectFlags aspectFlags,vk::ImageLayout imageLayout,vk::ImageHelper * image)548     void onImageRenderPassRead(VkImageAspectFlags aspectFlags,
549                                vk::ImageLayout imageLayout,
550                                vk::ImageHelper *image)
551     {
552         ASSERT(mRenderPassCommands->started());
553         mRenderPassCommands->imageRead(this, aspectFlags, imageLayout, image);
554     }
555 
onImageRenderPassWrite(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,VkImageAspectFlags aspectFlags,vk::ImageLayout imageLayout,vk::ImageHelper * image)556     void onImageRenderPassWrite(gl::LevelIndex level,
557                                 uint32_t layerStart,
558                                 uint32_t layerCount,
559                                 VkImageAspectFlags aspectFlags,
560                                 vk::ImageLayout imageLayout,
561                                 vk::ImageHelper *image)
562     {
563         ASSERT(mRenderPassCommands->started());
564         mRenderPassCommands->imageWrite(this, level, layerStart, layerCount, aspectFlags,
565                                         imageLayout, vk::AliasingMode::Allowed, image);
566     }
567 
onColorDraw(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,vk::ImageHelper * resolveImage,vk::PackedAttachmentIndex packedAttachmentIndex)568     void onColorDraw(gl::LevelIndex level,
569                      uint32_t layerStart,
570                      uint32_t layerCount,
571                      vk::ImageHelper *image,
572                      vk::ImageHelper *resolveImage,
573                      vk::PackedAttachmentIndex packedAttachmentIndex)
574     {
575         ASSERT(mRenderPassCommands->started());
576         mRenderPassCommands->colorImagesDraw(&mResourceUseList, level, layerStart, layerCount,
577                                              image, resolveImage, packedAttachmentIndex);
578     }
onDepthStencilDraw(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,vk::ImageHelper * resolveImage)579     void onDepthStencilDraw(gl::LevelIndex level,
580                             uint32_t layerStart,
581                             uint32_t layerCount,
582                             vk::ImageHelper *image,
583                             vk::ImageHelper *resolveImage)
584     {
585         ASSERT(mRenderPassCommands->started());
586         mRenderPassCommands->depthStencilImagesDraw(&mResourceUseList, level, layerStart,
587                                                     layerCount, image, resolveImage);
588     }
589 
finalizeImageLayout(const vk::ImageHelper * image)590     void finalizeImageLayout(const vk::ImageHelper *image)
591     {
592         if (mRenderPassCommands->started())
593         {
594             mRenderPassCommands->finalizeImageLayout(this, image);
595         }
596     }
597 
getOutsideRenderPassCommandBuffer(const vk::CommandBufferAccess & access,vk::OutsideRenderPassCommandBuffer ** commandBufferOut)598     angle::Result getOutsideRenderPassCommandBuffer(
599         const vk::CommandBufferAccess &access,
600         vk::OutsideRenderPassCommandBuffer **commandBufferOut)
601     {
602         ANGLE_TRY(onResourceAccess(access));
603         *commandBufferOut = &mOutsideRenderPassCommands->getCommandBuffer();
604         return angle::Result::Continue;
605     }
606 
submitStagedTextureUpdates()607     angle::Result submitStagedTextureUpdates()
608     {
609         // Staged updates are recorded in outside RP cammand buffer, submit them.
610         return flushOutsideRenderPassCommands();
611     }
612 
613     angle::Result beginNewRenderPass(const vk::Framebuffer &framebuffer,
614                                      const gl::Rectangle &renderArea,
615                                      const vk::RenderPassDesc &renderPassDesc,
616                                      const vk::AttachmentOpsArray &renderPassAttachmentOps,
617                                      const vk::PackedAttachmentCount colorAttachmentCount,
618                                      const vk::PackedAttachmentIndex depthStencilAttachmentIndex,
619                                      const vk::PackedClearValuesArray &clearValues,
620                                      vk::RenderPassCommandBuffer **commandBufferOut);
621 
622     // Only returns true if we have a started RP and we've run setupDraw.
hasStartedRenderPass()623     bool hasStartedRenderPass() const
624     {
625         // Checking mRenderPassCommandBuffer ensures we've called setupDraw.
626         return mRenderPassCommandBuffer && mRenderPassCommands->started();
627     }
628 
hasStartedRenderPassWithFramebuffer(vk::Framebuffer * framebuffer)629     bool hasStartedRenderPassWithFramebuffer(vk::Framebuffer *framebuffer)
630     {
631         return hasStartedRenderPass() &&
632                mRenderPassCommands->getFramebufferHandle() == framebuffer->getHandle();
633     }
634 
hasStartedRenderPassWithCommands()635     bool hasStartedRenderPassWithCommands() const
636     {
637         return hasStartedRenderPass() && !mRenderPassCommands->getCommandBuffer().empty();
638     }
639 
getStartedRenderPassCommands()640     vk::RenderPassCommandBufferHelper &getStartedRenderPassCommands()
641     {
642         ASSERT(mRenderPassCommands->started());
643         return *mRenderPassCommands;
644     }
645 
646     // TODO(https://anglebug.com/4968): Support multiple open render passes.
647     void restoreFinishedRenderPass(vk::Framebuffer *framebuffer);
648 
649     uint32_t getCurrentSubpassIndex() const;
650     uint32_t getCurrentViewCount() const;
651 
getContextPriority()652     egl::ContextPriority getContextPriority() const override { return mContextPriority; }
653     angle::Result startRenderPass(gl::Rectangle renderArea,
654                                   vk::RenderPassCommandBuffer **commandBufferOut,
655                                   bool *renderPassDescChangedOut);
656     angle::Result startNextSubpass();
657     angle::Result flushCommandsAndEndRenderPass(RenderPassClosureReason reason);
658     angle::Result flushCommandsAndEndRenderPassWithoutQueueSubmit(RenderPassClosureReason reason);
659     angle::Result submitOutsideRenderPassCommandsImpl();
660 
661     angle::Result syncExternalMemory();
662 
663     void addCommandBufferDiagnostics(const std::string &commandBufferDiagnostics);
664 
665     VkIndexType getVkIndexType(gl::DrawElementsType glIndexType) const;
666     size_t getVkIndexTypeSize(gl::DrawElementsType glIndexType) const;
667     bool shouldConvertUint8VkIndexType(gl::DrawElementsType glIndexType) const;
668 
isBresenhamEmulationEnabled(const gl::PrimitiveMode mode)669     ANGLE_INLINE bool isBresenhamEmulationEnabled(const gl::PrimitiveMode mode)
670     {
671         return getFeatures().basicGLLineRasterization.enabled && gl::IsLineMode(mode);
672     }
673 
674     ProgramExecutableVk *getExecutable() const;
675 
676     bool isRobustResourceInitEnabled() const;
677 
678     // Queries that begin and end automatically with render pass start and end
679     angle::Result beginRenderPassQuery(QueryVk *queryVk);
680     angle::Result endRenderPassQuery(QueryVk *queryVk);
681     void pauseRenderPassQueriesIfActive();
682     angle::Result resumeRenderPassQueriesIfActive();
683     angle::Result resumeXfbRenderPassQueriesIfActive();
684     bool doesPrimitivesGeneratedQuerySupportRasterizerDiscard() const;
685     bool isEmulatingRasterizerDiscardDuringPrimitivesGeneratedQuery(
686         bool isPrimitivesGeneratedQueryActive) const;
687 
688     // Used by QueryVk to share query helpers between transform feedback queries.
689     QueryVk *getActiveRenderPassQuery(gl::QueryType queryType) const;
690 
691     void syncObjectPerfCounters();
692     void updateOverlayOnPresent();
693     void addOverlayUsedBuffersCount(vk::CommandBufferHelperCommon *commandBuffer);
694 
695     // For testing only.
696     void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
697 
getEmptyBuffer()698     vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; }
699 
700     // Keeping track of the buffer copy size. Used to determine when to submit the outside command
701     // buffer.
702     angle::Result onCopyUpdate(VkDeviceSize size);
resetTotalBufferToImageCopySize()703     void resetTotalBufferToImageCopySize() { mTotalBufferToImageCopySize = 0; }
getTotalBufferToImageCopySize()704     VkDeviceSize getTotalBufferToImageCopySize() const { return mTotalBufferToImageCopySize; }
705 
706     // Implementation of MultisampleTextureInitializer
707     angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
708                                                       gl::Texture *glTexture) override;
709 
710     // TODO(http://anglebug.com/5624): rework updateActiveTextures(), createPipelineLayout(),
711     // handleDirtyGraphicsPipeline(), and ProgramPipelineVk::link().
resetCurrentGraphicsPipeline()712     void resetCurrentGraphicsPipeline() { mCurrentGraphicsPipeline = nullptr; }
713 
714     void onProgramExecutableReset(ProgramExecutableVk *executableVk);
715 
716     angle::Result handleGraphicsEventLog(GraphicsEventCmdBuf queryEventType);
717 
718     void flushDescriptorSetUpdates();
719 
getDefaultBufferPool(VkDeviceSize size,uint32_t memoryTypeIndex)720     vk::BufferPool *getDefaultBufferPool(VkDeviceSize size, uint32_t memoryTypeIndex)
721     {
722         return mShareGroupVk->getDefaultBufferPool(mRenderer, size, memoryTypeIndex);
723     }
724 
allocateStreamedVertexBuffer(size_t attribIndex,size_t bytesToAllocate,vk::BufferHelper ** vertexBufferOut)725     angle::Result allocateStreamedVertexBuffer(size_t attribIndex,
726                                                size_t bytesToAllocate,
727                                                vk::BufferHelper **vertexBufferOut)
728     {
729         bool newBufferOut;
730         ANGLE_TRY(mStreamedVertexBuffers[attribIndex].allocate(this, bytesToAllocate,
731                                                                vertexBufferOut, &newBufferOut));
732         if (newBufferOut)
733         {
734             mHasInFlightStreamedVertexBuffers.set(attribIndex);
735         }
736         return angle::Result::Continue;
737     }
738 
739     const angle::PerfMonitorCounterGroups &getPerfMonitorCounters() override;
740 
741     void resetPerFramePerfCounters();
742 
743   private:
744     // Dirty bits.
745     enum DirtyBitType : size_t
746     {
747         // Dirty bits that must be processed before the render pass is started.  The handlers for
748         // these dirty bits don't record any commands.
749 
750         // A glMemoryBarrier has been called and command buffers may need flushing.
751         DIRTY_BIT_MEMORY_BARRIER,
752         // Update default attribute buffers.
753         DIRTY_BIT_DEFAULT_ATTRIBS,
754         // The pipeline has changed and needs to be recreated.  This dirty bit may close the render
755         // pass.
756         DIRTY_BIT_PIPELINE_DESC,
757         // Support for depth/stencil read-only feedback loop.  When depth/stencil access changes,
758         // the render pass may need closing.
759         DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE,
760 
761         // Start the render pass.
762         DIRTY_BIT_RENDER_PASS,
763 
764         // Dirty bits that must be processed after the render pass is started.  Their handlers
765         // record commands.
766         DIRTY_BIT_EVENT_LOG,
767         // Update color and depth/stencil accesses in the render pass.
768         DIRTY_BIT_COLOR_ACCESS,
769         DIRTY_BIT_DEPTH_STENCIL_ACCESS,
770         // Pipeline needs to rebind because a new command buffer has been allocated, or UtilsVk has
771         // changed the binding.  The pipeline itself doesn't need to be recreated.
772         DIRTY_BIT_PIPELINE_BINDING,
773         DIRTY_BIT_TEXTURES,
774         DIRTY_BIT_VERTEX_BUFFERS,
775         DIRTY_BIT_INDEX_BUFFER,
776         DIRTY_BIT_UNIFORMS,
777         DIRTY_BIT_DRIVER_UNIFORMS,
778         DIRTY_BIT_DRIVER_UNIFORMS_BINDING,
779         // Shader resources excluding textures, which are handled separately.
780         DIRTY_BIT_SHADER_RESOURCES,
781         DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
782         DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME,
783         DIRTY_BIT_DESCRIPTOR_SETS,
784         DIRTY_BIT_FRAMEBUFFER_FETCH_BARRIER,
785         DIRTY_BIT_BLEND_BARRIER,
786         // Dynamic viewport/scissor
787         DIRTY_BIT_VIEWPORT,
788         DIRTY_BIT_SCISSOR,
789         DIRTY_BIT_MAX,
790     };
791 
792     // Dirty bit handlers that can break the render pass must always be specified before
793     // DIRTY_BIT_RENDER_PASS.
794     static_assert(
795         DIRTY_BIT_MEMORY_BARRIER < DIRTY_BIT_RENDER_PASS,
796         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
797     static_assert(
798         DIRTY_BIT_DEFAULT_ATTRIBS < DIRTY_BIT_RENDER_PASS,
799         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
800     static_assert(
801         DIRTY_BIT_PIPELINE_DESC < DIRTY_BIT_RENDER_PASS,
802         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
803     static_assert(
804         DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE < DIRTY_BIT_RENDER_PASS,
805         "Render pass breaking dirty bit must be handled before the render pass dirty bit");
806 
807     // Dirty bit handlers that record commands or otherwise expect to manipulate the render pass
808     // that will be used for the draw call must be specified after DIRTY_BIT_RENDER_PASS.
809     static_assert(DIRTY_BIT_EVENT_LOG > DIRTY_BIT_RENDER_PASS,
810                   "Render pass using dirty bit must be handled after the render pass dirty bit");
811     static_assert(DIRTY_BIT_COLOR_ACCESS > DIRTY_BIT_RENDER_PASS,
812                   "Render pass using dirty bit must be handled after the render pass dirty bit");
813     static_assert(DIRTY_BIT_DEPTH_STENCIL_ACCESS > DIRTY_BIT_RENDER_PASS,
814                   "Render pass using dirty bit must be handled after the render pass dirty bit");
815     static_assert(DIRTY_BIT_PIPELINE_BINDING > DIRTY_BIT_RENDER_PASS,
816                   "Render pass using dirty bit must be handled after the render pass dirty bit");
817     static_assert(DIRTY_BIT_TEXTURES > DIRTY_BIT_RENDER_PASS,
818                   "Render pass using dirty bit must be handled after the render pass dirty bit");
819     static_assert(DIRTY_BIT_VERTEX_BUFFERS > DIRTY_BIT_RENDER_PASS,
820                   "Render pass using dirty bit must be handled after the render pass dirty bit");
821     static_assert(DIRTY_BIT_INDEX_BUFFER > DIRTY_BIT_RENDER_PASS,
822                   "Render pass using dirty bit must be handled after the render pass dirty bit");
823     static_assert(DIRTY_BIT_DRIVER_UNIFORMS > DIRTY_BIT_RENDER_PASS,
824                   "Render pass using dirty bit must be handled after the render pass dirty bit");
825     static_assert(DIRTY_BIT_DRIVER_UNIFORMS_BINDING > DIRTY_BIT_RENDER_PASS,
826                   "Render pass using dirty bit must be handled after the render pass dirty bit");
827     static_assert(DIRTY_BIT_SHADER_RESOURCES > DIRTY_BIT_RENDER_PASS,
828                   "Render pass using dirty bit must be handled after the render pass dirty bit");
829     static_assert(DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS > DIRTY_BIT_RENDER_PASS,
830                   "Render pass using dirty bit must be handled after the render pass dirty bit");
831     static_assert(DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME > DIRTY_BIT_RENDER_PASS,
832                   "Render pass using dirty bit must be handled after the render pass dirty bit");
833     static_assert(DIRTY_BIT_DESCRIPTOR_SETS > DIRTY_BIT_RENDER_PASS,
834                   "Render pass using dirty bit must be handled after the render pass dirty bit");
835     static_assert(DIRTY_BIT_UNIFORMS > DIRTY_BIT_RENDER_PASS,
836                   "Render pass using dirty bit must be handled after the render pass dirty bit");
837     static_assert(DIRTY_BIT_FRAMEBUFFER_FETCH_BARRIER > DIRTY_BIT_RENDER_PASS,
838                   "Render pass using dirty bit must be handled after the render pass dirty bit");
839     static_assert(DIRTY_BIT_BLEND_BARRIER > DIRTY_BIT_RENDER_PASS,
840                   "Render pass using dirty bit must be handled after the render pass dirty bit");
841     static_assert(DIRTY_BIT_VIEWPORT > DIRTY_BIT_RENDER_PASS,
842                   "Render pass using dirty bit must be handled after the render pass dirty bit");
843     static_assert(DIRTY_BIT_SCISSOR > DIRTY_BIT_RENDER_PASS,
844                   "Render pass using dirty bit must be handled after the render pass dirty bit");
845 
846     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
847 
848     using GraphicsDirtyBitHandler = angle::Result (
849         ContextVk::*)(DirtyBits::Iterator *dirtyBitsIterator, DirtyBits dirtyBitMask);
850     using ComputeDirtyBitHandler = angle::Result (ContextVk::*)();
851 
852     struct DriverUniformsDescriptorSet
853     {
854         vk::DynamicBuffer dynamicBuffer;
855         VkDescriptorSet descriptorSet;
856         vk::BufferHelper *currentBuffer;
857         vk::BindingPointer<vk::DescriptorSetLayout> descriptorSetLayout;
858         vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
859         DriverUniformsDescriptorSetCache descriptorSetCache;
860 
861         DriverUniformsDescriptorSet();
862         ~DriverUniformsDescriptorSet();
863 
864         void init(RendererVk *rendererVk);
865         void destroy(RendererVk *rendererVk);
866     };
867 
868     // The GpuEventQuery struct holds together a timestamp query and enough data to create a
869     // trace event based on that. Use traceGpuEvent to insert such queries.  They will be readback
870     // when the results are available, without inserting a GPU bubble.
871     //
872     // - eventName will be the reported name of the event
873     // - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event).
874     //   See Google's "Trace Event Format":
875     //   https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
876     // - serial is the serial of the batch the query was submitted on.  Until the batch is
877     //   submitted, the query is not checked to avoid incuring a flush.
878     struct GpuEventQuery final
879     {
880         EventName name;
881         char phase;
882         vk::QueryHelper queryHelper;
883     };
884 
885     // Once a query result is available, the timestamp is read and a GpuEvent object is kept until
886     // the next clock sync, at which point the clock drift is compensated in the results before
887     // handing them off to the application.
888     struct GpuEvent final
889     {
890         uint64_t gpuTimestampCycles;
891         std::array<char, kMaxGpuEventNameLen> name;
892         char phase;
893     };
894 
895     struct GpuClockSyncInfo
896     {
897         double gpuTimestampS;
898         double cpuTimestampS;
899     };
900 
901     class ScopedDescriptorSetUpdates;
902 
903     angle::Result setupDraw(const gl::Context *context,
904                             gl::PrimitiveMode mode,
905                             GLint firstVertexOrInvalid,
906                             GLsizei vertexOrIndexCount,
907                             GLsizei instanceCount,
908                             gl::DrawElementsType indexTypeOrInvalid,
909                             const void *indices,
910                             DirtyBits dirtyBitMask);
911 
912     angle::Result setupIndexedDraw(const gl::Context *context,
913                                    gl::PrimitiveMode mode,
914                                    GLsizei indexCount,
915                                    GLsizei instanceCount,
916                                    gl::DrawElementsType indexType,
917                                    const void *indices);
918     angle::Result setupIndirectDraw(const gl::Context *context,
919                                     gl::PrimitiveMode mode,
920                                     DirtyBits dirtyBitMask,
921                                     vk::BufferHelper *indirectBuffer);
922     angle::Result setupIndexedIndirectDraw(const gl::Context *context,
923                                            gl::PrimitiveMode mode,
924                                            gl::DrawElementsType indexType,
925                                            vk::BufferHelper *indirectBuffer);
926 
927     angle::Result setupLineLoopIndexedIndirectDraw(const gl::Context *context,
928                                                    gl::PrimitiveMode mode,
929                                                    gl::DrawElementsType indexType,
930                                                    vk::BufferHelper *srcIndirectBuf,
931                                                    VkDeviceSize indirectBufferOffset,
932                                                    vk::BufferHelper **indirectBufferOut);
933     angle::Result setupLineLoopIndirectDraw(const gl::Context *context,
934                                             gl::PrimitiveMode mode,
935                                             vk::BufferHelper *indirectBuffer,
936                                             VkDeviceSize indirectBufferOffset,
937                                             vk::BufferHelper **indirectBufferOut);
938 
939     angle::Result setupLineLoopDraw(const gl::Context *context,
940                                     gl::PrimitiveMode mode,
941                                     GLint firstVertex,
942                                     GLsizei vertexOrIndexCount,
943                                     gl::DrawElementsType indexTypeOrInvalid,
944                                     const void *indices,
945                                     uint32_t *numIndicesOut);
946 
947     angle::Result setupDispatch(const gl::Context *context);
948 
949     gl::Rectangle getCorrectedViewport(const gl::Rectangle &viewport) const;
950     void updateViewport(FramebufferVk *framebufferVk,
951                         const gl::Rectangle &viewport,
952                         float nearPlane,
953                         float farPlane);
954     void updateDepthRange(float nearPlane, float farPlane);
955     void updateFlipViewportDrawFramebuffer(const gl::State &glState);
956     void updateFlipViewportReadFramebuffer(const gl::State &glState);
957     void updateSurfaceRotationDrawFramebuffer(const gl::State &glState);
958     void updateSurfaceRotationReadFramebuffer(const gl::State &glState);
959 
960     angle::Result updateActiveTextures(const gl::Context *context, gl::Command command);
961     template <typename CommandBufferHelperT>
962     angle::Result updateActiveImages(CommandBufferHelperT *commandBufferHelper);
963 
invalidateCurrentGraphicsPipeline()964     ANGLE_INLINE void invalidateCurrentGraphicsPipeline()
965     {
966         // Note: DIRTY_BIT_PIPELINE_BINDING will be automatically set if pipeline bind is necessary.
967         mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE_DESC);
968     }
969 
invalidateCurrentComputePipeline()970     ANGLE_INLINE void invalidateCurrentComputePipeline()
971     {
972         mComputeDirtyBits |= kPipelineDescAndBindingDirtyBits;
973         mCurrentComputePipeline = nullptr;
974     }
975 
976     angle::Result invalidateProgramExecutableHelper(const gl::Context *context);
977     angle::Result checkAndUpdateFramebufferFetchStatus(const gl::ProgramExecutable *executable);
978 
979     void invalidateCurrentDefaultUniforms();
980     angle::Result invalidateCurrentTextures(const gl::Context *context, gl::Command command);
981     angle::Result invalidateCurrentShaderResources(gl::Command command);
982     void invalidateGraphicsDriverUniforms();
983     void invalidateDriverUniforms();
984 
985     angle::Result handleNoopDrawEvent() override;
986 
987     // Handlers for graphics pipeline dirty bits.
988     angle::Result handleDirtyGraphicsMemoryBarrier(DirtyBits::Iterator *dirtyBitsIterator,
989                                                    DirtyBits dirtyBitMask);
990     angle::Result handleDirtyGraphicsDefaultAttribs(DirtyBits::Iterator *dirtyBitsIterator,
991                                                     DirtyBits dirtyBitMask);
992     angle::Result handleDirtyGraphicsPipelineDesc(DirtyBits::Iterator *dirtyBitsIterator,
993                                                   DirtyBits dirtyBitMask);
994     angle::Result handleDirtyGraphicsReadOnlyDepthFeedbackLoopMode(
995         DirtyBits::Iterator *dirtyBitsIterator,
996         DirtyBits dirtyBitMask);
997     angle::Result handleDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
998                                                 DirtyBits dirtyBitMask);
999     angle::Result handleDirtyGraphicsEventLog(DirtyBits::Iterator *dirtyBitsIterator,
1000                                               DirtyBits dirtyBitMask);
1001     angle::Result handleDirtyGraphicsColorAccess(DirtyBits::Iterator *dirtyBitsIterator,
1002                                                  DirtyBits dirtyBitMask);
1003     angle::Result handleDirtyGraphicsDepthStencilAccess(DirtyBits::Iterator *dirtyBitsIterator,
1004                                                         DirtyBits dirtyBitMask);
1005     angle::Result handleDirtyGraphicsPipelineBinding(DirtyBits::Iterator *dirtyBitsIterator,
1006                                                      DirtyBits dirtyBitMask);
1007     angle::Result handleDirtyGraphicsTextures(DirtyBits::Iterator *dirtyBitsIterator,
1008                                               DirtyBits dirtyBitMask);
1009     angle::Result handleDirtyGraphicsVertexBuffers(DirtyBits::Iterator *dirtyBitsIterator,
1010                                                    DirtyBits dirtyBitMask);
1011     angle::Result handleDirtyGraphicsIndexBuffer(DirtyBits::Iterator *dirtyBitsIterator,
1012                                                  DirtyBits dirtyBitMask);
1013     angle::Result handleDirtyGraphicsDriverUniforms(DirtyBits::Iterator *dirtyBitsIterator,
1014                                                     DirtyBits dirtyBitMask);
1015     angle::Result handleDirtyGraphicsDriverUniformsBinding(DirtyBits::Iterator *dirtyBitsIterator,
1016                                                            DirtyBits dirtyBitMask);
1017     angle::Result handleDirtyGraphicsShaderResources(DirtyBits::Iterator *dirtyBitsIterator,
1018                                                      DirtyBits dirtyBitMask);
1019     angle::Result handleDirtyGraphicsFramebufferFetchBarrier(DirtyBits::Iterator *dirtyBitsIterator,
1020                                                              DirtyBits dirtyBitMask);
1021     angle::Result handleDirtyGraphicsBlendBarrier(DirtyBits::Iterator *dirtyBitsIterator,
1022                                                   DirtyBits dirtyBitMask);
1023     angle::Result handleDirtyGraphicsTransformFeedbackBuffersEmulation(
1024         DirtyBits::Iterator *dirtyBitsIterator,
1025         DirtyBits dirtyBitMask);
1026     angle::Result handleDirtyGraphicsTransformFeedbackBuffersExtension(
1027         DirtyBits::Iterator *dirtyBitsIterator,
1028         DirtyBits dirtyBitMask);
1029     angle::Result handleDirtyGraphicsTransformFeedbackResume(DirtyBits::Iterator *dirtyBitsIterator,
1030                                                              DirtyBits dirtyBitMask);
1031     angle::Result handleDirtyGraphicsDescriptorSets(DirtyBits::Iterator *dirtyBitsIterator,
1032                                                     DirtyBits dirtyBitMask);
1033     angle::Result handleDirtyGraphicsUniforms(DirtyBits::Iterator *dirtyBitsIterator,
1034                                               DirtyBits dirtyBitMask);
1035     angle::Result handleDirtyGraphicsViewport(DirtyBits::Iterator *dirtyBitsIterator,
1036                                               DirtyBits dirtyBitMask);
1037     angle::Result handleDirtyGraphicsScissor(DirtyBits::Iterator *dirtyBitsIterator,
1038                                              DirtyBits dirtyBitMask);
1039 
1040     // Handlers for compute pipeline dirty bits.
1041     angle::Result handleDirtyComputeMemoryBarrier();
1042     angle::Result handleDirtyComputeEventLog();
1043     angle::Result handleDirtyComputePipelineDesc();
1044     angle::Result handleDirtyComputePipelineBinding();
1045     angle::Result handleDirtyComputeTextures();
1046     angle::Result handleDirtyComputeDriverUniforms();
1047     angle::Result handleDirtyComputeDriverUniformsBinding();
1048     angle::Result handleDirtyComputeShaderResources();
1049     angle::Result handleDirtyComputeDescriptorSets();
1050     angle::Result handleDirtyComputeUniforms();
1051 
1052     // Common parts of the common dirty bit handlers.
1053     angle::Result handleDirtyUniformsImpl();
1054     angle::Result handleDirtyMemoryBarrierImpl(DirtyBits::Iterator *dirtyBitsIterator,
1055                                                DirtyBits dirtyBitMask);
1056     template <typename CommandBufferT>
1057     angle::Result handleDirtyEventLogImpl(CommandBufferT *commandBuffer);
1058     template <typename CommandBufferHelperT>
1059     angle::Result handleDirtyTexturesImpl(CommandBufferHelperT *commandBufferHelper,
1060                                           PipelineType pipelineType);
1061     template <typename CommandBufferHelperT>
1062     angle::Result handleDirtyShaderResourcesImpl(CommandBufferHelperT *commandBufferHelper,
1063                                                  PipelineType pipelineType);
1064     void handleDirtyShaderBufferResourcesImpl(vk::CommandBufferHelperCommon *commandBufferHelper);
1065     template <typename CommandBufferT>
1066     void handleDirtyDriverUniformsBindingImpl(CommandBufferT *commandBuffer,
1067                                               VkPipelineBindPoint bindPoint,
1068                                               DriverUniformsDescriptorSet *driverUniforms);
1069     template <typename CommandBufferT>
1070     angle::Result handleDirtyDescriptorSetsImpl(CommandBufferT *commandBuffer,
1071                                                 PipelineType pipelineType);
1072     void handleDirtyGraphicsScissorImpl(bool isPrimitivesGeneratedQueryActive);
1073 
1074     angle::Result allocateDriverUniforms(size_t driverUniformsSize,
1075                                          DriverUniformsDescriptorSet *driverUniforms,
1076                                          uint8_t **ptrOut,
1077                                          bool *newBufferOut);
1078     angle::Result updateDriverUniformsDescriptorSet(bool newBuffer,
1079                                                     size_t driverUniformsSize,
1080                                                     PipelineType pipelineType);
1081 
1082     void writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOut, size_t offsetsSize);
1083 
1084     angle::Result submitFrame(const vk::Semaphore *signalSemaphore, Serial *submitSerialOut);
1085     angle::Result submitFrameOutsideCommandBufferOnly(Serial *submitSerialOut);
1086     angle::Result submitCommands(const vk::Semaphore *signalSemaphore, Serial *submitSerialOut);
1087 
1088     angle::Result synchronizeCpuGpuTime();
1089     angle::Result traceGpuEventImpl(vk::OutsideRenderPassCommandBuffer *commandBuffer,
1090                                     char phase,
1091                                     const EventName &name);
1092     angle::Result checkCompletedGpuEvents();
1093     void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS);
1094     void handleDeviceLost();
1095     bool shouldEmulateSeamfulCubeMapSampling() const;
1096     void clearAllGarbage();
1097     void dumpCommandStreamDiagnostics();
1098     angle::Result flushOutsideRenderPassCommands();
1099     // Flush commands and end render pass without setting any dirty bits.
1100     // flushCommandsAndEndRenderPass() and flushDirtyGraphicsRenderPass() will set the dirty bits
1101     // directly or through the iterator respectively.  Outside those two functions, this shouldn't
1102     // be called directly.
1103     angle::Result flushCommandsAndEndRenderPassImpl(QueueSubmitType queueSubmit,
1104                                                     RenderPassClosureReason reason);
1105     angle::Result flushDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
1106                                                DirtyBits dirtyBitMask,
1107                                                RenderPassClosureReason reason);
1108 
1109     void onRenderPassFinished(RenderPassClosureReason reason);
1110 
1111     void initIndexTypeMap();
1112 
1113     VertexArrayVk *getVertexArray() const;
1114     FramebufferVk *getDrawFramebuffer() const;
1115     ProgramVk *getProgram() const;
1116     ProgramPipelineVk *getProgramPipeline() const;
1117 
1118     // Read-after-write hazards are generally handled with |glMemoryBarrier| when the source of
1119     // write is storage output.  When the write is outside render pass, the natural placement of the
1120     // render pass after the current outside render pass commands ensures that the memory barriers
1121     // and image layout transitions automatically take care of such synchronizations.
1122     //
1123     // There are a number of read-after-write cases that require breaking the render pass however to
1124     // preserve the order of operations:
1125     //
1126     // - Transform feedback write (in render pass), then vertex/index read (in render pass)
1127     // - Transform feedback write (in render pass), then ubo read (outside render pass)
1128     // - Framebuffer attachment write (in render pass), then texture sample (outside render pass)
1129     //   * Note that texture sampling inside render pass would cause a feedback loop
1130     //
1131     angle::Result endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper *buffer);
1132     angle::Result endRenderPassIfComputeReadAfterTransformFeedbackWrite();
1133     angle::Result endRenderPassIfComputeReadAfterAttachmentWrite();
1134 
1135     void populateTransformFeedbackBufferSet(
1136         size_t bufferCount,
1137         const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers);
1138 
1139     // Update framebuffer's read-only depth feedback loop mode.  Typically called from
1140     // handleDirtyGraphicsReadOnlyDepthFeedbackLoopMode, but can be called from UtilsVk in functions
1141     // that don't necessarily break the render pass.
1142     angle::Result updateRenderPassDepthFeedbackLoopModeImpl(
1143         DirtyBits::Iterator *dirtyBitsIterator,
1144         DirtyBits dirtyBitMask,
1145         UpdateDepthFeedbackLoopReason depthReason,
1146         UpdateDepthFeedbackLoopReason stencilReason);
1147     bool shouldSwitchToReadOnlyDepthFeedbackLoopMode(gl::Texture *texture,
1148                                                      gl::Command command) const;
1149 
1150     angle::Result onResourceAccess(const vk::CommandBufferAccess &access);
1151     angle::Result flushCommandBuffersIfNecessary(const vk::CommandBufferAccess &access);
1152     bool renderPassUsesStorageResources() const;
1153 
1154     angle::Result pushDebugGroupImpl(GLenum source, GLuint id, const char *message);
1155     angle::Result popDebugGroupImpl();
1156 
1157     void updateSampleShadingWithRasterizationSamples(const uint32_t rasterizationSamples);
1158     void updateRasterizationSamples(const uint32_t rasterizationSamples);
1159     void updateRasterizerDiscardEnabled(bool isPrimitivesGeneratedQueryActive);
1160 
1161     void updateAdvancedBlendEquations(const gl::ProgramExecutable *executable);
1162 
1163     void updateDither();
1164 
1165     SpecConstUsageBits getCurrentProgramSpecConstUsageBits() const;
1166     void updateGraphicsPipelineDescWithSpecConstUsageBits(SpecConstUsageBits usageBits);
1167 
1168     void updateShaderResourcesDescriptorDesc(PipelineType pipelineType);
1169 
1170     std::array<GraphicsDirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
1171     std::array<ComputeDirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;
1172 
1173     vk::RenderPassCommandBuffer *mRenderPassCommandBuffer;
1174 
1175     vk::PipelineHelper *mCurrentGraphicsPipeline;
1176     vk::PipelineHelper *mCurrentComputePipeline;
1177     gl::PrimitiveMode mCurrentDrawMode;
1178 
1179     WindowSurfaceVk *mCurrentWindowSurface;
1180     // Records the current rotation of the surface (draw/read) framebuffer, derived from
1181     // mCurrentWindowSurface->getPreTransform().
1182     SurfaceRotation mCurrentRotationDrawFramebuffer;
1183     SurfaceRotation mCurrentRotationReadFramebuffer;
1184 
1185     // Keep a cached pipeline description structure that can be used to query the pipeline cache.
1186     // Kept in a pointer so allocations can be aligned, and structs can be portably packed.
1187     std::unique_ptr<vk::GraphicsPipelineDesc> mGraphicsPipelineDesc;
1188     vk::GraphicsPipelineTransitionBits mGraphicsPipelineTransition;
1189 
1190     // These pools are externally synchronized, so cannot be accessed from different
1191     // threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk.
1192     // Note that this implementation would need to change in shared resource scenarios. Likely
1193     // we'd instead share a single set of pools between the share groups.
1194     angle::PackedEnumMap<PipelineType, vk::DynamicDescriptorPool> mDriverUniformsDescriptorPools;
1195     gl::QueryTypeMap<vk::DynamicQueryPool> mQueryPools;
1196 
1197     // Queries that need to be closed and reopened with the render pass:
1198     //
1199     // - Occlusion queries
1200     // - Transform feedback queries, if not emulated
1201     gl::QueryTypeMap<QueryVk *> mActiveRenderPassQueries;
1202 
1203     // Dirty bits.
1204     DirtyBits mGraphicsDirtyBits;
1205     DirtyBits mComputeDirtyBits;
1206     DirtyBits mNonIndexedDirtyBitsMask;
1207     DirtyBits mIndexedDirtyBitsMask;
1208     DirtyBits mNewGraphicsCommandBufferDirtyBits;
1209     DirtyBits mNewComputeCommandBufferDirtyBits;
1210     static constexpr DirtyBits kColorAccessChangeDirtyBits{DIRTY_BIT_COLOR_ACCESS};
1211     static constexpr DirtyBits kDepthStencilAccessChangeDirtyBits{
1212         DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE, DIRTY_BIT_DEPTH_STENCIL_ACCESS};
1213     static constexpr DirtyBits kIndexAndVertexDirtyBits{DIRTY_BIT_VERTEX_BUFFERS,
1214                                                         DIRTY_BIT_INDEX_BUFFER};
1215     static constexpr DirtyBits kPipelineDescAndBindingDirtyBits{DIRTY_BIT_PIPELINE_DESC,
1216                                                                 DIRTY_BIT_PIPELINE_BINDING};
1217     static constexpr DirtyBits kTexturesAndDescSetDirtyBits{DIRTY_BIT_TEXTURES,
1218                                                             DIRTY_BIT_DESCRIPTOR_SETS};
1219     static constexpr DirtyBits kResourcesAndDescSetDirtyBits{DIRTY_BIT_SHADER_RESOURCES,
1220                                                              DIRTY_BIT_DESCRIPTOR_SETS};
1221     static constexpr DirtyBits kXfbBuffersAndDescSetDirtyBits{DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
1222                                                               DIRTY_BIT_DESCRIPTOR_SETS};
1223     static constexpr DirtyBits kDriverUniformsAndBindingDirtyBits{
1224         DIRTY_BIT_DRIVER_UNIFORMS, DIRTY_BIT_DRIVER_UNIFORMS_BINDING};
1225 
1226     // The offset we had the last time we bound the index buffer.
1227     const GLvoid *mLastIndexBufferOffset;
1228     VkDeviceSize mCurrentIndexBufferOffset;
1229     gl::DrawElementsType mCurrentDrawElementsType;
1230     angle::PackedEnumMap<gl::DrawElementsType, VkIndexType> mIndexTypeMap;
1231 
1232     // Cache the current draw call's firstVertex to be passed to
1233     // TransformFeedbackVk::getBufferOffsets.  Unfortunately, gl_BaseVertex support in Vulkan is
1234     // not yet ubiquitous, which would have otherwise removed the need for this value to be passed
1235     // as a uniform.
1236     GLint mXfbBaseVertex;
1237     // Cache the current draw call's vertex count as well to support instanced draw calls
1238     GLuint mXfbVertexCountPerInstance;
1239 
1240     // Cached clear value/mask for color and depth/stencil.
1241     VkClearValue mClearColorValue;
1242     VkClearValue mClearDepthStencilValue;
1243     gl::BlendStateExt::ColorMaskStorage::Type mClearColorMasks;
1244 
1245     IncompleteTextureSet mIncompleteTextures;
1246 
1247     // If the current surface bound to this context wants to have all rendering flipped vertically.
1248     // Updated on calls to onMakeCurrent.
1249     bool mFlipYForCurrentSurface;
1250     bool mFlipViewportForDrawFramebuffer;
1251     bool mFlipViewportForReadFramebuffer;
1252 
1253     // If any host-visible buffer is written by the GPU since last submission, a barrier is inserted
1254     // at the end of the command buffer to make that write available to the host.
1255     bool mIsAnyHostVisibleBufferWritten;
1256 
1257     // Whether this context should do seamful cube map sampling emulation.
1258     bool mEmulateSeamfulCubeMapSampling;
1259 
1260     angle::PackedEnumMap<PipelineType, DriverUniformsDescriptorSet> mDriverUniforms;
1261 
1262     // This cache should also probably include the texture index (shader location) and array
1263     // index (also in the shader). This info is used in the descriptor update step.
1264     gl::ActiveTextureArray<vk::TextureUnit> mActiveTextures;
1265 
1266     // We use textureSerial to optimize texture binding updates. Each permutation of a
1267     // {VkImage/VkSampler} generates a unique serial. These object ids are combined to form a unique
1268     // signature for each descriptor set. This allows us to keep a cache of descriptor sets and
1269     // avoid calling vkAllocateDesctiporSets each texture update.
1270     vk::DescriptorSetDesc mActiveTexturesDesc;
1271 
1272     vk::DescriptorSetDesc mShaderBuffersDescriptorDesc;
1273 
1274     gl::ActiveTextureArray<TextureVk *> mActiveImages;
1275 
1276     // "Current Value" aka default vertex attribute state.
1277     gl::AttributesMask mDirtyDefaultAttribsMask;
1278 
1279     // DynamicBuffers for streaming vertex data from client memory pointer as well as for default
1280     // attributes. mHasInFlightStreamedVertexBuffers indicates if the dynamic buffer has any
1281     // inflight buffer or not that we need to release at submission time.
1282     gl::AttribArray<vk::DynamicBuffer> mStreamedVertexBuffers;
1283     gl::AttributesMask mHasInFlightStreamedVertexBuffers;
1284 
1285     // We use a single pool for recording commands. We also keep a free list for pool recycling.
1286     vk::SecondaryCommandPools mCommandPools;
1287 
1288     vk::GarbageList mCurrentGarbage;
1289 
1290     RenderPassCache mRenderPassCache;
1291 
1292     vk::OutsideRenderPassCommandBufferHelper *mOutsideRenderPassCommands;
1293     vk::RenderPassCommandBufferHelper *mRenderPassCommands;
1294 
1295     // The following is used when creating debug-util markers for graphics debuggers (e.g. AGI).  A
1296     // given gl{Begin|End}Query command may result in commands being submitted to the outside or
1297     // render-pass command buffer.  The ContextVk::handleGraphicsEventLog() method records the
1298     // appropriate command buffer for use by ContextVk::endEventLogForQuery().  The knowledge of
1299     // which command buffer to use depends on the particular type of query (e.g. samples
1300     // vs. timestamp), and is only known by the query code, which is what calls
1301     // ContextVk::handleGraphicsEventLog().  After all back-end processing of the gl*Query command
1302     // is complete, the front-end calls ContextVk::endEventLogForQuery(), which needs to know which
1303     // command buffer to call endDebugUtilsLabelEXT() for.
1304     GraphicsEventCmdBuf mQueryEventType;
1305 
1306     // Transform feedback buffers.
1307     angle::FlatUnorderedSet<const vk::BufferHelper *,
1308                             gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS>
1309         mCurrentTransformFeedbackBuffers;
1310 
1311     // Internal shader library.
1312     vk::ShaderLibrary mShaderLibrary;
1313     UtilsVk mUtils;
1314 
1315     bool mGpuEventsEnabled;
1316     vk::DynamicQueryPool mGpuEventQueryPool;
1317     // A list of queries that have yet to be turned into an event (their result is not yet
1318     // available).
1319     std::vector<GpuEventQuery> mInFlightGpuEventQueries;
1320     // A list of gpu events since the last clock sync.
1321     std::vector<GpuEvent> mGpuEvents;
1322 
1323     // Cached value of the color attachment mask of the current draw framebuffer.  This is used to
1324     // know which attachment indices have their blend state set in |mGraphicsPipelineDesc|, and
1325     // subsequently is used to clear the blend state for attachments that no longer exist when a new
1326     // framebuffer is bound.
1327     gl::DrawBufferMask mCachedDrawFramebufferColorAttachmentMask;
1328 
1329     bool mHasDeferredFlush;
1330 
1331     // The size of copy commands issued between buffers and images. Used to submit the command
1332     // buffer for the outside render pass.
1333     VkDeviceSize mTotalBufferToImageCopySize = 0;
1334 
1335     // Semaphores that must be waited on in the next submission.
1336     std::vector<VkSemaphore> mWaitSemaphores;
1337     std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks;
1338 
1339     // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
1340     GpuClockSyncInfo mGpuClockSync;
1341 
1342     // The very first timestamp queried for a GPU event is used as origin, so event timestamps would
1343     // have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to
1344     // double.
1345     uint64_t mGpuEventTimestampOrigin;
1346 
1347     // A mix of per-frame and per-run counters.
1348     angle::PerfMonitorCounterGroups mPerfMonitorCounters;
1349 
1350     gl::State::DirtyBits mPipelineDirtyBitsMask;
1351 
1352     // List of all resources currently being used by this ContextVk's recorded commands.
1353     vk::ResourceUseList mResourceUseList;
1354 
1355     egl::ContextPriority mContextPriority;
1356 
1357     // Storage for vkUpdateDescriptorSets
1358     UpdateDescriptorSetsBuilder mUpdateDescriptorSetsBuilder;
1359 
1360     ShareGroupVk *mShareGroupVk;
1361 
1362     // This is a special "empty" placeholder buffer for use when we just need a placeholder buffer
1363     // but not the data. Examples are shader that has no uniform or doesn't use all slots in the
1364     // atomic counter buffer array, or places where there is no vertex buffer since Vulkan does not
1365     // allow binding a null vertex buffer.
1366     vk::BufferHelper mEmptyBuffer;
1367 
1368     // Storage for default uniforms of ProgramVks and ProgramPipelineVks.
1369     vk::DynamicBuffer mDefaultUniformStorage;
1370 
1371     std::vector<std::string> mCommandBufferDiagnostics;
1372 
1373     // Record GL API calls for debuggers
1374     std::vector<std::string> mEventLog;
1375 
1376     // Viewport and scissor are handled as dynamic state.
1377     VkViewport mViewport;
1378     VkRect2D mScissor;
1379 };
1380 
endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper * buffer)1381 ANGLE_INLINE angle::Result ContextVk::endRenderPassIfTransformFeedbackBuffer(
1382     const vk::BufferHelper *buffer)
1383 {
1384     if (!buffer || !mCurrentTransformFeedbackBuffers.contains(buffer))
1385     {
1386         return angle::Result::Continue;
1387     }
1388 
1389     return flushCommandsAndEndRenderPass(RenderPassClosureReason::XfbWriteThenVertexIndexBuffer);
1390 }
1391 
onIndexBufferChange(const vk::BufferHelper * currentIndexBuffer)1392 ANGLE_INLINE angle::Result ContextVk::onIndexBufferChange(
1393     const vk::BufferHelper *currentIndexBuffer)
1394 {
1395     mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
1396     mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer);
1397     return endRenderPassIfTransformFeedbackBuffer(currentIndexBuffer);
1398 }
1399 
onVertexBufferChange(const vk::BufferHelper * vertexBuffer)1400 ANGLE_INLINE angle::Result ContextVk::onVertexBufferChange(const vk::BufferHelper *vertexBuffer)
1401 {
1402     mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
1403     return endRenderPassIfTransformFeedbackBuffer(vertexBuffer);
1404 }
1405 
onVertexAttributeChange(size_t attribIndex,GLuint stride,GLuint divisor,angle::FormatID format,bool compressed,GLuint relativeOffset,const vk::BufferHelper * vertexBuffer)1406 ANGLE_INLINE angle::Result ContextVk::onVertexAttributeChange(size_t attribIndex,
1407                                                               GLuint stride,
1408                                                               GLuint divisor,
1409                                                               angle::FormatID format,
1410                                                               bool compressed,
1411                                                               GLuint relativeOffset,
1412                                                               const vk::BufferHelper *vertexBuffer)
1413 {
1414     invalidateCurrentGraphicsPipeline();
1415     // Set divisor to 1 for attribs with emulated divisor
1416     mGraphicsPipelineDesc->updateVertexInput(
1417         &mGraphicsPipelineTransition, static_cast<uint32_t>(attribIndex), stride,
1418         divisor > mRenderer->getMaxVertexAttribDivisor() ? 1 : divisor, format, compressed,
1419         relativeOffset);
1420     return onVertexBufferChange(vertexBuffer);
1421 }
1422 
UseLineRaster(const ContextVk * contextVk,gl::PrimitiveMode mode)1423 ANGLE_INLINE bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
1424 {
1425     return contextVk->getFeatures().basicGLLineRasterization.enabled && gl::IsLineMode(mode);
1426 }
1427 }  // namespace rx
1428 
1429 // Generate a perf warning, and insert an event marker in the command buffer.
1430 #define ANGLE_VK_PERF_WARNING(contextVk, severity, ...)                         \
1431     do                                                                          \
1432     {                                                                           \
1433         char ANGLE_MESSAGE[100];                                                \
1434         snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__);            \
1435         ANGLE_PERF_WARNING(contextVk->getDebug(), severity, ANGLE_MESSAGE);     \
1436                                                                                 \
1437         contextVk->insertEventMarkerImpl(GL_DEBUG_SOURCE_OTHER, ANGLE_MESSAGE); \
1438     } while (0)
1439 
1440 // Generate a trace event for graphics profiler, and insert an event marker in the command buffer.
1441 #define ANGLE_VK_TRACE_EVENT_AND_MARKER(contextVk, ...)                         \
1442     do                                                                          \
1443     {                                                                           \
1444         char ANGLE_MESSAGE[100];                                                \
1445         snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__);            \
1446         ANGLE_TRACE_EVENT0("gpu.angle", ANGLE_MESSAGE);                         \
1447                                                                                 \
1448         contextVk->insertEventMarkerImpl(GL_DEBUG_SOURCE_OTHER, ANGLE_MESSAGE); \
1449     } while (0)
1450 
1451 #endif  // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
1452