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