• 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 <vulkan/vulkan.h>
14 
15 #include "common/PackedEnums.h"
16 #include "libANGLE/renderer/ContextImpl.h"
17 #include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
18 #include "libANGLE/renderer/vulkan/RendererVk.h"
19 #include "libANGLE/renderer/vulkan/vk_helpers.h"
20 
21 namespace angle
22 {
23 struct FeaturesVk;
24 }
25 
26 namespace rx
27 {
28 class RendererVk;
29 class WindowSurfaceVk;
30 
31 class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassOwner
32 {
33   public:
34     ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk *renderer);
35     ~ContextVk() override;
36 
37     angle::Result initialize() override;
38 
39     void onDestroy(const gl::Context *context) override;
40 
41     // Flush and finish.
42     angle::Result flush(const gl::Context *context) override;
43     angle::Result finish(const gl::Context *context) override;
44 
45     // Drawing methods.
46     angle::Result drawArrays(const gl::Context *context,
47                              gl::PrimitiveMode mode,
48                              GLint first,
49                              GLsizei count) override;
50     angle::Result drawArraysInstanced(const gl::Context *context,
51                                       gl::PrimitiveMode mode,
52                                       GLint first,
53                                       GLsizei count,
54                                       GLsizei instanceCount) override;
55     angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
56                                                   gl::PrimitiveMode mode,
57                                                   GLint first,
58                                                   GLsizei count,
59                                                   GLsizei instanceCount,
60                                                   GLuint baseInstance) override;
61 
62     angle::Result drawElements(const gl::Context *context,
63                                gl::PrimitiveMode mode,
64                                GLsizei count,
65                                gl::DrawElementsType type,
66                                const void *indices) override;
67     angle::Result drawElementsInstanced(const gl::Context *context,
68                                         gl::PrimitiveMode mode,
69                                         GLsizei count,
70                                         gl::DrawElementsType type,
71                                         const void *indices,
72                                         GLsizei instanceCount) override;
73     angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
74                                                               gl::PrimitiveMode mode,
75                                                               GLsizei count,
76                                                               gl::DrawElementsType type,
77                                                               const void *indices,
78                                                               GLsizei instances,
79                                                               GLint baseVertex,
80                                                               GLuint baseInstance) override;
81     angle::Result drawRangeElements(const gl::Context *context,
82                                     gl::PrimitiveMode mode,
83                                     GLuint start,
84                                     GLuint end,
85                                     GLsizei count,
86                                     gl::DrawElementsType type,
87                                     const void *indices) override;
88     angle::Result drawArraysIndirect(const gl::Context *context,
89                                      gl::PrimitiveMode mode,
90                                      const void *indirect) override;
91     angle::Result drawElementsIndirect(const gl::Context *context,
92                                        gl::PrimitiveMode mode,
93                                        gl::DrawElementsType type,
94                                        const void *indirect) override;
95 
96     // Device loss
97     gl::GraphicsResetStatus getResetStatus() override;
98 
99     // Vendor and description strings.
100     std::string getVendorString() const override;
101     std::string getRendererDescription() const override;
102 
103     // EXT_debug_marker
104     void insertEventMarker(GLsizei length, const char *marker) override;
105     void pushGroupMarker(GLsizei length, const char *marker) override;
106     void popGroupMarker() override;
107 
108     // KHR_debug
109     void pushDebugGroup(GLenum source, GLuint id, const std::string &message) override;
110     void popDebugGroup() override;
111 
112     bool isViewportFlipEnabledForDrawFBO() const;
113     bool isViewportFlipEnabledForReadFBO() const;
114 
115     // State sync with dirty bits.
116     angle::Result syncState(const gl::Context *context,
117                             const gl::State::DirtyBits &dirtyBits,
118                             const gl::State::DirtyBits &bitMask) override;
119 
120     // Disjoint timer queries
121     GLint getGPUDisjoint() override;
122     GLint64 getTimestamp() override;
123 
124     // Context switching
125     angle::Result onMakeCurrent(const gl::Context *context) override;
126     angle::Result onUnMakeCurrent(const gl::Context *context) override;
127 
128     // Native capabilities, unmodified by gl::Context.
129     gl::Caps getNativeCaps() const override;
130     const gl::TextureCapsMap &getNativeTextureCaps() const override;
131     const gl::Extensions &getNativeExtensions() const override;
132     const gl::Limitations &getNativeLimitations() const override;
133 
134     // Shader creation
135     CompilerImpl *createCompiler() override;
136     ShaderImpl *createShader(const gl::ShaderState &state) override;
137     ProgramImpl *createProgram(const gl::ProgramState &state) override;
138 
139     // Framebuffer creation
140     FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override;
141 
142     // Texture creation
143     TextureImpl *createTexture(const gl::TextureState &state) override;
144 
145     // Renderbuffer creation
146     RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override;
147 
148     // Buffer creation
149     BufferImpl *createBuffer(const gl::BufferState &state) override;
150 
151     // Vertex Array creation
152     VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override;
153 
154     // Query and Fence creation
155     QueryImpl *createQuery(gl::QueryType type) override;
156     FenceNVImpl *createFenceNV() override;
157     SyncImpl *createSync() override;
158 
159     // Transform Feedback creation
160     TransformFeedbackImpl *createTransformFeedback(
161         const gl::TransformFeedbackState &state) override;
162 
163     // Sampler object creation
164     SamplerImpl *createSampler(const gl::SamplerState &state) override;
165 
166     // Program Pipeline object creation
167     ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
168 
169     // Path object creation
170     std::vector<PathImpl *> createPaths(GLsizei) override;
171 
172     // Memory object creation.
173     MemoryObjectImpl *createMemoryObject() override;
174 
175     // Semaphore creation.
176     SemaphoreImpl *createSemaphore() override;
177 
178     angle::Result dispatchCompute(const gl::Context *context,
179                                   GLuint numGroupsX,
180                                   GLuint numGroupsY,
181                                   GLuint numGroupsZ) override;
182     angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;
183 
184     angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
185     angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
186 
187     VkDevice getDevice() const;
188 
getFeatures()189     ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); }
190 
invalidateVertexAndIndexBuffers()191     ANGLE_INLINE void invalidateVertexAndIndexBuffers()
192     {
193         // TODO: Make the pipeline invalidate more fine-grained. Only need to dirty here if PSO
194         //  VtxInput state (stride, fmt, inputRate...) has changed. http://anglebug.com/3256
195         invalidateCurrentGraphicsPipeline();
196         mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
197         mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
198     }
199 
invalidateVertexBuffers()200     ANGLE_INLINE void invalidateVertexBuffers()
201     {
202         mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
203     }
204 
onVertexAttributeChange(size_t attribIndex,GLuint stride,GLuint divisor,angle::FormatID format,GLuint relativeOffset)205     ANGLE_INLINE void onVertexAttributeChange(size_t attribIndex,
206                                               GLuint stride,
207                                               GLuint divisor,
208                                               angle::FormatID format,
209                                               GLuint relativeOffset)
210     {
211         invalidateVertexAndIndexBuffers();
212         mGraphicsPipelineDesc->updateVertexInput(&mGraphicsPipelineTransition,
213                                                  static_cast<uint32_t>(attribIndex), stride,
214                                                  divisor, format, relativeOffset);
215     }
216 
217     void invalidateDefaultAttribute(size_t attribIndex);
218     void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
219     void onDrawFramebufferChange(FramebufferVk *framebufferVk);
onHostVisibleBufferWrite()220     void onHostVisibleBufferWrite() { mIsAnyHostVisibleBufferWritten = true; }
221 
222     void invalidateCurrentTransformFeedbackBuffers();
223     void onTransformFeedbackPauseResume();
224 
225     vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);
226 
227     const VkClearValue &getClearColorValue() const;
228     const VkClearValue &getClearDepthStencilValue() const;
229     VkColorComponentFlags getClearColorMask() const;
230     angle::Result getIncompleteTexture(const gl::Context *context,
231                                        gl::TextureType type,
232                                        gl::Texture **textureOut);
233     void updateColorMask(const gl::BlendState &blendState);
234     void updateSampleMask(const gl::State &glState);
235 
236     void handleError(VkResult errorCode,
237                      const char *file,
238                      const char *function,
239                      unsigned int line) override;
240     const gl::ActiveTextureArray<vk::TextureUnit> &getActiveTextures() const;
241 
setIndexBufferDirty()242     void setIndexBufferDirty()
243     {
244         mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
245         mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer);
246     }
247 
248     void insertWaitSemaphore(const vk::Semaphore *waitSemaphore);
249 
250     angle::Result flushImpl(const vk::Semaphore *semaphore);
251     angle::Result finishImpl();
252 
253     void addWaitSemaphore(VkSemaphore semaphore);
254 
255     const vk::CommandPool &getCommandPool() const;
256 
getCurrentQueueSerial()257     Serial getCurrentQueueSerial() const { return mCurrentQueueSerial; }
getLastSubmittedQueueSerial()258     Serial getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; }
getLastCompletedQueueSerial()259     Serial getLastCompletedQueueSerial() const { return mLastCompletedQueueSerial; }
260 
261     bool isSerialInUse(Serial serial) const;
262 
263     template <typename T>
releaseObject(Serial resourceSerial,T * object)264     void releaseObject(Serial resourceSerial, T *object)
265     {
266         if (!isSerialInUse(resourceSerial))
267         {
268             object->destroy(getDevice());
269         }
270         else
271         {
272             object->dumpResources(resourceSerial, &mGarbage);
273         }
274     }
275 
276     // Check to see which batches have finished completion (forward progress for
277     // mLastCompletedQueueSerial, for example for when the application busy waits on a query
278     // result).
279     angle::Result checkCompletedCommands();
280 
281     // Wait for completion of batches until (at least) batch with given serial is finished.
282     angle::Result finishToSerial(Serial serial);
283     // A variant of finishToSerial that can time out.  Timeout status returned in outTimedOut.
284     angle::Result finishToSerialOrTimeout(Serial serial, uint64_t timeout, bool *outTimedOut);
285 
286     angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc,
287                                           vk::RenderPass **renderPassOut);
288     angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc,
289                                        const vk::AttachmentOpsArray &ops,
290                                        vk::RenderPass **renderPassOut);
291 
292     // Get (or allocate) the fence that will be signaled on next submission.
293     angle::Result getNextSubmitFence(vk::Shared<vk::Fence> *sharedFenceOut);
294     vk::Shared<vk::Fence> getLastSubmittedFence() const;
295 
296     // This should only be called from ResourceVk.
297     vk::CommandGraph *getCommandGraph();
298 
getShaderLibrary()299     vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; }
getUtils()300     UtilsVk &getUtils() { return mUtils; }
301 
302     angle::Result getTimestamp(uint64_t *timestampOut);
303 
304     // Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries.
305     // The events are queued until the query results are available.  Possible values for `phase`
306     // are TRACE_EVENT_PHASE_*
traceGpuEvent(vk::PrimaryCommandBuffer * commandBuffer,char phase,const char * name)307     ANGLE_INLINE angle::Result traceGpuEvent(vk::PrimaryCommandBuffer *commandBuffer,
308                                              char phase,
309                                              const char *name)
310     {
311         if (mGpuEventsEnabled)
312             return traceGpuEventImpl(commandBuffer, phase, name);
313         return angle::Result::Continue;
314     }
315 
getRenderPassCache()316     RenderPassCache &getRenderPassCache() { return mRenderPassCache; }
317 
318     vk::DescriptorSetLayoutDesc getDriverUniformsDescriptorSetDesc(
319         VkShaderStageFlags shaderStages) const;
320 
321     // We use texture serials to optimize texture binding updates. Each permutation of a
322     // {VkImage/VkSampler} generates a unique serial. These serials are combined to form a unique
323     // signature for each descriptor set. This allows us to keep a cache of descriptor sets and
324     // avoid calling vkAllocateDesctiporSets each texture update.
generateTextureSerial()325     Serial generateTextureSerial() { return mTextureSerialFactory.generate(); }
getActiveTexturesDesc()326     const vk::TextureDescriptorDesc &getActiveTexturesDesc() const { return mActiveTexturesDesc; }
327 
328     void updateScissor(const gl::State &glState);
329 
emulateSeamfulCubeMapSampling(bool * useSubgroupOpsOut)330     bool emulateSeamfulCubeMapSampling(bool *useSubgroupOpsOut) const
331     {
332         *useSubgroupOpsOut = mEmulateSeamfulCubeMapSamplingWithSubgroupOps;
333         return mEmulateSeamfulCubeMapSampling;
334     }
335 
336   private:
337     // Dirty bits.
338     enum DirtyBitType : size_t
339     {
340         DIRTY_BIT_DEFAULT_ATTRIBS,
341         DIRTY_BIT_PIPELINE,
342         DIRTY_BIT_TEXTURES,
343         DIRTY_BIT_VERTEX_BUFFERS,
344         DIRTY_BIT_INDEX_BUFFER,
345         DIRTY_BIT_DRIVER_UNIFORMS,
346         DIRTY_BIT_SHADER_RESOURCES,  // excluding textures, which are handled separately.
347         DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
348         DIRTY_BIT_DESCRIPTOR_SETS,
349         DIRTY_BIT_MAX,
350     };
351 
352     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
353 
354     using DirtyBitHandler = angle::Result (ContextVk::*)(const gl::Context *,
355                                                          vk::CommandBuffer *commandBuffer);
356 
357     std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
358     std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;
359 
360     enum class PipelineType
361     {
362         Graphics = 0,
363         Compute  = 1,
364 
365         InvalidEnum = 2,
366         EnumCount   = 2,
367     };
368 
369     angle::Result setupDraw(const gl::Context *context,
370                             gl::PrimitiveMode mode,
371                             GLint firstVertex,
372                             GLsizei vertexOrIndexCount,
373                             GLsizei instanceCount,
374                             gl::DrawElementsType indexTypeOrInvalid,
375                             const void *indices,
376                             DirtyBits dirtyBitMask,
377                             vk::CommandBuffer **commandBufferOut);
378     angle::Result setupIndexedDraw(const gl::Context *context,
379                                    gl::PrimitiveMode mode,
380                                    GLsizei indexCount,
381                                    GLsizei instanceCount,
382                                    gl::DrawElementsType indexType,
383                                    const void *indices,
384                                    vk::CommandBuffer **commandBufferOut);
385     angle::Result setupLineLoopDraw(const gl::Context *context,
386                                     gl::PrimitiveMode mode,
387                                     GLint firstVertex,
388                                     GLsizei vertexOrIndexCount,
389                                     gl::DrawElementsType indexTypeOrInvalid,
390                                     const void *indices,
391                                     vk::CommandBuffer **commandBufferOut,
392                                     uint32_t *numIndicesOut);
393     angle::Result setupDispatch(const gl::Context *context, vk::CommandBuffer **commandBufferOut);
394 
395     void updateViewport(FramebufferVk *framebufferVk,
396                         const gl::Rectangle &viewport,
397                         float nearPlane,
398                         float farPlane,
399                         bool invertViewport);
400     void updateDepthRange(float nearPlane, float farPlane);
401     void updateFlipViewportDrawFramebuffer(const gl::State &glState);
402     void updateFlipViewportReadFramebuffer(const gl::State &glState);
403 
404     angle::Result updateActiveTextures(const gl::Context *context,
405                                        vk::CommandGraphResource *recorder);
406     angle::Result updateDefaultAttribute(size_t attribIndex);
407 
invalidateCurrentGraphicsPipeline()408     ANGLE_INLINE void invalidateCurrentGraphicsPipeline()
409     {
410         mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE);
411     }
invalidateCurrentComputePipeline()412     ANGLE_INLINE void invalidateCurrentComputePipeline()
413     {
414         mComputeDirtyBits.set(DIRTY_BIT_PIPELINE);
415         mCurrentComputePipeline = nullptr;
416     }
417 
418     void invalidateCurrentTextures();
419     void invalidateCurrentShaderResources();
420     void invalidateGraphicsDriverUniforms();
421     void invalidateDriverUniforms();
422 
423     // Handlers for graphics pipeline dirty bits.
424     angle::Result handleDirtyGraphicsDefaultAttribs(const gl::Context *context,
425                                                     vk::CommandBuffer *commandBuffer);
426     angle::Result handleDirtyGraphicsPipeline(const gl::Context *context,
427                                               vk::CommandBuffer *commandBuffer);
428     angle::Result handleDirtyGraphicsTextures(const gl::Context *context,
429                                               vk::CommandBuffer *commandBuffer);
430     angle::Result handleDirtyGraphicsVertexBuffers(const gl::Context *context,
431                                                    vk::CommandBuffer *commandBuffer);
432     angle::Result handleDirtyGraphicsIndexBuffer(const gl::Context *context,
433                                                  vk::CommandBuffer *commandBuffer);
434     angle::Result handleDirtyGraphicsDriverUniforms(const gl::Context *context,
435                                                     vk::CommandBuffer *commandBuffer);
436     angle::Result handleDirtyGraphicsShaderResources(const gl::Context *context,
437                                                      vk::CommandBuffer *commandBuffer);
438     angle::Result handleDirtyGraphicsTransformFeedbackBuffers(const gl::Context *context,
439                                                               vk::CommandBuffer *commandBuffer);
440     angle::Result handleDirtyGraphicsDescriptorSets(const gl::Context *context,
441                                                     vk::CommandBuffer *commandBuffer);
442 
443     // Handlers for compute pipeline dirty bits.
444     angle::Result handleDirtyComputePipeline(const gl::Context *context,
445                                              vk::CommandBuffer *commandBuffer);
446     angle::Result handleDirtyComputeTextures(const gl::Context *context,
447                                              vk::CommandBuffer *commandBuffer);
448     angle::Result handleDirtyComputeDriverUniforms(const gl::Context *context,
449                                                    vk::CommandBuffer *commandBuffer);
450     angle::Result handleDirtyComputeShaderResources(const gl::Context *context,
451                                                     vk::CommandBuffer *commandBuffer);
452     angle::Result handleDirtyComputeDescriptorSets(const gl::Context *context,
453                                                    vk::CommandBuffer *commandBuffer);
454 
455     // Common parts of the common dirty bit handlers.
456     angle::Result handleDirtyTexturesImpl(const gl::Context *context,
457                                           vk::CommandBuffer *commandBuffer,
458                                           vk::CommandGraphResource *recorder);
459     angle::Result handleDirtyShaderResourcesImpl(const gl::Context *context,
460                                                  vk::CommandBuffer *commandBuffer,
461                                                  vk::CommandGraphResource *recorder);
462     struct DriverUniformsDescriptorSet;
463     angle::Result handleDirtyDescriptorSetsImpl(vk::CommandBuffer *commandBuffer,
464                                                 VkPipelineBindPoint bindPoint,
465                                                 const DriverUniformsDescriptorSet &driverUniforms);
466     angle::Result allocateDriverUniforms(size_t driverUniformsSize,
467                                          DriverUniformsDescriptorSet *driverUniforms,
468                                          VkBuffer *bufferOut,
469                                          uint8_t **ptrOut,
470                                          bool *newBufferOut);
471     angle::Result updateDriverUniformsDescriptorSet(VkBuffer buffer,
472                                                     bool newBuffer,
473                                                     size_t driverUniformsSize,
474                                                     DriverUniformsDescriptorSet *driverUniforms);
475 
476     void writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOut, size_t offsetsSize);
477 
478     angle::Result submitFrame(const VkSubmitInfo &submitInfo,
479                               vk::PrimaryCommandBuffer &&commandBuffer);
480     angle::Result flushCommandGraph(vk::PrimaryCommandBuffer *commandBatch);
481 
482     angle::Result synchronizeCpuGpuTime();
483     angle::Result traceGpuEventImpl(vk::PrimaryCommandBuffer *commandBuffer,
484                                     char phase,
485                                     const char *name);
486     angle::Result checkCompletedGpuEvents();
487     void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS);
488 
489     void handleDeviceLost();
490 
491     void waitForSwapchainImageIfNecessary();
492 
493     bool shouldEmulateSeamfulCubeMapSampling(bool *useSubgroupOpsOut) const;
494 
495     vk::PipelineHelper *mCurrentGraphicsPipeline;
496     vk::PipelineAndSerial *mCurrentComputePipeline;
497     gl::PrimitiveMode mCurrentDrawMode;
498 
499     WindowSurfaceVk *mCurrentWindowSurface;
500 
501     // Keep a cached pipeline description structure that can be used to query the pipeline cache.
502     // Kept in a pointer so allocations can be aligned, and structs can be portably packed.
503     std::unique_ptr<vk::GraphicsPipelineDesc> mGraphicsPipelineDesc;
504     vk::GraphicsPipelineTransitionBits mGraphicsPipelineTransition;
505 
506     // These pools are externally sychronized, so cannot be accessed from different
507     // threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk.
508     // Note that this implementation would need to change in shared resource scenarios. Likely
509     // we'd instead share a single set of pools between the share groups.
510     vk::DynamicDescriptorPool mDriverUniformsDescriptorPool;
511     angle::PackedEnumMap<gl::QueryType, vk::DynamicQueryPool> mQueryPools;
512 
513     // Dirty bits.
514     DirtyBits mGraphicsDirtyBits;
515     DirtyBits mComputeDirtyBits;
516     DirtyBits mNonIndexedDirtyBitsMask;
517     DirtyBits mIndexedDirtyBitsMask;
518     DirtyBits mNewGraphicsCommandBufferDirtyBits;
519     DirtyBits mNewComputeCommandBufferDirtyBits;
520 
521     // Cached back-end objects.
522     VertexArrayVk *mVertexArray;
523     FramebufferVk *mDrawFramebuffer;
524     ProgramVk *mProgram;
525 
526     // Graph resource used to record dispatch commands and hold resource dependencies.
527     vk::DispatchHelper mDispatcher;
528 
529     // The offset we had the last time we bound the index buffer.
530     const GLvoid *mLastIndexBufferOffset;
531     gl::DrawElementsType mCurrentDrawElementsType;
532 
533     // Cache the current draw call's firstVertex to be passed to
534     // TransformFeedbackVk::getBufferOffsets.  Unfortunately, gl_BaseVertex support in Vulkan is
535     // not yet ubiquitous, which would have otherwise removed the need for this value to be passed
536     // as a uniform.
537     GLint mXfbBaseVertex;
538 
539     // Cached clear value/mask for color and depth/stencil.
540     VkClearValue mClearColorValue;
541     VkClearValue mClearDepthStencilValue;
542     VkColorComponentFlags mClearColorMask;
543 
544     IncompleteTextureSet mIncompleteTextures;
545 
546     // If the current surface bound to this context wants to have all rendering flipped vertically.
547     // Updated on calls to onMakeCurrent.
548     bool mFlipYForCurrentSurface;
549     bool mFlipViewportForDrawFramebuffer;
550     bool mFlipViewportForReadFramebuffer;
551 
552     // If any host-visible buffer is written by the GPU since last submission, a barrier is inserted
553     // at the end of the command buffer to make that write available to the host.
554     bool mIsAnyHostVisibleBufferWritten;
555 
556     // Whether this context should do seamful cube map sampling emulation, and whether subgroup
557     // operations should be used.
558     bool mEmulateSeamfulCubeMapSampling;
559     bool mEmulateSeamfulCubeMapSamplingWithSubgroupOps;
560 
561     struct DriverUniformsDescriptorSet
562     {
563         vk::DynamicBuffer dynamicBuffer;
564         VkDescriptorSet descriptorSet;
565         uint32_t dynamicOffset;
566         vk::BindingPointer<vk::DescriptorSetLayout> descriptorSetLayout;
567         vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
568 
569         DriverUniformsDescriptorSet();
570         ~DriverUniformsDescriptorSet();
571 
572         void init(RendererVk *rendererVk);
573         void destroy(VkDevice device);
574     };
575 
576     angle::PackedEnumMap<PipelineType, DriverUniformsDescriptorSet> mDriverUniforms;
577 
578     // This cache should also probably include the texture index (shader location) and array
579     // index (also in the shader). This info is used in the descriptor update step.
580     gl::ActiveTextureArray<vk::TextureUnit> mActiveTextures;
581     vk::TextureDescriptorDesc mActiveTexturesDesc;
582 
583     // "Current Value" aka default vertex attribute state.
584     gl::AttributesMask mDirtyDefaultAttribsMask;
585     gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;
586 
587     // We use a single pool for recording commands. We also keep a free list for pool recycling.
588     vk::CommandPool mCommandPool;
589     std::vector<vk::CommandPool> mCommandPoolFreeList;
590 
591     // We use a Persistent CommandPool with pre-allocated buffers for primary CommandBuffer
592     vk::PersistentCommandPool mPrimaryCommandPool;
593 
594     Serial mLastCompletedQueueSerial;
595     Serial mLastSubmittedQueueSerial;
596     Serial mCurrentQueueSerial;
597 
598     struct CommandBatch final : angle::NonCopyable
599     {
600         CommandBatch();
601         ~CommandBatch();
602         CommandBatch(CommandBatch &&other);
603         CommandBatch &operator=(CommandBatch &&other);
604 
605         void destroy(VkDevice device);
606 
607         vk::PrimaryCommandBuffer primaryCommands;
608         // commandPool is for secondary CommandBuffer allocation
609         vk::CommandPool commandPool;
610         vk::Shared<vk::Fence> fence;
611         Serial serial;
612     };
613 
614     angle::Result releaseToCommandBatch(vk::PrimaryCommandBuffer &&commandBuffer,
615                                         CommandBatch *batch);
616     angle::Result recycleCommandBatch(CommandBatch *batch);
617 
618     std::vector<CommandBatch> mInFlightCommands;
619     std::vector<vk::GarbageObject> mGarbage;
620 
621     RenderPassCache mRenderPassCache;
622 
623     // mSubmitFence is the fence that's going to be signaled at the next submission.  This is used
624     // to support SyncVk objects, which may outlive the context (as EGLSync objects).
625     //
626     // TODO(geofflang): this is in preparation for moving RendererVk functionality to ContextVk, and
627     // is otherwise unnecessary as the SyncVk objects don't actually outlive the renderer currently.
628     // http://anglebug.com/2701
629     vk::Shared<vk::Fence> mSubmitFence;
630 
631     // Pool allocator used for command graph but may be expanded to other allocations
632     angle::PoolAllocator mPoolAllocator;
633 
634     // See CommandGraph.h for a desription of the Command Graph.
635     vk::CommandGraph mCommandGraph;
636 
637     // Internal shader library.
638     vk::ShaderLibrary mShaderLibrary;
639     UtilsVk mUtils;
640 
641     // The GpuEventQuery struct holds together a timestamp query and enough data to create a
642     // trace event based on that. Use traceGpuEvent to insert such queries.  They will be readback
643     // when the results are available, without inserting a GPU bubble.
644     //
645     // - eventName will be the reported name of the event
646     // - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event).
647     //   See Google's "Trace Event Format":
648     //   https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
649     // - serial is the serial of the batch the query was submitted on.  Until the batch is
650     //   submitted, the query is not checked to avoid incuring a flush.
651     struct GpuEventQuery final
652     {
653         const char *name;
654         char phase;
655 
656         uint32_t queryIndex;
657         size_t queryPoolIndex;
658 
659         Serial serial;
660     };
661 
662     // Once a query result is available, the timestamp is read and a GpuEvent object is kept until
663     // the next clock sync, at which point the clock drift is compensated in the results before
664     // handing them off to the application.
665     struct GpuEvent final
666     {
667         uint64_t gpuTimestampCycles;
668         const char *name;
669         char phase;
670     };
671 
672     bool mGpuEventsEnabled;
673     vk::DynamicQueryPool mGpuEventQueryPool;
674     // A list of queries that have yet to be turned into an event (their result is not yet
675     // available).
676     std::vector<GpuEventQuery> mInFlightGpuEventQueries;
677     // A list of gpu events since the last clock sync.
678     std::vector<GpuEvent> mGpuEvents;
679 
680     // Semaphores that must be waited on in the next submission.
681     std::vector<VkSemaphore> mWaitSemaphores;
682     std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks;
683 
684     // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
685     struct GpuClockSyncInfo
686     {
687         double gpuTimestampS;
688         double cpuTimestampS;
689     };
690     GpuClockSyncInfo mGpuClockSync;
691 
692     // The very first timestamp queried for a GPU event is used as origin, so event timestamps would
693     // have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to
694     // double.
695     uint64_t mGpuEventTimestampOrigin;
696 
697     // Generator for texure serials.
698     SerialFactory mTextureSerialFactory;
699 
700     gl::State::DirtyBits mPipelineDirtyBitsMask;
701 };
702 }  // namespace rx
703 
704 #endif  // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
705