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