//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ContextVk.h:
//    Defines the class interface for ContextVk, implementing ContextImpl.
//

#ifndef LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
#define LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_

#include <condition_variable>

#include "common/PackedEnums.h"
#include "common/vulkan/vk_headers.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/OverlayVk.h"
#include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/vk_helpers.h"

namespace angle
{
struct FeaturesVk;
}  // namespace angle

namespace rx
{
class ProgramExecutableVk;
class RendererVk;
class WindowSurfaceVk;
class ShareGroupVk;

static constexpr uint32_t kMaxGpuEventNameLen = 32;
using EventName                               = std::array<char, kMaxGpuEventNameLen>;

class ContextVk : public ContextImpl, public vk::Context
{
  public:
    ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk *renderer);
    ~ContextVk() override;

    angle::Result initialize() override;

    void onDestroy(const gl::Context *context) override;

    // Flush and finish.
    angle::Result flush(const gl::Context *context) override;
    angle::Result finish(const gl::Context *context) override;

    // Drawing methods.
    angle::Result drawArrays(const gl::Context *context,
                             gl::PrimitiveMode mode,
                             GLint first,
                             GLsizei count) override;
    angle::Result drawArraysInstanced(const gl::Context *context,
                                      gl::PrimitiveMode mode,
                                      GLint first,
                                      GLsizei count,
                                      GLsizei instanceCount) override;
    angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
                                                  gl::PrimitiveMode mode,
                                                  GLint first,
                                                  GLsizei count,
                                                  GLsizei instanceCount,
                                                  GLuint baseInstance) override;

    angle::Result drawElements(const gl::Context *context,
                               gl::PrimitiveMode mode,
                               GLsizei count,
                               gl::DrawElementsType type,
                               const void *indices) override;
    angle::Result drawElementsBaseVertex(const gl::Context *context,
                                         gl::PrimitiveMode mode,
                                         GLsizei count,
                                         gl::DrawElementsType type,
                                         const void *indices,
                                         GLint baseVertex) override;
    angle::Result drawElementsInstanced(const gl::Context *context,
                                        gl::PrimitiveMode mode,
                                        GLsizei count,
                                        gl::DrawElementsType type,
                                        const void *indices,
                                        GLsizei instanceCount) override;
    angle::Result drawElementsInstancedBaseVertex(const gl::Context *context,
                                                  gl::PrimitiveMode mode,
                                                  GLsizei count,
                                                  gl::DrawElementsType type,
                                                  const void *indices,
                                                  GLsizei instanceCount,
                                                  GLint baseVertex) override;
    angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
                                                              gl::PrimitiveMode mode,
                                                              GLsizei count,
                                                              gl::DrawElementsType type,
                                                              const void *indices,
                                                              GLsizei instances,
                                                              GLint baseVertex,
                                                              GLuint baseInstance) override;
    angle::Result drawRangeElements(const gl::Context *context,
                                    gl::PrimitiveMode mode,
                                    GLuint start,
                                    GLuint end,
                                    GLsizei count,
                                    gl::DrawElementsType type,
                                    const void *indices) override;
    angle::Result drawRangeElementsBaseVertex(const gl::Context *context,
                                              gl::PrimitiveMode mode,
                                              GLuint start,
                                              GLuint end,
                                              GLsizei count,
                                              gl::DrawElementsType type,
                                              const void *indices,
                                              GLint baseVertex) override;
    angle::Result drawArraysIndirect(const gl::Context *context,
                                     gl::PrimitiveMode mode,
                                     const void *indirect) override;
    angle::Result drawElementsIndirect(const gl::Context *context,
                                       gl::PrimitiveMode mode,
                                       gl::DrawElementsType type,
                                       const void *indirect) override;

    angle::Result multiDrawArrays(const gl::Context *context,
                                  gl::PrimitiveMode mode,
                                  const GLint *firsts,
                                  const GLsizei *counts,
                                  GLsizei drawcount) override;
    angle::Result multiDrawArraysInstanced(const gl::Context *context,
                                           gl::PrimitiveMode mode,
                                           const GLint *firsts,
                                           const GLsizei *counts,
                                           const GLsizei *instanceCounts,
                                           GLsizei drawcount) override;
    angle::Result multiDrawElements(const gl::Context *context,
                                    gl::PrimitiveMode mode,
                                    const GLsizei *counts,
                                    gl::DrawElementsType type,
                                    const GLvoid *const *indices,
                                    GLsizei drawcount) override;
    angle::Result multiDrawElementsInstanced(const gl::Context *context,
                                             gl::PrimitiveMode mode,
                                             const GLsizei *counts,
                                             gl::DrawElementsType type,
                                             const GLvoid *const *indices,
                                             const GLsizei *instanceCounts,
                                             GLsizei drawcount) override;
    angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
                                                       gl::PrimitiveMode mode,
                                                       const GLint *firsts,
                                                       const GLsizei *counts,
                                                       const GLsizei *instanceCounts,
                                                       const GLuint *baseInstances,
                                                       GLsizei drawcount) override;
    angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
                                                                   gl::PrimitiveMode mode,
                                                                   const GLsizei *counts,
                                                                   gl::DrawElementsType type,
                                                                   const GLvoid *const *indices,
                                                                   const GLsizei *instanceCounts,
                                                                   const GLint *baseVertices,
                                                                   const GLuint *baseInstances,
                                                                   GLsizei drawcount) override;

    // ShareGroup
    ShareGroupVk *getShareGroupVk() { return mShareGroupVk; }
    PipelineLayoutCache &getPipelineLayoutCache()
    {
        return mShareGroupVk->getPipelineLayoutCache();
    }
    DescriptorSetLayoutCache &getDescriptorSetLayoutCache()
    {
        return mShareGroupVk->getDescriptorSetLayoutCache();
    }

    // Device loss
    gl::GraphicsResetStatus getResetStatus() override;

    // Vendor and description strings.
    std::string getVendorString() const override;
    std::string getRendererDescription() const override;

    // EXT_debug_marker
    angle::Result insertEventMarker(GLsizei length, const char *marker) override;
    angle::Result pushGroupMarker(GLsizei length, const char *marker) override;
    angle::Result popGroupMarker() override;

    // KHR_debug
    angle::Result pushDebugGroup(const gl::Context *context,
                                 GLenum source,
                                 GLuint id,
                                 const std::string &message) override;
    angle::Result popDebugGroup(const gl::Context *context) override;

    // Record GL API calls for debuggers
    void logEvent(const char *eventString);
    void endEventLog(gl::EntryPoint entryPoint);

    bool isViewportFlipEnabledForDrawFBO() const;
    bool isViewportFlipEnabledForReadFBO() const;
    // When the device/surface is rotated such that the surface's aspect ratio is different than
    // the native device (e.g. 90 degrees), the width and height of the viewport, scissor, and
    // render area must be swapped.
    bool isRotatedAspectRatioForDrawFBO() const;
    bool isRotatedAspectRatioForReadFBO() const;
    SurfaceRotation getRotationDrawFramebuffer() const;
    SurfaceRotation getRotationReadFramebuffer() const;

    void invalidateProgramBindingHelper(const gl::State &glState);
    angle::Result invalidateProgramExecutableHelper(const gl::Context *context);

    // State sync with dirty bits.
    angle::Result syncState(const gl::Context *context,
                            const gl::State::DirtyBits &dirtyBits,
                            const gl::State::DirtyBits &bitMask) override;

    // Disjoint timer queries
    GLint getGPUDisjoint() override;
    GLint64 getTimestamp() override;

    // Context switching
    angle::Result onMakeCurrent(const gl::Context *context) override;
    angle::Result onUnMakeCurrent(const gl::Context *context) override;

    // Native capabilities, unmodified by gl::Context.
    gl::Caps getNativeCaps() const override;
    const gl::TextureCapsMap &getNativeTextureCaps() const override;
    const gl::Extensions &getNativeExtensions() const override;
    const gl::Limitations &getNativeLimitations() const override;

    // Shader creation
    CompilerImpl *createCompiler() override;
    ShaderImpl *createShader(const gl::ShaderState &state) override;
    ProgramImpl *createProgram(const gl::ProgramState &state) override;

    // Framebuffer creation
    FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override;

    // Texture creation
    TextureImpl *createTexture(const gl::TextureState &state) override;

    // Renderbuffer creation
    RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override;

    // Buffer creation
    BufferImpl *createBuffer(const gl::BufferState &state) override;

    // Vertex Array creation
    VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override;

    // Query and Fence creation
    QueryImpl *createQuery(gl::QueryType type) override;
    FenceNVImpl *createFenceNV() override;
    SyncImpl *createSync() override;

    // Transform Feedback creation
    TransformFeedbackImpl *createTransformFeedback(
        const gl::TransformFeedbackState &state) override;

    // Sampler object creation
    SamplerImpl *createSampler(const gl::SamplerState &state) override;

    // Program Pipeline object creation
    ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;

    // Memory object creation.
    MemoryObjectImpl *createMemoryObject() override;

    // Semaphore creation.
    SemaphoreImpl *createSemaphore() override;

    // Overlay creation.
    OverlayImpl *createOverlay(const gl::OverlayState &state) override;

    angle::Result dispatchCompute(const gl::Context *context,
                                  GLuint numGroupsX,
                                  GLuint numGroupsY,
                                  GLuint numGroupsZ) override;
    angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;

    angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
    angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;

    ANGLE_INLINE void invalidateTexture(gl::TextureType target) override {}

    VkDevice getDevice() const;
    egl::ContextPriority getPriority() const { return mContextPriority; }

    ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); }

    ANGLE_INLINE void invalidateVertexAndIndexBuffers()
    {
        invalidateCurrentGraphicsPipeline();
        mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
        mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
    }

    angle::Result onVertexBufferChange(const vk::BufferHelper *vertexBuffer);

    angle::Result onVertexAttributeChange(size_t attribIndex,
                                          GLuint stride,
                                          GLuint divisor,
                                          angle::FormatID format,
                                          bool compressed,
                                          GLuint relativeOffset,
                                          const vk::BufferHelper *vertexBuffer);

    void invalidateDefaultAttribute(size_t attribIndex);
    void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
    void onFramebufferChange(FramebufferVk *framebufferVk);
    void onDrawFramebufferRenderPassDescChange(FramebufferVk *framebufferVk);
    void onHostVisibleBufferWrite() { mIsAnyHostVisibleBufferWritten = true; }

    void invalidateCurrentTransformFeedbackBuffers();
    void onTransformFeedbackStateChanged();
    angle::Result onBeginTransformFeedback(
        size_t bufferCount,
        const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers);
    void onEndTransformFeedback();
    angle::Result onPauseTransformFeedback();

    // When UtilsVk issues draw or dispatch calls, it binds descriptor sets that the context is not
    // aware of.  This function is called to make sure affected descriptor set bindings are dirtied
    // for the next application draw/dispatch call.
    void invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet);
    void invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet);

    void optimizeRenderPassForPresent(VkFramebuffer framebufferHandle);

    vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);

    const VkClearValue &getClearColorValue() const;
    const VkClearValue &getClearDepthStencilValue() const;
    gl::BlendStateExt::ColorMaskStorage::Type getClearColorMasks() const;
    angle::Result getIncompleteTexture(const gl::Context *context,
                                       gl::TextureType type,
                                       gl::Texture **textureOut);
    void updateColorMasks(const gl::BlendStateExt &blendStateExt);
    void updateSampleMask(const gl::State &glState);

    void handleError(VkResult errorCode,
                     const char *file,
                     const char *function,
                     unsigned int line) override;
    const gl::ActiveTextureArray<vk::TextureUnit> &getActiveTextures() const
    {
        return mActiveTextures;
    }
    const gl::ActiveTextureArray<TextureVk *> &getActiveImages() const { return mActiveImages; }

    angle::Result onIndexBufferChange(const vk::BufferHelper *currentIndexBuffer);

    angle::Result flushImpl(const vk::Semaphore *semaphore);
    angle::Result finishImpl();

    void addWaitSemaphore(VkSemaphore semaphore, VkPipelineStageFlags stageMask);

    const vk::CommandPool &getCommandPool() const;

    Serial getCurrentQueueSerial() const { return mRenderer->getCurrentQueueSerial(); }
    Serial getLastSubmittedQueueSerial() const { return mRenderer->getLastSubmittedQueueSerial(); }
    Serial getLastCompletedQueueSerial() const { return mRenderer->getLastCompletedQueueSerial(); }

    bool isSerialInUse(Serial serial) const;

    template <typename T>
    void addGarbage(T *object)
    {
        if (object->valid())
        {
            mCurrentGarbage.emplace_back(vk::GetGarbage(object));
        }
    }

    // It would be nice if we didn't have to expose this for QueryVk::getResult.
    angle::Result checkCompletedCommands();

    // Wait for completion of batches until (at least) batch with given serial is finished.
    angle::Result finishToSerial(Serial serial);

    angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc,
                                          vk::RenderPass **renderPassOut);
    angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc,
                                       const vk::AttachmentOpsArray &ops,
                                       vk::RenderPass **renderPassOut);

    // Get (or allocate) the fence that will be signaled on next submission.
    angle::Result getNextSubmitFence(vk::Shared<vk::Fence> *sharedFenceOut);
    vk::Shared<vk::Fence> getLastSubmittedFence() const;

    vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; }
    UtilsVk &getUtils() { return mUtils; }

    angle::Result getTimestamp(uint64_t *timestampOut);

    // Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries.
    // The events are queued until the query results are available.  Possible values for `phase`
    // are TRACE_EVENT_PHASE_*
    ANGLE_INLINE angle::Result traceGpuEvent(vk::CommandBuffer *commandBuffer,
                                             char phase,
                                             const EventName &name)
    {
        if (mGpuEventsEnabled)
            return traceGpuEventImpl(commandBuffer, phase, name);
        return angle::Result::Continue;
    }

    RenderPassCache &getRenderPassCache() { return mRenderPassCache; }

    vk::DescriptorSetLayoutDesc getDriverUniformsDescriptorSetDesc(
        VkShaderStageFlags shaderStages) const;

    // We use textureSerial to optimize texture binding updates. Each permutation of a
    // {VkImage/VkSampler} generates a unique serial. These object ids are combined to form a unique
    // signature for each descriptor set. This allows us to keep a cache of descriptor sets and
    // avoid calling vkAllocateDesctiporSets each texture update.
    const vk::TextureDescriptorDesc &getActiveTexturesDesc() const { return mActiveTexturesDesc; }

    void updateScissor(const gl::State &glState);

    bool emulateSeamfulCubeMapSampling() const { return mEmulateSeamfulCubeMapSampling; }

    bool useOldRewriteStructSamplers() const { return mUseOldRewriteStructSamplers; }

    const gl::Debug &getDebug() const { return mState.getDebug(); }
    const gl::OverlayType *getOverlay() const { return mState.getOverlay(); }

    vk::ResourceUseList &getResourceUseList() { return mResourceUseList; }

    angle::Result onBufferTransferRead(vk::BufferHelper *buffer)
    {
        return onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, vk::PipelineStage::Transfer, buffer);
    }
    angle::Result onBufferTransferWrite(vk::BufferHelper *buffer)
    {
        return onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, vk::PipelineStage::Transfer, buffer);
    }
    angle::Result onBufferSelfCopy(vk::BufferHelper *buffer)
    {
        return onBufferWrite(VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
                             vk::PipelineStage::Transfer, buffer);
    }
    angle::Result onBufferComputeShaderRead(vk::BufferHelper *buffer)
    {
        return onBufferRead(VK_ACCESS_SHADER_READ_BIT, vk::PipelineStage::ComputeShader, buffer);
    }
    angle::Result onBufferComputeShaderWrite(vk::BufferHelper *buffer)
    {
        return onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, vk::PipelineStage::ComputeShader, buffer);
    }
    angle::Result onBufferReleaseToExternal(const vk::BufferHelper &buffer);

    angle::Result onImageTransferRead(VkImageAspectFlags aspectFlags, vk::ImageHelper *image)
    {
        return onImageRead(aspectFlags, vk::ImageLayout::TransferSrc, image);
    }
    angle::Result onImageTransferWrite(gl::LevelIndex levelStart,
                                       uint32_t levelCount,
                                       uint32_t layerStart,
                                       uint32_t layerCount,
                                       VkImageAspectFlags aspectFlags,
                                       vk::ImageHelper *image)
    {
        return onImageWrite(levelStart, levelCount, layerStart, layerCount, aspectFlags,
                            vk::ImageLayout::TransferDst, image);
    }
    angle::Result onImageComputeShaderRead(VkImageAspectFlags aspectFlags, vk::ImageHelper *image)
    {
        return onImageRead(aspectFlags, vk::ImageLayout::ComputeShaderReadOnly, image);
    }
    angle::Result onImageComputeShaderWrite(gl::LevelIndex levelStart,
                                            uint32_t levelCount,
                                            uint32_t layerStart,
                                            uint32_t layerCount,
                                            VkImageAspectFlags aspectFlags,
                                            vk::ImageHelper *image)
    {
        return onImageWrite(levelStart, levelCount, layerStart, layerCount, aspectFlags,
                            vk::ImageLayout::ComputeShaderWrite, image);
    }
    angle::Result onImageReleaseToExternal(const vk::ImageHelper &image);

    void onImageRenderPassRead(VkImageAspectFlags aspectFlags,
                               vk::ImageLayout imageLayout,
                               vk::ImageHelper *image)
    {
        ASSERT(mRenderPassCommands->started());
        mRenderPassCommands->imageRead(&mResourceUseList, aspectFlags, imageLayout, image);
    }

    void onImageRenderPassWrite(gl::LevelIndex level,
                                uint32_t layerStart,
                                uint32_t layerCount,
                                VkImageAspectFlags aspectFlags,
                                vk::ImageLayout imageLayout,
                                vk::ImageHelper *image)
    {
        ASSERT(mRenderPassCommands->started());
        mRenderPassCommands->imageWrite(&mResourceUseList, level, layerStart, layerCount,
                                        aspectFlags, imageLayout, vk::AliasingMode::Allowed, image);
    }

    void onDepthStencilDraw(gl::LevelIndex level,
                            uint32_t layer,
                            vk::ImageHelper *image,
                            vk::ImageHelper *resolveImage)
    {
        ASSERT(mRenderPassCommands->started());
        mRenderPassCommands->depthStencilImagesDraw(&mResourceUseList, level, layer, image,
                                                    resolveImage);
    }

    void onImageHelperRelease(const vk::ImageHelper *image)
    {
        if (mRenderPassCommands->started())
        {
            mRenderPassCommands->onImageHelperRelease(image);
        }
    }

    vk::CommandBuffer &getOutsideRenderPassCommandBuffer()
    {
        return mOutsideRenderPassCommands->getCommandBuffer();
    }

    angle::Result beginNewRenderPass(const vk::Framebuffer &framebuffer,
                                     const gl::Rectangle &renderArea,
                                     const vk::RenderPassDesc &renderPassDesc,
                                     const vk::AttachmentOpsArray &renderPassAttachmentOps,
                                     const vk::PackedAttachmentIndex depthStencilAttachmentIndex,
                                     const vk::PackedClearValuesArray &clearValues,
                                     vk::CommandBuffer **commandBufferOut);

    // Only returns true if we have a started RP and we've run setupDraw.
    bool hasStartedRenderPass() const
    {
        // Checking mRenderPassCommandBuffer ensures we've called setupDraw.
        return mRenderPassCommandBuffer && mRenderPassCommands->started();
    }

    bool hasStartedRenderPassWithFramebuffer(vk::Framebuffer *framebuffer)
    {
        return hasStartedRenderPass() &&
               mRenderPassCommands->getFramebufferHandle() == framebuffer->getHandle();
    }

    bool hasStartedRenderPassWithCommands() const
    {
        return hasStartedRenderPass() && !mRenderPassCommands->getCommandBuffer().empty();
    }

    vk::CommandBufferHelper &getStartedRenderPassCommands()
    {
        ASSERT(mRenderPassCommands->started());
        return *mRenderPassCommands;
    }

    // TODO(https://anglebug.com/4968): Support multiple open render passes.
    void restoreFinishedRenderPass(vk::Framebuffer *framebuffer);

    uint32_t getCurrentSubpassIndex() const;

    egl::ContextPriority getContextPriority() const override { return mContextPriority; }
    angle::Result startRenderPass(gl::Rectangle renderArea, vk::CommandBuffer **commandBufferOut);
    void startNextSubpass();
    angle::Result flushCommandsAndEndRenderPass();

    angle::Result syncExternalMemory();

    void addCommandBufferDiagnostics(const std::string &commandBufferDiagnostics);

    VkIndexType getVkIndexType(gl::DrawElementsType glIndexType) const;
    size_t getVkIndexTypeSize(gl::DrawElementsType glIndexType) const;
    bool shouldConvertUint8VkIndexType(gl::DrawElementsType glIndexType) const;

    ANGLE_INLINE bool isBresenhamEmulationEnabled(const gl::PrimitiveMode mode)
    {
        return getFeatures().basicGLLineRasterization.enabled && gl::IsLineMode(mode);
    }

    const ProgramExecutableVk *getExecutable() const { return mExecutable; }
    ProgramExecutableVk *getExecutable() { return mExecutable; }

    bool isRobustResourceInitEnabled() const;

    // occlusion query
    void beginOcclusionQuery(QueryVk *queryVk);
    void endOcclusionQuery(QueryVk *queryVk);

    angle::Result pauseOcclusionQueryIfActive();
    angle::Result resumeOcclusionQueryIfActive();

    void updateOverlayOnPresent();
    void addOverlayUsedBuffersCount(vk::CommandBufferHelper *commandBuffer);

    // Sync any errors from the command processor
    void commandProcessorSyncErrors();
    // Sync any error from worker thread and queue up next command for processing
    void commandProcessorSyncErrorsAndQueueCommand(vk::CommandProcessorTask *command);
    // When worker thread completes, it releases command buffers back to context queue
    void recycleCommandBuffer(vk::CommandBufferHelper *commandBuffer);

    // DescriptorSet writes
    VkDescriptorBufferInfo *allocDescriptorBufferInfos(size_t count);
    VkDescriptorImageInfo *allocDescriptorImageInfos(size_t count);
    VkWriteDescriptorSet *allocWriteDescriptorSets(size_t count);

    VkDescriptorBufferInfo &allocDescriptorBufferInfo() { return *allocDescriptorBufferInfos(1); }
    VkDescriptorImageInfo &allocDescriptorImageInfo() { return *allocDescriptorImageInfos(1); }
    VkWriteDescriptorSet &allocWriteDescriptorSet() { return *allocWriteDescriptorSets(1); }

    vk::DynamicBuffer *getDefaultUniformStorage() { return &mDefaultUniformStorage; }
    // For testing only.
    void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);

    vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; }
    vk::DynamicBuffer *getStagingBuffer() { return &mStagingBuffer; }

    const vk::PerfCounters &getPerfCounters() const { return mPerfCounters; }
    vk::PerfCounters &getPerfCounters() { return mPerfCounters; }

    void onSyncHelperInitialize() { mSyncObjectPendingFlush = true; }

    // When UtilsVk issues a draw call on the currently running render pass, the pipelines and
    // descriptor sets it binds need to be undone.
    void invalidateGraphicsPipelineAndDescriptorSets();

  private:
    // Dirty bits.
    enum DirtyBitType : size_t
    {
        DIRTY_BIT_EVENT_LOG,
        DIRTY_BIT_DEFAULT_ATTRIBS,
        DIRTY_BIT_PIPELINE,
        DIRTY_BIT_TEXTURES,
        DIRTY_BIT_VERTEX_BUFFERS,
        DIRTY_BIT_INDEX_BUFFER,
        DIRTY_BIT_DRIVER_UNIFORMS,
        DIRTY_BIT_DRIVER_UNIFORMS_BINDING,
        DIRTY_BIT_SHADER_RESOURCES,  // excluding textures, which are handled separately.
        DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
        DIRTY_BIT_TRANSFORM_FEEDBACK_STATE,
        DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME,
        DIRTY_BIT_DESCRIPTOR_SETS,
        DIRTY_BIT_MAX,
    };

    using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;

    using DirtyBitHandler = angle::Result (ContextVk::*)(const gl::Context *,
                                                         vk::CommandBuffer *commandBuffer);

    struct DriverUniformsDescriptorSet
    {
        vk::DynamicBuffer dynamicBuffer;
        VkDescriptorSet descriptorSet;
        uint32_t dynamicOffset;
        vk::BindingPointer<vk::DescriptorSetLayout> descriptorSetLayout;
        vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
        angle::FastIntegerMap<VkDescriptorSet> descriptorSetCache;

        DriverUniformsDescriptorSet();
        ~DriverUniformsDescriptorSet();

        void init(RendererVk *rendererVk);
        void destroy(RendererVk *rendererVk);
    };

    enum class PipelineType
    {
        Graphics = 0,
        Compute  = 1,

        InvalidEnum = 2,
        EnumCount   = 2,
    };

    // The GpuEventQuery struct holds together a timestamp query and enough data to create a
    // trace event based on that. Use traceGpuEvent to insert such queries.  They will be readback
    // when the results are available, without inserting a GPU bubble.
    //
    // - eventName will be the reported name of the event
    // - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event).
    //   See Google's "Trace Event Format":
    //   https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
    // - serial is the serial of the batch the query was submitted on.  Until the batch is
    //   submitted, the query is not checked to avoid incuring a flush.
    struct GpuEventQuery final
    {
        EventName name;
        char phase;
        vk::QueryHelper queryHelper;
    };

    // Once a query result is available, the timestamp is read and a GpuEvent object is kept until
    // the next clock sync, at which point the clock drift is compensated in the results before
    // handing them off to the application.
    struct GpuEvent final
    {
        uint64_t gpuTimestampCycles;
        std::array<char, kMaxGpuEventNameLen> name;
        char phase;
    };

    struct GpuClockSyncInfo
    {
        double gpuTimestampS;
        double cpuTimestampS;
    };

    // Performance Counters specific to this object type
    using DescriptorSetList =
        std::array<uint32_t, ToUnderlying(ContextVk::PipelineType::EnumCount)>;
    struct PerfCounters
    {
        DescriptorSetList descriptorSetsAllocated;
    };

    class ScopedDescriptorSetUpdates;

    angle::Result setupDraw(const gl::Context *context,
                            gl::PrimitiveMode mode,
                            GLint firstVertexOrInvalid,
                            GLsizei vertexOrIndexCount,
                            GLsizei instanceCount,
                            gl::DrawElementsType indexTypeOrInvalid,
                            const void *indices,
                            DirtyBits dirtyBitMask,
                            vk::CommandBuffer **commandBufferOut);

    angle::Result setupIndexedDraw(const gl::Context *context,
                                   gl::PrimitiveMode mode,
                                   GLsizei indexCount,
                                   GLsizei instanceCount,
                                   gl::DrawElementsType indexType,
                                   const void *indices,
                                   vk::CommandBuffer **commandBufferOut);
    angle::Result setupIndirectDraw(const gl::Context *context,
                                    gl::PrimitiveMode mode,
                                    DirtyBits dirtyBitMask,
                                    vk::BufferHelper *indirectBuffer,
                                    VkDeviceSize indirectBufferOffset,
                                    vk::CommandBuffer **commandBufferOut);
    angle::Result setupIndexedIndirectDraw(const gl::Context *context,
                                           gl::PrimitiveMode mode,
                                           gl::DrawElementsType indexType,
                                           vk::BufferHelper *indirectBuffer,
                                           VkDeviceSize indirectBufferOffset,
                                           vk::CommandBuffer **commandBufferOut);

    angle::Result setupLineLoopIndexedIndirectDraw(const gl::Context *context,
                                                   gl::PrimitiveMode mode,
                                                   gl::DrawElementsType indexType,
                                                   vk::BufferHelper *srcIndirectBuf,
                                                   VkDeviceSize indirectBufferOffset,
                                                   vk::CommandBuffer **commandBufferOut,
                                                   vk::BufferHelper **indirectBufferOut,
                                                   VkDeviceSize *indirectBufferOffsetOut);
    angle::Result setupLineLoopIndirectDraw(const gl::Context *context,
                                            gl::PrimitiveMode mode,
                                            vk::BufferHelper *indirectBuffer,
                                            VkDeviceSize indirectBufferOffset,
                                            vk::CommandBuffer **commandBufferOut,
                                            vk::BufferHelper **indirectBufferOut,
                                            VkDeviceSize *indirectBufferOffsetOut);

    angle::Result setupLineLoopDraw(const gl::Context *context,
                                    gl::PrimitiveMode mode,
                                    GLint firstVertex,
                                    GLsizei vertexOrIndexCount,
                                    gl::DrawElementsType indexTypeOrInvalid,
                                    const void *indices,
                                    vk::CommandBuffer **commandBufferOut,
                                    uint32_t *numIndicesOut);
    angle::Result setupDispatch(const gl::Context *context, vk::CommandBuffer **commandBufferOut);

    gl::Rectangle getCorrectedViewport(const gl::Rectangle &viewport) const;
    void updateViewport(FramebufferVk *framebufferVk,
                        const gl::Rectangle &viewport,
                        float nearPlane,
                        float farPlane,
                        bool invertViewport);
    void updateDepthRange(float nearPlane, float farPlane);
    void updateFlipViewportDrawFramebuffer(const gl::State &glState);
    void updateFlipViewportReadFramebuffer(const gl::State &glState);
    void updateSurfaceRotationDrawFramebuffer(const gl::State &glState);
    void updateSurfaceRotationReadFramebuffer(const gl::State &glState);

    angle::Result updateActiveTextures(const gl::Context *context);
    angle::Result updateActiveImages(const gl::Context *context,
                                     vk::CommandBufferHelper *commandBufferHelper);
    angle::Result updateDefaultAttribute(size_t attribIndex);

    ANGLE_INLINE void invalidateCurrentGraphicsPipeline()
    {
        mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE);
    }

    ANGLE_INLINE void invalidateCurrentComputePipeline()
    {
        mComputeDirtyBits.set(DIRTY_BIT_PIPELINE);
        mCurrentComputePipeline = nullptr;
    }

    void invalidateCurrentDefaultUniforms();
    angle::Result invalidateCurrentTextures(const gl::Context *context);
    void invalidateCurrentShaderResources();
    void invalidateGraphicsDriverUniforms();
    void invalidateDriverUniforms();

    // Handlers for graphics pipeline dirty bits.
    angle::Result handleDirtyGraphicsEventLog(const gl::Context *context,
                                              vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsDefaultAttribs(const gl::Context *context,
                                                    vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsPipeline(const gl::Context *context,
                                              vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsTextures(const gl::Context *context,
                                              vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsVertexBuffers(const gl::Context *context,
                                                   vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsIndexBuffer(const gl::Context *context,
                                                 vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsDriverUniforms(const gl::Context *context,
                                                    vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsDriverUniformsBinding(const gl::Context *context,
                                                           vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsShaderResources(const gl::Context *context,
                                                     vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsTransformFeedbackBuffersEmulation(
        const gl::Context *context,
        vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsTransformFeedbackBuffersExtension(
        const gl::Context *context,
        vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsTransformFeedbackState(const gl::Context *context,
                                                            vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyGraphicsTransformFeedbackResume(const gl::Context *context,
                                                             vk::CommandBuffer *commandBuffer);

    // Handlers for compute pipeline dirty bits.
    angle::Result handleDirtyComputePipeline(const gl::Context *context,
                                             vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyComputeTextures(const gl::Context *context,
                                             vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyComputeDriverUniforms(const gl::Context *context,
                                                   vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyComputeDriverUniformsBinding(const gl::Context *context,
                                                          vk::CommandBuffer *commandBuffer);
    angle::Result handleDirtyComputeShaderResources(const gl::Context *context,
                                                    vk::CommandBuffer *commandBuffer);

    // Common parts of the common dirty bit handlers.
    angle::Result handleDirtyTexturesImpl(vk::CommandBufferHelper *commandBufferHelper);
    angle::Result handleDirtyShaderResourcesImpl(const gl::Context *context,
                                                 vk::CommandBufferHelper *commandBufferHelper);
    void handleDirtyDriverUniformsBindingImpl(vk::CommandBuffer *commandBuffer,
                                              VkPipelineBindPoint bindPoint,
                                              DriverUniformsDescriptorSet *driverUniforms);
    angle::Result handleDirtyDescriptorSets(const gl::Context *context,
                                            vk::CommandBuffer *commandBuffer);
    angle::Result allocateDriverUniforms(size_t driverUniformsSize,
                                         DriverUniformsDescriptorSet *driverUniforms,
                                         uint8_t **ptrOut,
                                         bool *newBufferOut);
    angle::Result updateDriverUniformsDescriptorSet(bool newBuffer,
                                                    size_t driverUniformsSize,
                                                    DriverUniformsDescriptorSet *driverUniforms);

    void writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOut, size_t offsetsSize);

    angle::Result submitFrame(const vk::Semaphore *signalSemaphore);
    angle::Result memoryBarrierImpl(GLbitfield barriers, VkPipelineStageFlags stageMask);

    angle::Result synchronizeCpuGpuTime();
    angle::Result traceGpuEventImpl(vk::CommandBuffer *commandBuffer,
                                    char phase,
                                    const EventName &name);
    angle::Result checkCompletedGpuEvents();
    void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS);
    void handleDeviceLost();
    bool shouldEmulateSeamfulCubeMapSampling() const;
    bool shouldUseOldRewriteStructSamplers() const;
    void clearAllGarbage();
    angle::Result ensureSubmitFenceInitialized();
    bool hasRecordedCommands();
    void dumpCommandStreamDiagnostics();
    angle::Result flushOutsideRenderPassCommands();
    void flushDescriptorSetUpdates();

    ANGLE_INLINE void onRenderPassFinished() { mRenderPassCommandBuffer = nullptr; }

    angle::Result onBufferRead(VkAccessFlags readAccessType,
                               vk::PipelineStage readStage,
                               vk::BufferHelper *buffer);
    angle::Result onBufferWrite(VkAccessFlags writeAccessType,
                                vk::PipelineStage writeStage,
                                vk::BufferHelper *buffer);

    angle::Result onImageRead(VkImageAspectFlags aspectFlags,
                              vk::ImageLayout imageLayout,
                              vk::ImageHelper *image);
    angle::Result onImageWrite(gl::LevelIndex levelStart,
                               uint32_t levelCount,
                               uint32_t layerStart,
                               uint32_t layerCount,
                               VkImageAspectFlags aspectFlags,
                               vk::ImageLayout imageLayout,
                               vk::ImageHelper *image);

    void initIndexTypeMap();

    // Pull an available CBH ptr from the CBH queue and set to specified hasRenderPass state
    void getNextAvailableCommandBuffer(vk::CommandBufferHelper **commandBuffer, bool hasRenderPass);

    angle::Result endRenderPassIfImageUsed(const vk::ImageHelper &image);

    angle::Result endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper *buffer);

    void populateTransformFeedbackBufferSet(
        size_t bufferCount,
        const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers);
    void resumeTransformFeedbackIfStarted();

    // DescriptorSet writes
    template <typename T, const T *VkWriteDescriptorSet::*pInfo>
    T *allocDescriptorInfos(std::vector<T> *descriptorVector, size_t count);
    template <typename T, const T *VkWriteDescriptorSet::*pInfo>
    void growDesciptorCapacity(std::vector<T> *descriptorVector, size_t newSize);

    angle::Result updateRenderPassDepthStencilAccess();
    bool shouldSwitchToReadOnlyDepthFeedbackLoopMode(const gl::Context *context,
                                                     gl::Texture *texture) const;

    void outputCumulativePerfCounters();

    std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
    std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;

    vk::CommandBuffer *mRenderPassCommandBuffer;

    vk::PipelineHelper *mCurrentGraphicsPipeline;
    vk::PipelineAndSerial *mCurrentComputePipeline;
    gl::PrimitiveMode mCurrentDrawMode;

    WindowSurfaceVk *mCurrentWindowSurface;
    // Records the current rotation of the surface (draw/read) framebuffer, derived from
    // mCurrentWindowSurface->getPreTransform().
    SurfaceRotation mCurrentRotationDrawFramebuffer;
    SurfaceRotation mCurrentRotationReadFramebuffer;

    // Keep a cached pipeline description structure that can be used to query the pipeline cache.
    // Kept in a pointer so allocations can be aligned, and structs can be portably packed.
    std::unique_ptr<vk::GraphicsPipelineDesc> mGraphicsPipelineDesc;
    vk::GraphicsPipelineTransitionBits mGraphicsPipelineTransition;

    // These pools are externally sychronized, so cannot be accessed from different
    // threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk.
    // Note that this implementation would need to change in shared resource scenarios. Likely
    // we'd instead share a single set of pools between the share groups.
    angle::PackedEnumMap<PipelineType, vk::DynamicDescriptorPool> mDriverUniformsDescriptorPools;
    angle::PackedEnumMap<gl::QueryType, vk::DynamicQueryPool> mQueryPools;

    // Dirty bits.
    DirtyBits mGraphicsDirtyBits;
    DirtyBits mComputeDirtyBits;
    DirtyBits mNonIndexedDirtyBitsMask;
    DirtyBits mIndexedDirtyBitsMask;
    DirtyBits mNewGraphicsCommandBufferDirtyBits;
    DirtyBits mNewComputeCommandBufferDirtyBits;

    // Cached back-end objects.
    VertexArrayVk *mVertexArray;
    FramebufferVk *mDrawFramebuffer;
    ProgramVk *mProgram;
    ProgramPipelineVk *mProgramPipeline;
    ProgramExecutableVk *mExecutable;

    // occlusion query
    QueryVk *mActiveQueryAnySamples;
    QueryVk *mActiveQueryAnySamplesConservative;

    // The offset we had the last time we bound the index buffer.
    const GLvoid *mLastIndexBufferOffset;
    gl::DrawElementsType mCurrentDrawElementsType;
    angle::PackedEnumMap<gl::DrawElementsType, VkIndexType> mIndexTypeMap;

    // Cache the current draw call's firstVertex to be passed to
    // TransformFeedbackVk::getBufferOffsets.  Unfortunately, gl_BaseVertex support in Vulkan is
    // not yet ubiquitous, which would have otherwise removed the need for this value to be passed
    // as a uniform.
    GLint mXfbBaseVertex;
    // Cache the current draw call's vertex count as well to support instanced draw calls
    GLuint mXfbVertexCountPerInstance;

    // Cached clear value/mask for color and depth/stencil.
    VkClearValue mClearColorValue;
    VkClearValue mClearDepthStencilValue;
    gl::BlendStateExt::ColorMaskStorage::Type mClearColorMasks;

    IncompleteTextureSet mIncompleteTextures;

    // If the current surface bound to this context wants to have all rendering flipped vertically.
    // Updated on calls to onMakeCurrent.
    bool mFlipYForCurrentSurface;
    bool mFlipViewportForDrawFramebuffer;
    bool mFlipViewportForReadFramebuffer;

    // If any host-visible buffer is written by the GPU since last submission, a barrier is inserted
    // at the end of the command buffer to make that write available to the host.
    bool mIsAnyHostVisibleBufferWritten;

    // Whether this context should do seamful cube map sampling emulation.
    bool mEmulateSeamfulCubeMapSampling;

    // Whether this context should use the old version of the
    // RewriteStructSamplers pass.
    bool mUseOldRewriteStructSamplers;

    angle::PackedEnumMap<PipelineType, DriverUniformsDescriptorSet> mDriverUniforms;

    // This cache should also probably include the texture index (shader location) and array
    // index (also in the shader). This info is used in the descriptor update step.
    gl::ActiveTextureArray<vk::TextureUnit> mActiveTextures;
    vk::TextureDescriptorDesc mActiveTexturesDesc;

    gl::ActiveTextureArray<TextureVk *> mActiveImages;

    // "Current Value" aka default vertex attribute state.
    gl::AttributesMask mDirtyDefaultAttribsMask;
    gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;

    // We use a single pool for recording commands. We also keep a free list for pool recycling.
    vk::CommandPool mCommandPool;

    // TODO: This can be killed once threading is enabled https://issuetracker.google.com/153666475
    vk::CommandQueue mCommandQueue;
    vk::GarbageList mCurrentGarbage;

    RenderPassCache mRenderPassCache;

    // mSubmitFence is the fence that's going to be signaled at the next submission.  This is used
    // to support SyncVk objects, which may outlive the context (as EGLSync objects).
    //
    // TODO(geofflang): this is in preparation for moving RendererVk functionality to ContextVk, and
    // is otherwise unnecessary as the SyncVk objects don't actually outlive the renderer currently.
    // http://anglebug.com/2701
    vk::Shared<vk::Fence> mSubmitFence;

    // We have a queue of CommandBufferHelpers (CBHs) that is drawn from for the two active command
    //  buffers in the main thread. The two active command buffers are the inside and outside
    //  RenderPass command buffers.
    constexpr static size_t kNumCommandBuffers = 50;
    std::array<vk::CommandBufferHelper, kNumCommandBuffers> mCommandBuffers;

    // Lock access to the command buffer queue
    std::mutex mCommandBufferQueueMutex;
    std::queue<vk::CommandBufferHelper *> mAvailableCommandBuffers;
    std::condition_variable mAvailableCommandBufferCondition;

    vk::CommandBufferHelper *mOutsideRenderPassCommands;
    vk::CommandBufferHelper *mRenderPassCommands;

    // Transform feedback buffers.
    angle::FastUnorderedSet<const vk::BufferHelper *,
                            gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS>
        mCurrentTransformFeedbackBuffers;

    // Internal shader library.
    vk::ShaderLibrary mShaderLibrary;
    UtilsVk mUtils;

    bool mGpuEventsEnabled;
    vk::DynamicQueryPool mGpuEventQueryPool;
    // A list of queries that have yet to be turned into an event (their result is not yet
    // available).
    std::vector<GpuEventQuery> mInFlightGpuEventQueries;
    // A list of gpu events since the last clock sync.
    std::vector<GpuEvent> mGpuEvents;

    // Track SyncHelper object been added into secondary command buffer that has not been flushed to
    // vulkan.
    bool mSyncObjectPendingFlush;
    uint32_t mDeferredFlushCount;

    // Semaphores that must be waited on in the next submission.
    std::vector<VkSemaphore> mWaitSemaphores;
    std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks;

    // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
    GpuClockSyncInfo mGpuClockSync;

    // The very first timestamp queried for a GPU event is used as origin, so event timestamps would
    // have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to
    // double.
    uint64_t mGpuEventTimestampOrigin;

    // A mix of per-frame and per-run counters.
    vk::PerfCounters mPerfCounters;
    PerfCounters mObjectPerfCounters;

    gl::State::DirtyBits mPipelineDirtyBitsMask;

    // List of all resources currently being used by this ContextVk's recorded commands.
    vk::ResourceUseList mResourceUseList;

    egl::ContextPriority mContextPriority;

    const vk::BufferHelper *mCurrentIndirectBuffer;

    // Storage for vkUpdateDescriptorSets
    std::vector<VkDescriptorBufferInfo> mDescriptorBufferInfos;
    std::vector<VkDescriptorImageInfo> mDescriptorImageInfos;
    std::vector<VkWriteDescriptorSet> mWriteDescriptorSets;

    ShareGroupVk *mShareGroupVk;

    // This is a special "empty" placeholder buffer for use when we just need a placeholder buffer
    // but not the data. Examples are shader that has no uniform or doesn't use all slots in the
    // atomic counter buffer array, or places where there is no vertex buffer since Vulkan does not
    // allow binding a null vertex buffer.
    vk::BufferHelper mEmptyBuffer;

    // Storage for default uniforms of ProgramVks and ProgramPipelineVks.
    vk::DynamicBuffer mDefaultUniformStorage;

    // All staging buffer support is provided by a DynamicBuffer.
    vk::DynamicBuffer mStagingBuffer;

    std::vector<std::string> mCommandBufferDiagnostics;

    // Record GL API calls for debuggers
    std::vector<std::string> mEventLog;
};

ANGLE_INLINE angle::Result ContextVk::endRenderPassIfTransformFeedbackBuffer(
    const vk::BufferHelper *buffer)
{
    if (!buffer || !mCurrentTransformFeedbackBuffers.contains(buffer))
    {
        return angle::Result::Continue;
    }

    return flushCommandsAndEndRenderPass();
}

ANGLE_INLINE angle::Result ContextVk::onIndexBufferChange(
    const vk::BufferHelper *currentIndexBuffer)
{
    mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
    mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer);
    return endRenderPassIfTransformFeedbackBuffer(currentIndexBuffer);
}

ANGLE_INLINE angle::Result ContextVk::onVertexBufferChange(const vk::BufferHelper *vertexBuffer)
{
    mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
    return endRenderPassIfTransformFeedbackBuffer(vertexBuffer);
}

ANGLE_INLINE angle::Result ContextVk::onVertexAttributeChange(size_t attribIndex,
                                                              GLuint stride,
                                                              GLuint divisor,
                                                              angle::FormatID format,
                                                              bool compressed,
                                                              GLuint relativeOffset,
                                                              const vk::BufferHelper *vertexBuffer)
{
    invalidateCurrentGraphicsPipeline();
    // Set divisor to 1 for attribs with emulated divisor
    mGraphicsPipelineDesc->updateVertexInput(
        &mGraphicsPipelineTransition, static_cast<uint32_t>(attribIndex), stride,
        divisor > mRenderer->getMaxVertexAttribDivisor() ? 1 : divisor, format, compressed,
        relativeOffset);
    return onVertexBufferChange(vertexBuffer);
}
}  // namespace rx

#endif  // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
