//
// Copyright 2020 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.
//
// VulkanPerformanceCounterTest:
//   Validates specific GL call patterns with ANGLE performance counters.
//   For example we can verify a certain call set doesn't break the render pass.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#include "include/platform/Feature.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/angle_test_instantiate.h"
#include "test_utils/gl_raii.h"
#include "util/EGLWindow.h"
#include "util/OSWindow.h"
#include "util/random_utils.h"
#include "util/shader_utils.h"
#include "util/test_utils.h"

using namespace angle;

namespace
{
// Normally, if LOAD_OP_NONE is not supported, LOAD_OP_LOAD is used instead.  Similarly, if
// STORE_OP_NONE is not supported, STORE_OP_STORE is used instead.
//
// If an attachment has undefined contents and is unused, LOAD_OP_DONT_CARE and
// STORE_OP_DONT_CARE can be used.  However, these are write operations for synchronization
// purposes, and so ANGLE uses LOAD_OP_NONE and STORE_OP_NONE if available to avoid the
// synchronization.  When NONE is not available, ANGLE foregoes synchronization, producing
// syncval errors.
//
// For the sake of validation, it's unknown if NONE is turned into LOAD/STORE or DONT_CARE.  So
// validation allows variations there.
#define EXPECT_OP_LOAD_AND_NONE(expectedLoads, actualLoads, expectedNones, actualNones) \
    {                                                                                   \
        if (hasLoadOpNoneSupport())                                                     \
        {                                                                               \
            EXPECT_EQ(expectedLoads, actualLoads);                                      \
            EXPECT_EQ(expectedNones, actualNones);                                      \
        }                                                                               \
        else                                                                            \
        {                                                                               \
            EXPECT_EQ(actualNones, 0u);                                                 \
            EXPECT_LE(expectedLoads, actualLoads);                                      \
            EXPECT_GE(expectedLoads + expectedNones, actualLoads);                      \
        }                                                                               \
    }
#define EXPECT_OP_STORE_AND_NONE(expectedStores, actualStores, expectedNones, actualNones) \
    {                                                                                      \
        if (hasStoreOpNoneSupport() && hasLoadOpNoneSupport())                             \
        {                                                                                  \
            EXPECT_EQ(expectedStores, actualStores);                                       \
            EXPECT_EQ(expectedNones, actualNones);                                         \
        }                                                                                  \
        else                                                                               \
        {                                                                                  \
            if (!hasStoreOpNoneSupport())                                                  \
            {                                                                              \
                EXPECT_EQ(actualNones, 0u);                                                \
            }                                                                              \
            EXPECT_LE(expectedStores, actualStores);                                       \
            EXPECT_GE(expectedStores + expectedNones, actualStores + actualNones);         \
        }                                                                                  \
    }

#define EXPECT_DEPTH_OP_COUNTERS(counters, expected)                                       \
    {                                                                                      \
        EXPECT_EQ(expected.depthLoadOpClears, counters.depthLoadOpClears);                 \
        EXPECT_OP_LOAD_AND_NONE(expected.depthLoadOpLoads, counters.depthLoadOpLoads,      \
                                expected.depthLoadOpNones, counters.depthLoadOpNones);     \
        EXPECT_OP_STORE_AND_NONE(expected.depthStoreOpStores, counters.depthStoreOpStores, \
                                 expected.depthStoreOpNones, counters.depthStoreOpNones);  \
    }

#define EXPECT_STENCIL_OP_COUNTERS(counters, expected)                                         \
    {                                                                                          \
        EXPECT_EQ(expected.stencilLoadOpClears, counters.stencilLoadOpClears);                 \
        EXPECT_OP_LOAD_AND_NONE(expected.stencilLoadOpLoads, counters.stencilLoadOpLoads,      \
                                expected.stencilLoadOpNones, counters.stencilLoadOpNones);     \
        EXPECT_OP_STORE_AND_NONE(expected.stencilStoreOpStores, counters.stencilStoreOpStores, \
                                 expected.stencilStoreOpNones, counters.stencilStoreOpNones);  \
    }

#define EXPECT_DEPTH_STENCIL_OP_COUNTERS(counters, expected) \
    {                                                        \
        EXPECT_DEPTH_OP_COUNTERS(counters, expected);        \
        EXPECT_STENCIL_OP_COUNTERS(counters, expected);      \
    }

#define EXPECT_COLOR_OP_COUNTERS(counters, expected)                                       \
    {                                                                                      \
        EXPECT_EQ(expected.colorLoadOpClears, counters.colorLoadOpClears);                 \
        EXPECT_OP_LOAD_AND_NONE(expected.colorLoadOpLoads, counters.colorLoadOpLoads,      \
                                expected.colorLoadOpNones, counters.colorLoadOpNones);     \
        EXPECT_OP_STORE_AND_NONE(expected.colorStoreOpStores, counters.colorStoreOpStores, \
                                 expected.colorStoreOpNones, counters.colorStoreOpNones);  \
    }

#define EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(counters, expected)            \
    {                                                                        \
        EXPECT_EQ(expected.depthLoadOpLoads, counters.depthLoadOpLoads);     \
        EXPECT_EQ(expected.stencilLoadOpLoads, counters.stencilLoadOpLoads); \
    }

#define EXPECT_COUNTERS_FOR_UNRESOLVE_RESOLVE_TEST(counters, expected)                         \
    {                                                                                          \
        EXPECT_EQ(expected.colorAttachmentUnresolves, counters.colorAttachmentUnresolves);     \
        EXPECT_EQ(expected.depthAttachmentUnresolves, counters.depthAttachmentUnresolves);     \
        EXPECT_EQ(expected.stencilAttachmentUnresolves, counters.stencilAttachmentUnresolves); \
        EXPECT_EQ(expected.colorAttachmentResolves, counters.colorAttachmentResolves);         \
        EXPECT_EQ(expected.depthAttachmentResolves, counters.depthAttachmentResolves);         \
        EXPECT_EQ(expected.stencilAttachmentResolves, counters.stencilAttachmentResolves);     \
    }

#define EXPECT_CLEAR_ATTACHMENTS_COUNTER(expected, actual) \
    {                                                      \
        if (hasPreferDrawOverClearAttachments())           \
        {                                                  \
            EXPECT_EQ(actual, 0u);                         \
        }                                                  \
        else                                               \
        {                                                  \
            EXPECT_EQ(actual, expected);                   \
        }                                                  \
    }

enum class BufferUpdate
{
    SubData,  // use glBufferSubData
    Copy,     // use glCopyBufferSubData
};

class VulkanPerformanceCounterTest : public ANGLETest<>
{
  protected:
    VulkanPerformanceCounterTest()
    {
        // Depth/Stencil required for SwapShouldInvalidate*.
        // Also RGBA8 is required to avoid the clear for emulated alpha.
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);
        setConfigStencilBits(8);
    }

    static constexpr GLsizei kOpsTestSize = 16;

    void testSetUp() override
    {
        // Using local variable so that ASAN can catch "stack-buffer-overflow" error.
        GLuint localMonitor;
        glGenPerfMonitorsAMD(1, &localMonitor);
        glBeginPerfMonitorAMD(localMonitor);
        monitor = localMonitor;
    }

    void testTearDown() override
    {
        glEndPerfMonitorAMD(monitor);
        glDeletePerfMonitorsAMD(1, &monitor);
    }

    void setupForColorOpsTest(GLFramebuffer *framebuffer, GLTexture *texture)
    {
        // Setup the framebuffer
        glBindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
        glBindTexture(GL_TEXTURE_2D, *texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kOpsTestSize, kOpsTestSize, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    }

    void setupForColorDepthOpsTest(GLFramebuffer *framebuffer,
                                   GLTexture *texture,
                                   GLRenderbuffer *renderbuffer)
    {
        // Setup color and depth
        glBindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
        glBindTexture(GL_TEXTURE_2D, *texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kOpsTestSize, kOpsTestSize, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0);
        glBindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, kOpsTestSize, kOpsTestSize);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                  *renderbuffer);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Setup depth parameters
        glEnable(GL_DEPTH_TEST);
        glDepthMask(GL_TRUE);
        glDepthFunc(GL_GEQUAL);
        glClearDepthf(0.99f);
        glViewport(0, 0, kOpsTestSize, kOpsTestSize);
        ASSERT_GL_NO_ERROR();
    }

    void setupForDepthStencilOpsTest(GLFramebuffer *framebuffer,
                                     GLTexture *texture,
                                     GLRenderbuffer *renderbuffer)
    {
        // Setup color, depth, and stencil
        glBindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
        glBindTexture(GL_TEXTURE_2D, *texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kOpsTestSize, kOpsTestSize, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0);
        glBindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kOpsTestSize, kOpsTestSize);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                  *renderbuffer);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Setup depth parameters
        glEnable(GL_DEPTH_TEST);
        glDepthMask(GL_TRUE);
        glDepthFunc(GL_GEQUAL);
        glEnable(GL_STENCIL_TEST);
        glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
        glStencilMask(0xFF);
        glClearDepthf(0.99f);
        glClearStencil(0xAA);
        glViewport(0, 0, kOpsTestSize, kOpsTestSize);
        ASSERT_GL_NO_ERROR();
    }

    void setupClearAndDrawForDepthStencilOpsTest(GLProgram *program,
                                                 GLFramebuffer *framebuffer,
                                                 GLTexture *texture,
                                                 GLRenderbuffer *renderbuffer,
                                                 bool clearStencil)
    {
        setupForDepthStencilOpsTest(framebuffer, texture, renderbuffer);

        // Clear and draw with depth and stencil buffer enabled
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
                (clearStencil ? GL_STENCIL_BUFFER_BIT : 0));
        drawQuad(*program, essl1_shaders::PositionAttrib(), 1.f);
        ASSERT_GL_NO_ERROR();
    }

    void setExpectedCountersForColorOps(const angle::VulkanPerfCounters &counters,
                                        uint64_t incrementalRenderPasses,
                                        uint64_t incrementalColorLoadOpClears,
                                        uint64_t incrementalColorLoadOpLoads,
                                        uint64_t incrementalColorLoadOpNones,
                                        uint64_t incrementalColorStoreOpStores,
                                        uint64_t incrementalColorStoreOpNones,
                                        angle::VulkanPerfCounters *expected)
    {
        expected->renderPasses       = counters.renderPasses + incrementalRenderPasses;
        expected->colorLoadOpClears  = counters.colorLoadOpClears + incrementalColorLoadOpClears;
        expected->colorLoadOpLoads   = counters.colorLoadOpLoads + incrementalColorLoadOpLoads;
        expected->colorLoadOpNones   = counters.colorLoadOpNones + incrementalColorLoadOpNones;
        expected->colorStoreOpStores = counters.colorStoreOpStores + incrementalColorStoreOpStores;
        expected->colorStoreOpNones  = counters.colorStoreOpNones + incrementalColorStoreOpNones;
    }

    void setExpectedCountersForUnresolveResolveTest(const angle::VulkanPerfCounters &counters,
                                                    uint64_t incrementalColorAttachmentUnresolves,
                                                    uint64_t incrementalDepthAttachmentUnresolves,
                                                    uint64_t incrementalStencilAttachmentUnresolves,
                                                    uint64_t incrementalColorAttachmentResolves,
                                                    uint64_t incrementalDepthAttachmentResolves,
                                                    uint64_t incrementalStencilAttachmentResolves,
                                                    angle::VulkanPerfCounters *expected)
    {
        expected->colorAttachmentUnresolves =
            counters.colorAttachmentUnresolves + incrementalColorAttachmentUnresolves;
        expected->depthAttachmentUnresolves =
            counters.depthAttachmentUnresolves + incrementalDepthAttachmentUnresolves;
        expected->stencilAttachmentUnresolves =
            counters.stencilAttachmentUnresolves + incrementalStencilAttachmentUnresolves;
        expected->colorAttachmentResolves =
            counters.colorAttachmentResolves + incrementalColorAttachmentResolves;
        expected->depthAttachmentResolves =
            counters.depthAttachmentResolves + incrementalDepthAttachmentResolves;
        expected->stencilAttachmentResolves =
            counters.stencilAttachmentResolves + incrementalStencilAttachmentResolves;
    }

    void maskedFramebufferFetchDraw(const GLColor &clearColor, GLBuffer &buffer);
    void maskedFramebufferFetchDrawVerify(const GLColor &expectedColor, GLBuffer &buffer);

    void updateBuffer(BufferUpdate update,
                      GLenum target,
                      GLintptr offset,
                      GLsizeiptr size,
                      const void *data)
    {
        if (update == BufferUpdate::SubData)
        {
            // If using glBufferSubData, directly upload data on the specified target (where the
            // buffer is already bound)
            glBufferSubData(target, offset, size, data);
        }
        else
        {
            // Otherwise copy through a temp buffer.  Use a non-zero offset for more coverage.
            constexpr GLintptr kStagingOffset = 123;
            GLBuffer staging;
            glBindBuffer(GL_COPY_READ_BUFFER, staging);
            glBufferData(GL_COPY_READ_BUFFER, offset + size + kStagingOffset * 2, nullptr,
                         GL_STATIC_DRAW);
            glBufferSubData(GL_COPY_READ_BUFFER, kStagingOffset, size, data);
            glCopyBufferSubData(GL_COPY_READ_BUFFER, target, kStagingOffset, offset, size);
        }
    }

    void mappingGpuReadOnlyBufferGhostsBuffer(BufferUpdate update);
    void partialBufferUpdateShouldNotBreakRenderPass(BufferUpdate update);
    void bufferSubDataShouldNotTriggerSyncState(BufferUpdate update);

    angle::VulkanPerfCounters getPerfCounters()
    {
        if (mIndexMap.empty())
        {
            mIndexMap = BuildCounterNameToIndexMap();
        }

        return GetPerfCounters(mIndexMap);
    }

    // Support status for ANGLE features.
    bool isFeatureEnabled(Feature feature) const
    {
        return getEGLWindow()->isFeatureEnabled(feature);
    }
    bool hasLoadOpNoneSupport() const
    {
        return isFeatureEnabled(Feature::SupportsRenderPassLoadStoreOpNone);
    }
    bool hasStoreOpNoneSupport() const
    {
        return isFeatureEnabled(Feature::SupportsRenderPassLoadStoreOpNone) ||
               isFeatureEnabled(Feature::SupportsRenderPassStoreOpNone);
    }
    bool hasMutableMipmapTextureUpload() const
    {
        return isFeatureEnabled(Feature::MutableMipmapTextureUpload);
    }
    bool hasPreferDrawOverClearAttachments() const
    {
        return isFeatureEnabled(Feature::PreferDrawClearOverVkCmdClearAttachments);
    }
    bool hasSupportsPipelineCreationFeedback() const
    {
        return isFeatureEnabled(Feature::SupportsPipelineCreationFeedback);
    }
    bool hasWarmUpPipelineCacheAtLink() const
    {
        return isFeatureEnabled(Feature::WarmUpPipelineCacheAtLink);
    }
    bool skipPipelineCacheSerialization() const
    {
        return isFeatureEnabled(Feature::SkipPipelineCacheSerialization);
    }
    bool hasPreferCPUForBufferSubData() const
    {
        return isFeatureEnabled(Feature::PreferCPUForBufferSubData);
    }
    bool hasPreferSubmitAtFBOBoundary() const
    {
        return isFeatureEnabled(Feature::PreferSubmitAtFBOBoundary);
    }
    bool hasDisallowMixedDepthStencilLoadOpNoneAndLoad() const
    {
        return isFeatureEnabled(Feature::DisallowMixedDepthStencilLoadOpNoneAndLoad);
    }
    bool hasSupportsImagelessFramebuffer() const
    {
        return isFeatureEnabled(Feature::SupportsImagelessFramebuffer);
    }
    bool hasSupportsHostImageCopy() const
    {
        return isFeatureEnabled(Feature::SupportsHostImageCopy);
    }
    bool hasDepthStencilResolveThroughAttachment() const
    {
        return isFeatureEnabled(Feature::SupportsDepthStencilResolve) &&
               !isFeatureEnabled(Feature::DisableDepthStencilResolveThroughAttachment);
    }
    bool hasSupportsTileMemoryOrSimulation() const
    {
        return isFeatureEnabled(Feature::SupportsTileMemoryHeap) ||
               isFeatureEnabled(Feature::SimulateTileMemoryForTesting);
    }
    bool hasSupportsShaderStencilExport() const
    {
        return isFeatureEnabled(Feature::SupportsShaderStencilExport);
    }

    // Setup color texture and depth/stencil render buffer
    void setupColorTextureAndDepthBuffer(GLuint colorTexture,
                                         GLuint depthStencil,
                                         GLenum depthStencilFormat,
                                         GLsizei width,
                                         GLsizei height)
    {
        glBindTexture(GL_TEXTURE_2D, colorTexture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);

        glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
        glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
    }

    // Setup FBO with color/depth/stencil attachment
    void setupFBO(GLuint colorTexture,
                  GLuint depthBuffer,
                  GLuint stencilBuffer,
                  GLuint fbo,
                  GLsizei width,
                  GLsizei height)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        if (colorTexture != 0)
        {
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                   colorTexture, 0);
        }
        if (depthBuffer != 0)
        {
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
                                      depthBuffer);
        }
        if (stencilBuffer != 0)
        {
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                                      stencilBuffer);
        }
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
        glViewport(0, 0, width, height);
    }

    // Draw a quad that would display green if depth buffer == depthValue, and display red
    // otherwise.
    void drawQuadToVerifyDepthValue(const GLProgram &drawGreen,
                                    const GLProgram &drawRed,
                                    GLfloat depthValue)
    {
        GLfloat kErrorTolerance = 0.01f;
        glDisable(GL_STENCIL_TEST);
        // Don't modify depth buffer
        glDepthMask(GL_FALSE);
        glEnable(GL_DEPTH_TEST);
        // This should pass
        glDepthFunc(GL_LESS);
        drawQuad(drawGreen, essl1_shaders::PositionAttrib(), depthValue - kErrorTolerance);
        // This should fail
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), depthValue + kErrorTolerance);
        glDepthFunc(GL_GREATER);
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), depthValue - kErrorTolerance);
    }

    // Draw a quad that would display green if stencil buffer == stencilValue.
    void drawQuadToVerifyStencilValue(const GLProgram &drawGreen, GLint stencilValue)
    {
        glDisable(GL_DEPTH_TEST);
        glStencilMask(0x00);
        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_EQUAL, stencilValue, 0xFF);
        drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
    }

    void drawWithDepthValue(std::array<Vector3, 6> &quadVertices, float depth)
    {
        for (Vector3 &vertice : quadVertices)
        {
            vertice[2] = depth;
        }
        glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(quadVertices[0]) * quadVertices.size(),
                        quadVertices.data());
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }

    GLuint monitor;
    CounterNameToIndexMap mIndexMap;
};

class VulkanPerformanceCounterTest_DepthStencilLoadStoreOps : public VulkanPerformanceCounterTest
{
  protected:
    void setExpectedCountersForDepthOps(const angle::VulkanPerfCounters &counters,
                                        uint64_t incrementalRenderPasses,
                                        uint64_t incrementalDepthLoadOpClears,
                                        uint64_t incrementalDepthLoadOpLoads,
                                        uint64_t incrementalDepthLoadOpNones,
                                        uint64_t incrementalDepthStoreOpStores,
                                        uint64_t incrementalDepthStoreOpNones,
                                        angle::VulkanPerfCounters *expected)
    {
        expected->renderPasses       = counters.renderPasses + incrementalRenderPasses;
        expected->depthLoadOpClears  = counters.depthLoadOpClears + incrementalDepthLoadOpClears;
        expected->depthLoadOpLoads   = counters.depthLoadOpLoads + incrementalDepthLoadOpLoads;
        expected->depthLoadOpNones   = counters.depthLoadOpNones + incrementalDepthLoadOpNones;
        expected->depthStoreOpStores = counters.depthStoreOpStores + incrementalDepthStoreOpStores;
        expected->depthStoreOpNones  = counters.depthStoreOpNones + incrementalDepthStoreOpNones;
    }

    void setExpectedCountersForStencilOps(const angle::VulkanPerfCounters &counters,
                                          uint64_t incrementalStencilLoadOpClears,
                                          uint64_t incrementalStencilLoadOpLoads,
                                          uint64_t incrementalStencilLoadOpNones,
                                          uint64_t incrementalStencilStoreOpStores,
                                          uint64_t incrementalStencilStoreOpNones,
                                          angle::VulkanPerfCounters *expected)
    {
        expected->stencilLoadOpClears =
            counters.stencilLoadOpClears + incrementalStencilLoadOpClears;
        expected->stencilLoadOpLoads = counters.stencilLoadOpLoads + incrementalStencilLoadOpLoads;
        expected->stencilLoadOpNones = counters.stencilLoadOpNones + incrementalStencilLoadOpNones;
        expected->stencilStoreOpStores =
            counters.stencilStoreOpStores + incrementalStencilStoreOpStores;
        expected->stencilStoreOpNones =
            counters.stencilStoreOpNones + incrementalStencilStoreOpNones;
    }

    void setAndIncrementDepthStencilLoadCountersForOpsTest(
        const angle::VulkanPerfCounters &counters,
        uint64_t incrementalDepthLoadOpLoads,
        uint64_t incrementalStencilLoadOpLoads,
        angle::VulkanPerfCounters *expected)
    {
        expected->depthLoadOpLoads   = counters.depthLoadOpLoads + incrementalDepthLoadOpLoads;
        expected->stencilLoadOpLoads = counters.stencilLoadOpLoads + incrementalStencilLoadOpLoads;
    }

    void setAndIncrementDepthStencilStoreCountersForOpsTest(
        const angle::VulkanPerfCounters &counters,
        uint64_t incrementalDepthStoreOpStores,
        uint64_t incrementalStencilStoreOpStores,
        angle::VulkanPerfCounters *expected)
    {
        expected->depthStoreOpStores = counters.depthStoreOpStores + incrementalDepthStoreOpStores;
        expected->stencilStoreOpStores =
            counters.stencilStoreOpStores + incrementalStencilStoreOpStores;
    }

    void adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(
        const angle::VulkanPerfCounters &counters,
        angle::VulkanPerfCounters *expected)
    {
        if (counters.fallbackFromTileMemory == 0)
        {
            return;
        }

        bool depthContentDefined =
            expected->depthStoreOpStores > 0 || expected->depthStoreOpNones > 0;
        if (depthContentDefined)
        {
            // fallbackFromTileMemory adds one load/store op if there is valid depth data.
            expected->depthLoadOpLoads += counters.fallbackFromTileMemory;
            expected->depthStoreOpStores += counters.fallbackFromTileMemory;
        }
        else
        {
            if (hasLoadOpNoneSupport())
            {
                expected->depthLoadOpNones += counters.fallbackFromTileMemory;
            }
            else
            {
                expected->depthLoadOpLoads += counters.fallbackFromTileMemory;
            }
            if (hasStoreOpNoneSupport())
            {
                expected->depthStoreOpNones += counters.fallbackFromTileMemory;
            }
            else
            {
                expected->depthStoreOpStores += counters.fallbackFromTileMemory;
            }
        }

        // fallbackFromTileMemory adds one load/store op if there is valid stencil data.
        if (expected->stencilStoreOpStores > 0 && hasSupportsShaderStencilExport())
        {
            // If driver supports shader export, copy is implemented with graphics shader write.
            expected->stencilLoadOpLoads += counters.fallbackFromTileMemory;
            expected->stencilStoreOpStores += counters.fallbackFromTileMemory;
        }
        else
        {
            if (hasLoadOpNoneSupport())
            {
                expected->stencilLoadOpNones += counters.fallbackFromTileMemory;
            }
            else
            {
                expected->stencilLoadOpLoads += counters.fallbackFromTileMemory;
            }
            if (hasStoreOpNoneSupport())
            {
                expected->stencilStoreOpNones += counters.fallbackFromTileMemory;
            }
            else
            {
                expected->stencilStoreOpStores += counters.fallbackFromTileMemory;
            }
        }
    }
};

class VulkanPerformanceCounterTest_RGBSurface : public VulkanPerformanceCounterTest
{
  protected:
    VulkanPerformanceCounterTest_RGBSurface() : VulkanPerformanceCounterTest()
    {
        // Only set the Alpha bit to 0 on ARM platforms to avoid EGL configuration
        // failures.
        if (IsARM())
        {
            setConfigAlphaBits(0);
        }
    }
};

class VulkanPerformanceCounterTest_ES31 : public VulkanPerformanceCounterTest
{};

class VulkanPerformanceCounterTest_DepthStencilLoadStoreOps_ES31
    : public VulkanPerformanceCounterTest_DepthStencilLoadStoreOps
{};

class VulkanPerformanceCounterTest_MSAA
    : public VulkanPerformanceCounterTest_DepthStencilLoadStoreOps
{
  protected:
    VulkanPerformanceCounterTest_MSAA() : VulkanPerformanceCounterTest_DepthStencilLoadStoreOps()
    {
        // Make sure the window is non-square to correctly test prerotation
        setWindowWidth(32);
        setWindowHeight(64);
        setSamples(4);
        setMultisampleEnabled(true);
    }
};

class VulkanPerformanceCounterTest_SingleBuffer : public VulkanPerformanceCounterTest
{
  protected:
    VulkanPerformanceCounterTest_SingleBuffer() : VulkanPerformanceCounterTest()
    {
        setMutableRenderBuffer(true);
    }
};

class VulkanPerformanceCounterTest_Prerotation : public VulkanPerformanceCounterTest
{
  protected:
    VulkanPerformanceCounterTest_Prerotation() : VulkanPerformanceCounterTest()
    {
        // Make sure the window is non-square to correctly test prerotation
        setWindowWidth(32);
        setWindowHeight(64);
    }
};

void VulkanPerformanceCounterTest::maskedFramebufferFetchDraw(const GLColor &clearColor,
                                                              GLBuffer &buffer)
{
    // Initialize the color buffer
    angle::Vector4 clearAsVec4 = clearColor.toNormalizedVector();
    glClearColor(clearAsVec4[0], clearAsVec4[1], clearAsVec4[2], clearAsVec4[3]);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_NEAR(0, 0, clearColor, 1);

    // Create output buffer
    constexpr GLsizei kBufferSize = kOpsTestSize * kOpsTestSize * sizeof(float[4]);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
    glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, 0, kBufferSize);

    // Zero-initialize it
    void *bufferData = glMapBufferRange(
        GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
        GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
    memset(bufferData, 0, kBufferSize);
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

    // Mask color output
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

    static constexpr char kVS[] = R"(#version 310 es
in highp vec4 a_position;

void main (void)
{
    gl_Position = a_position;
})";

    static constexpr char kFS[] = R"(#version 310 es
#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
layout(noncoherent, location = 0) inout highp vec4 o_color;

layout(std140, binding = 0) buffer outBlock {
    highp vec4 data[256];
};

uniform highp vec4 u_color;
void main (void)
{
    uint index = uint(gl_FragCoord.y) * 16u + uint(gl_FragCoord.x);
    data[index] = o_color;
    o_color += u_color;
})";

    // Draw
    ANGLE_GL_PROGRAM(program, kVS, kFS);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
}

void VulkanPerformanceCounterTest::maskedFramebufferFetchDrawVerify(const GLColor &expectedColor,
                                                                    GLBuffer &buffer)
{
    angle::Vector4 expectedAsVec4 = expectedColor.toNormalizedVector();

    // Read back the storage buffer and make sure framebuffer fetch worked as intended despite
    // masked color.
    glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);

    constexpr GLsizei kBufferSize = kOpsTestSize * kOpsTestSize * sizeof(float[4]);
    const float *colorData        = static_cast<const float *>(
        glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
    for (uint32_t y = 0; y < kOpsTestSize; ++y)
    {
        for (uint32_t x = 0; x < kOpsTestSize; ++x)
        {
            uint32_t ssboIndex = (y * kOpsTestSize + x) * 4;
            EXPECT_NEAR(colorData[ssboIndex + 0], expectedAsVec4[0], 0.05);
            EXPECT_NEAR(colorData[ssboIndex + 1], expectedAsVec4[1], 0.05);
            EXPECT_NEAR(colorData[ssboIndex + 2], expectedAsVec4[2], 0.05);
            EXPECT_NEAR(colorData[ssboIndex + 3], expectedAsVec4[3], 0.05);
        }
    }
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
}

// Tests that texture updates to unused textures don't break the RP.
TEST_P(VulkanPerformanceCounterTest, NewTextureDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    GLColor kInitialData[4] = {GLColor::red, GLColor::blue, GLColor::green, GLColor::yellow};

    // Step 1: Set up a simple 2D Texture rendering loop.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kInitialData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    auto quadVerts = GetQuadVertices();

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
                 GL_STATIC_DRAW);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program);

    GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
    ASSERT_NE(-1, posLoc);

    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses;

    // Step 2: Introduce a new 2D Texture with the same Program and Framebuffer.
    GLTexture newTexture;
    glBindTexture(GL_TEXTURE_2D, newTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kInitialData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Tests that each update for a large cube map face results in outside command buffer submission.
TEST_P(VulkanPerformanceCounterTest, LargeCubeMapUpdatesSubmitsOutsideCommandBuffer)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    constexpr size_t kMaxBufferToImageCopySize = 64 * 1024 * 1024;
    constexpr uint64_t kNumSubmits             = 6;
    uint64_t expectedSubmitCommandsCount = getPerfCounters().vkQueueSubmitCallsTotal + kNumSubmits;

    // Set up a simple large cubemap texture so that each face update, when flushed, can result in a
    // separate submission.
    GLTexture textureCube;
    constexpr GLsizei kTexDim         = 4096;
    constexpr uint32_t kPixelSizeRGBA = 4;
    static_assert(kTexDim * kTexDim * kPixelSizeRGBA == kMaxBufferToImageCopySize);

    std::vector<GLColor> kInitialData(kTexDim * kTexDim, GLColor::magenta);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureCube);

    for (size_t i = 0; i < 6; i++)
    {
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, kTexDim, kTexDim, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, kInitialData.data());
    }

    // Flush the previous texture.
    GLTexture lastTexture;
    glBindTexture(GL_TEXTURE_2D, lastTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 kInitialData.data());

    // Verify number of submissions.
    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedSubmitCommandsCount);
}

// Tests that submitting the outside command buffer due to texture upload size does not break the
// current render pass.
TEST_P(VulkanPerformanceCounterTest, SubmittingOutsideCommandBufferDoesNotBreakRenderPass)
{
    GLTexture tex;
    GLFramebuffer fbo;
    setupForColorOpsTest(&fbo, &tex);

    constexpr size_t kMaxBufferToImageCopySize = 64 * 1024 * 1024;
    constexpr uint64_t kNumSubmits             = 2;
    uint64_t expectedRenderPassCount           = getPerfCounters().renderPasses + 1;
    uint64_t submitCommandsCountBefore         = getPerfCounters().vkQueueSubmitCallsTotal;

    // Step 1: Set up a simple 2D texture.
    GLTexture texture;
    constexpr GLsizei kTexDim         = 256;
    constexpr uint32_t kPixelSizeRGBA = 4;
    constexpr uint32_t kTextureSize   = kTexDim * kTexDim * kPixelSizeRGBA;
    std::vector<GLColor> kInitialData(kTexDim * kTexDim, GLColor::green);

    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexDim, kTexDim, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 kInitialData.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    auto quadVerts = GetQuadVertices();

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
                 GL_STATIC_DRAW);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program);

    GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
    ASSERT_NE(-1, posLoc);

    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Step 2: Load a new 2D Texture multiple times with the same Program and Framebuffer. The total
    // size of the loaded textures must exceed the threshold to submit the outside command buffer.
    constexpr size_t kMaxLoadCount = kMaxBufferToImageCopySize / kTextureSize * kNumSubmits + 1;
    for (size_t loadCount = 0; loadCount < kMaxLoadCount; loadCount++)
    {
        GLTexture newTexture;
        glBindTexture(GL_TEXTURE_2D, newTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexDim, kTexDim, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     kInitialData.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glDrawArrays(GL_TRIANGLES, 0, 6);
        ASSERT_GL_NO_ERROR();
    }

    // Verify render pass and submitted frame counts.
    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal - submitCommandsCountBefore, kNumSubmits);
}

// Tests that submitting the outside command buffer due to texture upload size does not result in
// garbage collection of render pass resources..
TEST_P(VulkanPerformanceCounterTest, SubmittingOutsideCommandBufferDoesNotCollectRenderPassGarbage)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_disjoint_timer_query"));

    // If VK_EXT_host_image_copy is used, uploads will all be done on the CPU and there would be no
    // submissions.
    ANGLE_SKIP_TEST_IF(hasSupportsHostImageCopy());

    GLTexture tex;
    GLFramebuffer fbo;
    setupForColorOpsTest(&fbo, &tex);

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;
    uint64_t submitCommandsCount     = getPerfCounters().vkQueueSubmitCallsTotal;

    // Set up a simple 2D texture.
    GLTexture texture;
    constexpr GLsizei kTexDim = 256;
    std::vector<GLColor> kInitialData(kTexDim * kTexDim, GLColor::green);

    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexDim, kTexDim, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 kInitialData.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    auto quadVerts = GetQuadVertices();

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
                 GL_STATIC_DRAW);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program);

    GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
    ASSERT_NE(-1, posLoc);

    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);
    ASSERT_GL_NO_ERROR();

    // Issue a timestamp query, just for the sake of using it as a means of knowing when a
    // submission is finished.  In the Vulkan backend, querying the status of the query results in a
    // check of completed submissions, at which point associated garbage is also destroyed.
    GLQuery query;
    glQueryCounterEXT(query, GL_TIMESTAMP_EXT);

    // Issue a draw call, and delete the program
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();
    program.reset();

    ANGLE_GL_PROGRAM(program2, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program2);
    ASSERT_EQ(posLoc, glGetAttribLocation(program2, essl1_shaders::PositionAttrib()));

    // Issue uploads until there's an implicit submission
    size_t textureCount = 0;
    while (getPerfCounters().vkQueueSubmitCallsTotal == submitCommandsCount)
    {
        GLTexture newTexture;
        glBindTexture(GL_TEXTURE_2D, newTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexDim, kTexDim, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     kInitialData.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glDrawArrays(GL_TRIANGLES, 0, 6);
        ASSERT_GL_NO_ERROR();
        textureCount++;
    }
    // 256x256 texture upload should not trigger a submission
    ASSERT(textureCount > 1);

    ++submitCommandsCount;
    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, submitCommandsCount);

    // Busy wait until the query results are available.
    GLuint ready = GL_FALSE;
    while (ready == GL_FALSE)
    {
        angle::Sleep(0);
        glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, &ready);
    }

    // At this point, the render pass should still not be submitted, and the pipeline that is
    // deleted should still not be garbage collected.  Submit the commands and ensure there is no
    // crash.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    ++submitCommandsCount;

    // Verify counters.
    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, submitCommandsCount);
}

// Tests that submitting the outside command buffer due to texture upload size and triggers
// endRenderPass works correctly.
TEST_P(VulkanPerformanceCounterTest, SubmittingOutsideCommandBufferTriggersEndRenderPass)
{
    // If VK_EXT_host_image_copy is used, uploads will all be done on the CPU and there would be no
    // submissions.
    ANGLE_SKIP_TEST_IF(hasSupportsHostImageCopy());

    const int width                  = getWindowWidth();
    const int height                 = getWindowHeight();
    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;
    uint64_t submitCommandsCount     = getPerfCounters().vkQueueSubmitCallsTotal;

    GLTexture tex;
    GLFramebuffer fbo;
    setupForColorOpsTest(&fbo, &tex);

    // Start a new renderpass with red quad on left.
    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    glScissor(0, 0, width / 2, height);
    glEnable(GL_SCISSOR_TEST);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);

    // Issue texture uploads and draw green quad on right until endRenderPass is triggered
    glScissor(width / 2, 0, width / 2, height);
    ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());
    glUseProgram(textureProgram);
    GLint textureLoc = glGetUniformLocation(textureProgram, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, textureLoc);
    glUniform1i(textureLoc, 0);

    // This test is specifically try to test outsideRPCommands submission drain the reserved
    // queueSerials. Right now we are reserving 15 queue Serials. This is to ensure if the
    // implementation changes, we do not end up with infinite loop here.
    constexpr GLsizei kMaxOutsideRPCommandsSubmitCount = 17;
    constexpr GLsizei kTexDim                          = 1024;
    std::vector<GLColor> kInitialData(kTexDim * kTexDim, GLColor::green);
    // Put a limit on the loop to avoid infinite loop in bad case.
    while (getPerfCounters().renderPasses == expectedRenderPassCount &&
           getPerfCounters().vkQueueSubmitCallsTotal <
               submitCommandsCount + kMaxOutsideRPCommandsSubmitCount)
    {
        GLTexture newTexture;
        glBindTexture(GL_TEXTURE_2D, newTexture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexDim, kTexDim);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexDim, kTexDim, GL_RGBA, GL_UNSIGNED_BYTE,
                        kInitialData.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f);
        ASSERT_GL_NO_ERROR();
    }

    ++expectedRenderPassCount;
    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);

    // Verify renderpass draw quads correctly
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(width / 2 + 1, 0, GLColor::green);
}

// Tests that a color 2D image is cleared via vkCmdClearColorImage.
TEST_P(VulkanPerformanceCounterTest, ClearTextureEXTFullColorImageClear2D)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
    uint32_t expectedFullImageClearsAfterFullClear1 = getPerfCounters().fullImageClears + 1;
    uint32_t expectedFullImageClearsAfterFullClear2 = getPerfCounters().fullImageClears + 2;

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // The following is the first full clear.
    glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
    EXPECT_GL_NO_ERROR();
    EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
    EXPECT_EQ(getPerfCounters().fullImageClears, expectedFullImageClearsAfterFullClear1);

    // The following are several partial clears.
    glClearTexSubImageEXT(tex, 0, 0, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glClearTexSubImageEXT(tex, 0, 8, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
    glClearTexSubImageEXT(tex, 0, 0, 8, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::cyan);
    glClearTexSubImageEXT(tex, 0, 8, 8, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::yellow);
    EXPECT_GL_NO_ERROR();
    EXPECT_PIXEL_RECT_EQ(0, 0, 8, 8, GLColor::transparentBlack);
    EXPECT_EQ(getPerfCounters().fullImageClears, expectedFullImageClearsAfterFullClear1);

    // The following is the second full clear (extents of a full clear).
    glClearTexSubImageEXT(tex, 0, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::magenta);
    EXPECT_GL_NO_ERROR();
    EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::magenta);
    EXPECT_EQ(getPerfCounters().fullImageClears, expectedFullImageClearsAfterFullClear2);
}

// Tests that a color 3D image is cleared via vkCmdClearColorImage.
TEST_P(VulkanPerformanceCounterTest, ClearTextureEXTFullColorImageClear3D)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
    uint32_t expectedFullImageClears = getPerfCounters().fullImageClears + 1;

    constexpr uint32_t kWidth  = 4;
    constexpr uint32_t kHeight = 4;
    constexpr uint32_t kDepth  = 4;

    GLTexture texture;
    glBindTexture(GL_TEXTURE_3D, texture);
    glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);

    glClearTexImageEXT(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::white);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, 0);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::white);
    EXPECT_EQ(getPerfCounters().fullImageClears, expectedFullImageClears);

    glClearTexSubImageEXT(texture, 0, 0, 0, 0, kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE,
                          &GLColor::green);
    glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, 0);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);

    EXPECT_EQ(getPerfCounters().fullImageClears, expectedFullImageClears);
}

// Tests that mutable texture is uploaded with appropriate mip level attributes.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCompatibleMipLevelsInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded + 1;

    std::vector<GLColor> mip0Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that a single-level mutable texture is uploaded with appropriate attributes.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCompatibleSingleMipLevelInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded + 1;

    std::vector<GLColor> mip0Color(4 * 4, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable texture is uploaded with appropriate mip level attributes, even with unequal
// dimensions.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCompatibleMipLevelsNonSquareInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded + 1;

    std::vector<GLColor> mip0Color(4 * 2, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 1, GLColor::red);
    std::vector<GLColor> mip2Color(1 * 1, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Color.data());
    glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip2Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that a mutable texture is not uploaded if there are no data or updates for it.
TEST_P(VulkanPerformanceCounterTest, MutableTextureSingleLevelWithNoDataNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable texture is not uploaded with more than one updates in a single mip level.
TEST_P(VulkanPerformanceCounterTest, MutableTextureSingleLevelWithMultipleUpdatesNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(4 * 4, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexSubImage2D(GL_TEXTURE_2D, 0, 2, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 2, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexSubImage2D(GL_TEXTURE_2D, 0, 2, 2, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that the optimization is not triggered when a mutable texture becomes immutable, e.g.,
// after glTexStorage2D.
TEST_P(VulkanPerformanceCounterTest, MutableTextureChangeToImmutableNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Color.data());
    glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 4, 4);
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable texture is not uploaded when there is no base mip level (0).
TEST_P(VulkanPerformanceCounterTest, MutableTextureNoBaseLevelNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip1Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip2Color(2 * 2, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Color.data());
    glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip2Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable texture is uploaded even when there is a missing mip level greater than 1
// despite the defined mip levels being compatible.
TEST_P(VulkanPerformanceCounterTest, MutableTextureMissingMipLevelGreaterThanOneInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded + 1;

    std::vector<GLColor> mip0Color(8 * 8, GLColor::red);
    std::vector<GLColor> mip1Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip3Color(1 * 1, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Color.data());
    glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip3Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable texture is not uploaded with incompatible mip level sizes.
TEST_P(VulkanPerformanceCounterTest, MutableTextureMipLevelsWithIncompatibleSizesNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(8 * 8, GLColor::red);
    std::vector<GLColor> mip1Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip2Color(3 * 3, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Color.data());
    glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip2Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable texture is not uploaded with incompatible mip level formats.
TEST_P(VulkanPerformanceCounterTest, MutableTextureMipLevelsWithIncompatibleFormatsNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Color.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, mip1Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable 3D texture is uploaded with appropriate mip level attributes.
TEST_P(VulkanPerformanceCounterTest, MutableTexture3DCompatibleMipLevelsInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded + 1;

    std::vector<GLColor> mip0Color(4 * 4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2 * 2, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_3D, texture1);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip0Color.data());
    glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, 2, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip1Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_3D, texture2);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable 3D texture is uploaded with appropriate mip level attributes, even with
// unequal dimensions.
TEST_P(VulkanPerformanceCounterTest, MutableTexture3DCompatibleMipLevelsNonCubeInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded + 1;

    std::vector<GLColor> mip0Color(4 * 2 * 2, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 1 * 1, GLColor::red);
    std::vector<GLColor> mip2Color(1 * 1 * 1, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_3D, texture1);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip0Color.data());
    glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, 2, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip1Color.data());
    glTexImage3D(GL_TEXTURE_3D, 2, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip1Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_3D, texture2);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable 3D texture is not uploaded with incompatible mip level sizes.
TEST_P(VulkanPerformanceCounterTest, MutableTexture3DMipLevelsWithIncompatibleSizesNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(4 * 4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2 * 3, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_3D, texture1);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip0Color.data());
    glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, 2, 2, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip1Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_3D, texture2);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable 2D array texture is not uploaded with incompatible mip level sizes.
TEST_P(VulkanPerformanceCounterTest, MutableTexture2DArrayMipLevelsWithIncompatibleSizesNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(4 * 4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2 * 3, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D_ARRAY, texture1);
    glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip0Color.data());
    glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA, 2, 2, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip1Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_3D, texture2);
    glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable cubemap texture is uploaded with appropriate mip level attributes.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCubemapCompatibleMipLevelsInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded + 1;

    std::vector<GLColor> mip0Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_CUBE_MAP, texture1);
    for (size_t i = 0; i < 6; i++)
    {
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, 4, 4, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, mip0Color.data());
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 1, GL_RGBA, 2, 2, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, mip1Color.data());
    }
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable cubemap texture is not uploaded with no data or updates.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCubemapWithNoDataNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_CUBE_MAP, texture1);
    for (size_t i = 0; i < 6; i++)
    {
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, 4, 4, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 1, GL_RGBA, 2, 2, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
    }
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable cubemap texture is not uploaded with more than one update in a cube face.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCubemapMultipleUpdatesForOneFaceNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_CUBE_MAP, texture1);
    for (size_t i = 0; i < 6; i++)
    {
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, 4, 4, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 1, GL_RGBA, 2, 2, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
    }
    EXPECT_GL_NO_ERROR();
    for (size_t i = 0; i < 6; i++)
    {
        glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, 4, 4, GL_RGBA,
                        GL_UNSIGNED_BYTE, mip0Color.data());
        glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 1, 0, 0, 2, 2, GL_RGBA,
                        GL_UNSIGNED_BYTE, mip1Color.data());
    }
    glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 1, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
                    GLColor::red.data());

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable cubemap texture is not uploaded if not complete.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCubemapIncompleteInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(4 * 4, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_CUBE_MAP, texture1);
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip0Color.data());
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 1, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip1Color.data());
    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable cubemap array texture is uploaded with appropriate mip level attributes.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCubemapArrayCompatibleMipLevelsInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded + 1;

    std::vector<GLColor> mip0Color(4 * 4 * 6, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2 * 6, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texture1);
    glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 4, 4, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip0Color.data());
    glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA, 2, 2, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip1Color.data());

    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that mutable cubemap array texture is not uploaded with different layer-faces.
TEST_P(VulkanPerformanceCounterTest, MutableTextureCubemapArrayDifferentLayerFacesNoInit)
{
    ANGLE_SKIP_TEST_IF(!hasMutableMipmapTextureUpload());

    uint32_t expectedMutableTexturesUploaded = getPerfCounters().mutableTexturesUploaded;

    std::vector<GLColor> mip0Color(4 * 4 * 6, GLColor::red);
    std::vector<GLColor> mip1Color(2 * 2 * 12, GLColor::red);

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texture1);
    glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 4, 4, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip0Color.data());
    glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA, 2, 2, 12, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 mip1Color.data());

    EXPECT_GL_NO_ERROR();

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 GLColor::green.data());
    EXPECT_GL_NO_ERROR();
    EXPECT_EQ(getPerfCounters().mutableTexturesUploaded, expectedMutableTexturesUploaded);
}

// Tests that RGB texture should not break renderpass.
TEST_P(VulkanPerformanceCounterTest, SampleFromRGBTextureDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program);
    GLint textureLoc = glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, textureLoc);

    GLTexture textureRGBA;
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureRGBA);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    GLTexture textureRGB;
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, textureRGB);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // First draw with textureRGBA which should start the renderpass
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUniform1i(textureLoc, 0);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Next draw with textureRGB which should not end the renderpass
    glUniform1i(textureLoc, 1);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Tests that RGB texture should not break renderpass.
TEST_P(VulkanPerformanceCounterTest, RenderToRGBTextureDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor());
    glUseProgram(program);
    GLint colorUniformLocation =
        glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(-1, colorUniformLocation);
    ASSERT_GL_NO_ERROR();

    GLTexture textureRGB;
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, textureRGB);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureRGB, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // Draw into FBO
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);  // clear to green
    glClear(GL_COLOR_BUFFER_BIT);
    glViewport(0, 0, 256, 256);
    glUniform4fv(colorUniformLocation, 1, GLColor::blue.toNormalizedVector().data());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Tests that changing a Texture's max level hits the descriptor set cache.
TEST_P(VulkanPerformanceCounterTest, ChangingMaxLevelHitsDescriptorCache)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    GLColor kInitialData[4] = {GLColor::red, GLColor::blue, GLColor::green, GLColor::yellow};

    // Step 1: Set up a simple mipped 2D Texture rendering loop.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kInitialData);
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, kInitialData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);

    auto quadVerts = GetQuadVertices();

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
                 GL_STATIC_DRAW);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program);

    GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
    ASSERT_NE(-1, posLoc);

    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Step 2: Change max level and draw.
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedWriteDescriptorSetCount = getPerfCounters().writeDescriptorSets;

    // Step 3: Change max level back to original value and verify we hit the cache.
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t actualWriteDescriptorSetCount = getPerfCounters().writeDescriptorSets;
    EXPECT_EQ(expectedWriteDescriptorSetCount, actualWriteDescriptorSetCount);
}

// Tests that two glCopyBufferSubData commands can share a barrier.
TEST_P(VulkanPerformanceCounterTest, IndependentBufferCopiesShareSingleBarrier)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLint srcDataA[] = {1, 2, 3, 4};
    constexpr GLint srcDataB[] = {5, 6, 7, 8};

    // Step 1: Set up four buffers for two copies.
    GLBuffer srcA;
    glBindBuffer(GL_COPY_READ_BUFFER, srcA);
    // Note: We can't use GL_STATIC_COPY. Using STATIC will cause driver to allocate a host
    // invisible memory and issue a copyToBuffer, which will trigger outsideRenderPassCommandBuffer
    // flush when glCopyBufferSubData is called due to read after write. That will break the
    // expectations and cause test to fail.
    glBufferData(GL_COPY_READ_BUFFER, sizeof(srcDataA), srcDataA, GL_DYNAMIC_COPY);

    GLBuffer dstA;
    glBindBuffer(GL_COPY_WRITE_BUFFER, dstA);
    // Note: We can't use GL_STATIC_COPY. Using STATIC will cause driver to allocate a host
    // invisible memory and issue a copyToBuffer, which will trigger outsideRenderPassCommandBuffer
    // flush when glCopyBufferSubData is called due to write after write. That will break the
    // expectations and cause test to fail.
    glBufferData(GL_COPY_WRITE_BUFFER, sizeof(srcDataA[0]) * 2, nullptr, GL_DYNAMIC_COPY);

    GLBuffer srcB;
    glBindBuffer(GL_COPY_READ_BUFFER, srcB);
    glBufferData(GL_COPY_READ_BUFFER, sizeof(srcDataB), srcDataB, GL_DYNAMIC_COPY);

    GLBuffer dstB;
    glBindBuffer(GL_COPY_WRITE_BUFFER, dstB);
    glBufferData(GL_COPY_WRITE_BUFFER, sizeof(srcDataB[0]) * 2, nullptr, GL_DYNAMIC_COPY);

    // We expect that ANGLE generate zero additional command buffers.
    uint64_t expectedFlushCount = getPerfCounters().flushedOutsideRenderPassCommandBuffers;

    // Step 2: Do the two copies.
    glBindBuffer(GL_COPY_READ_BUFFER, srcA);
    glBindBuffer(GL_COPY_WRITE_BUFFER, dstA);
    glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, sizeof(srcDataB[0]), 0,
                        sizeof(srcDataA[0]) * 2);

    glBindBuffer(GL_COPY_READ_BUFFER, srcB);
    glBindBuffer(GL_COPY_WRITE_BUFFER, dstB);
    glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, sizeof(srcDataB[0]), 0,
                        sizeof(srcDataB[0]) * 2);

    ASSERT_GL_NO_ERROR();

    uint64_t actualFlushCount = getPerfCounters().flushedOutsideRenderPassCommandBuffers;
    EXPECT_EQ(expectedFlushCount, actualFlushCount);
}

// Test resolving a multisampled texture with blit doesn't break the render pass so a subpass can be
// used
TEST_P(VulkanPerformanceCounterTest_ES31, MultisampleResolveWithBlit)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr int kSize = 16;
    glViewport(0, 0, kSize, kSize);

    GLFramebuffer msaaFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
    glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
    ASSERT_GL_NO_ERROR();
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
                           0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
                     essl31_shaders::fs::RedGreenGradient());
    drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
    ASSERT_GL_NO_ERROR();

    // Create another FBO to resolve the multisample buffer into.
    GLTexture resolveTexture;
    GLFramebuffer resolveFBO;
    glBindTexture(GL_TEXTURE_2D, resolveTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));

    glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
    glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(getPerfCounters().resolveImageCommands, 0u);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
    constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
    EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
    EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
    EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
    EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
                      255, 1.0);
}

// Test resolving a multisampled texture with blit and then invalidate the msaa buffer
TEST_P(VulkanPerformanceCounterTest_ES31, ResolveToFBOWithInvalidate)
{
    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 0, 1, 0, &expected);
    expected.colorAttachmentResolves = getPerfCounters().colorAttachmentResolves + 1;

    constexpr int kWindowWidth  = 4;
    constexpr int kWindowHeight = 4;
    GLTexture resolveTexture;
    glBindTexture(GL_TEXTURE_2D, resolveTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWindowWidth, kWindowHeight, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    GLFramebuffer resolveFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);

    GLTexture msaaTexture;
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTexture);
    glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWindowWidth, kWindowHeight,
                              GL_FALSE);

    GLFramebuffer msaaFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, msaaFBO,
                           0);
    ANGLE_GL_PROGRAM(redprogram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    drawQuad(redprogram, essl1_shaders::PositionAttrib(), 0.5f);
    // Resolve into FBO
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
    glBlitFramebuffer(0, 0, kWindowWidth, kWindowHeight, 0, 0, kWindowWidth, kWindowHeight,
                      GL_COLOR_BUFFER_BIT, GL_NEAREST);

    GLenum attachment = GL_COLOR_ATTACHMENT0;
    glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, &attachment);
    glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);

    // Top-left pixels should be all red.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_EQ(expected.colorAttachmentResolves, getPerfCounters().colorAttachmentResolves);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);

    ASSERT_GL_NO_ERROR();
}

// Test resolving different attachments of an FBO to separate FBOs then invalidate
TEST_P(VulkanPerformanceCounterTest_ES31, MultisampleResolveBothAttachments)
{
    enum class Invalidate
    {
        AfterEachResolve,
        AllAtEnd,
    };

    constexpr char kFS[] = R"(#version 300 es
precision highp float;

uniform vec4 value0;
uniform vec4 value2;

layout(location = 0) out vec4 color0;
layout(location = 2) out vec4 color2;

void main()
{
    color0 = value0;
    color2 = value2;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    glUseProgram(program);
    const GLint color0Loc = glGetUniformLocation(program, "value0");
    const GLint color1Loc = glGetUniformLocation(program, "value2");

    constexpr int kWidth  = 16;
    constexpr int kHeight = 20;
    glViewport(0, 0, kWidth, kHeight);

    GLTexture msaa0, msaa1;
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaa0);
    glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, false);
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaa1);
    glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, false);

    GLFramebuffer msaaFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, msaa0,
                           0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D_MULTISAMPLE, msaa1,
                           0);
    ASSERT_GL_NO_ERROR();
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    GLenum bufs[3] = {GL_COLOR_ATTACHMENT0, GL_NONE, GL_COLOR_ATTACHMENT2};
    glDrawBuffers(3, bufs);

    // Create two resolve FBOs and textures. Use different texture levels and layers.
    GLTexture resolveTexture1;
    glBindTexture(GL_TEXTURE_2D, resolveTexture1);
    glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, kWidth * 2, kHeight * 2);

    GLFramebuffer resolveFBO1;
    glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 1);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    GLTexture resolveTexture2;
    glBindTexture(GL_TEXTURE_2D_ARRAY, resolveTexture2);
    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, GL_RGBA8, kWidth * 4, kHeight * 4, 5);

    GLFramebuffer resolveFBO2;
    glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
    glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, resolveTexture2, 2, 3);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    auto test = [&](GLColor color0, GLColor color1, Invalidate invalidate) {
        const GLenum discards[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT2};

        // Resolve attachments should be used and the MSAA attachments should be invalidated.
        // Only the resolve attachments should have Store.
        //
        // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+0, Stores+2, StoreNones+0)
        angle::VulkanPerfCounters expected;
        setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 0, 2, 0, &expected);
        expected.colorAttachmentResolves = getPerfCounters().colorAttachmentResolves + 2;

        glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
        glUniform4fv(color0Loc, 1, color0.toNormalizedVector().data());
        glUniform4fv(color1Loc, 1, color1.toNormalizedVector().data());
        drawQuad(program, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
        ASSERT_GL_NO_ERROR();

        // Resolve the first attachment
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO1);
        glReadBuffer(GL_COLOR_ATTACHMENT0);
        glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
                          GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        if (invalidate == Invalidate::AfterEachResolve)
        {
            glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, discards);
        }

        // Resolve the second attachment
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO2);
        glReadBuffer(GL_COLOR_ATTACHMENT2);
        glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
                          GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        if (invalidate == Invalidate::AfterEachResolve)
        {
            glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, discards + 1);
        }
        else if (invalidate == Invalidate::AllAtEnd)
        {
            glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, discards);
        }

        glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO1);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, color0);
        glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO2);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, color1);
        ASSERT_GL_NO_ERROR();

        EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
        EXPECT_EQ(expected.colorAttachmentResolves, getPerfCounters().colorAttachmentResolves);
        EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    };

    test(GLColor::blue, GLColor::yellow, Invalidate::AfterEachResolve);
    test(GLColor::cyan, GLColor::magenta, Invalidate::AllAtEnd);
}

// Test resolving the depth/stencil attachment
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps_ES31, MultisampleDepthStencilResolve)
{
    ANGLE_SKIP_TEST_IF(!hasDepthStencilResolveThroughAttachment());

    constexpr int kWidth  = 24;
    constexpr int kHeight = 12;
    glViewport(0, 0, kWidth, kHeight);

    GLFramebuffer msaaFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);

    GLRenderbuffer depthStencil;
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kWidth, kHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              depthStencil);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    // Create two resolve FBOs and textures. Use different texture levels and layers.
    GLTexture resolveTexture;
    glBindTexture(GL_TEXTURE_2D, resolveTexture);
    glTexStorage2D(GL_TEXTURE_2D, 4, GL_DEPTH24_STENCIL8, kWidth * 4, kHeight * 4);

    GLFramebuffer resolveFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
                           resolveTexture, 2);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    ANGLE_GL_PROGRAM(red, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());

    // Resolve attachment should be used and the MSAA attachment should be invalidated.
    // Only the resolve attachment should have Store.
    //
    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    angle::VulkanPerfCounters expected;
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 1, 0, &expected);
    expected.depthAttachmentResolves   = getPerfCounters().depthAttachmentResolves + 1;
    expected.stencilAttachmentResolves = getPerfCounters().stencilAttachmentResolves + 1;

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);
    glDepthMask(GL_TRUE);
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glStencilMask(0xFF);

    // Initialize the depth/stencil image
    glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
    drawQuad(red, essl1_shaders::PositionAttrib(), 0.3f);
    ASSERT_GL_NO_ERROR();

    // Resolve depth and stencil, then verify the results
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight,
                      GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);

    // Invalidate depth/stencil
    const GLenum discards[] = {GL_DEPTH_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, discards);

    // Break the render pass
    glFinish();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_EQ(expected.depthAttachmentResolves, getPerfCounters().depthAttachmentResolves);
    EXPECT_EQ(expected.stencilAttachmentResolves, getPerfCounters().stencilAttachmentResolves);
    EXPECT_DEPTH_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    ASSERT_GL_NO_ERROR();
}

// Ensures a read-only depth-stencil feedback loop works in a single RenderPass.
TEST_P(VulkanPerformanceCounterTest, ReadOnlyDepthStencilFeedbackLoopUsesSingleRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 4;

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());

    GLTexture colorTexture;
    glBindTexture(GL_TEXTURE_2D, colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    setupQuadVertexBuffer(0.5f, 1.0f);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    // Set up a depth texture and fill it with an arbitrary initial value.
    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, kSize, kSize, 0, GL_DEPTH_COMPONENT,
                 GL_UNSIGNED_INT, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);

    GLFramebuffer depthAndColorFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, depthAndColorFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    GLFramebuffer depthOnlyFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, depthOnlyFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw to a first FBO to initialize the depth buffer.
    glBindFramebuffer(GL_FRAMEBUFFER, depthOnlyFBO);
    glEnable(GL_DEPTH_TEST);
    glUseProgram(redProgram);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // Start new RenderPass with depth write disabled and no loop.
    glBindFramebuffer(GL_FRAMEBUFFER, depthAndColorFBO);
    glDepthMask(false);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Now set up the read-only feedback loop.
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glUseProgram(texProgram);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Tweak the bits to keep it read-only.
    glEnable(GL_DEPTH_TEST);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Render with just the depth attachment.
    glUseProgram(redProgram);
    glBindTexture(GL_TEXTURE_2D, 0);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Rebind the depth texture.
    glUseProgram(texProgram);
    glDepthMask(GL_FALSE);
    glEnable(GL_DEPTH_TEST);
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);

    // Do a final write to depth to make sure we can switch out of read-only mode.
    glBindTexture(GL_TEXTURE_2D, 0);
    glDepthMask(GL_TRUE);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();
}

// Ensures clear color buffer and read-only depth-stencil works in a single RenderPass (as seen in
// gfxbench manhattan).
TEST_P(VulkanPerformanceCounterTest, ClearColorBufferAndReadOnlyDepthStencilUsesSingleRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 4;

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());

    setupQuadVertexBuffer(0.5f, 1.0f);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    // Set up a depth texture and draw a quad to initialize it with known value.
    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, kSize, kSize, 0, GL_DEPTH_COMPONENT,
                 GL_UNSIGNED_INT, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);
    GLFramebuffer depthOnlyFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, depthOnlyFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);
    glDepthMask(GL_TRUE);
    glUseProgram(redProgram);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Setup a color texture and FBO with color and read only depth attachment.
    GLTexture colorTexture;
    glBindTexture(GL_TEXTURE_2D, colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    GLFramebuffer depthAndColorFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, depthAndColorFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;
    // First clear color buffer. This should not cause this render pass to switch to read only depth
    // stencil mode
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    // Now set up the read-only feedback loop.
    glDepthMask(GL_FALSE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glUseProgram(texProgram);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Render with just the depth attachment.
    glUseProgram(redProgram);
    glBindTexture(GL_TEXTURE_2D, 0);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Rebind the depth texture.
    glUseProgram(texProgram);
    glDepthMask(GL_FALSE);
    glEnable(GL_DEPTH_TEST);
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);

    // Do a final write to depth to make sure we can switch out of read-only mode.
    glBindTexture(GL_TEXTURE_2D, 0);
    glDepthMask(GL_TRUE);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();
}

// Similar scenario as in ClearColorBufferAndReadOnlyDepthStencilUsesSingleRenderPass based on
// Manhattan, but involving queries that end up marking a render pass for closure.  This results in
// the switch to read-only depth/stencil mode to flush the render pass twice.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       QueryThenClearColorBufferAndReadOnlyDepthStencilUsesSingleRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 4;

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());

    setupQuadVertexBuffer(0.5f, 1.0f);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    // Set up a depth texture and framebuffer.
    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, kSize, kSize, 0, GL_DEPTH_COMPONENT,
                 GL_UNSIGNED_INT, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    // Issue a draw call that writes to the depth image.  At the same time, end a query after the
    // draw call.  The end of query can mark the render pass for closure.
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);
    glDepthMask(GL_TRUE);
    glUseProgram(redProgram);
    GLQuery query;
    glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glEndQuery(GL_ANY_SAMPLES_PASSED);
    ASSERT_GL_NO_ERROR();

    // Add a color texture to the FBO.  This changes the render pass such that glClear isn't
    // translated to vkCmdClearAttachments (which it would, if the color attachment was added
    // earlier).
    GLTexture colorTexture;
    glBindTexture(GL_TEXTURE_2D, colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
    angle::VulkanPerfCounters expected;
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 0, 1, 0, &expected);

    // First clear the color buffer.  This leads to a deferred clear.
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    // Now set up the read-only feedback loop and issue a draw call.  The clear and draw should be
    // done in the same render pass.
    glDepthMask(GL_FALSE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glUseProgram(texProgram);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_DEPTH_OP_COUNTERS(getPerfCounters(), expected);
}

// Make sure depth/stencil clears followed by a switch to read-only mode still lets the color clears
// use loadOp=CLEAR optimally.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       SwitchToReadOnlyDepthStencilLeavesOtherAspectsOptimal)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 4;

    ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());

    setupQuadVertexBuffer(0.5f, 1.0f);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    // Set up a framebuffer.
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glTexStorage2D(GL_TEXTURE_2D, 2, GL_DEPTH24_STENCIL8, kSize * 2, kSize * 2);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthTexture,
                           1);

    GLTexture colorTexture;
    glBindTexture(GL_TEXTURE_2D, colorTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    // Expect rpCount+1, color(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    // depth(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+1),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    angle::VulkanPerfCounters expected;
    setExpectedCountersForColorOps(getPerfCounters(), 0, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 0, 1, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 1, 0, &expected);

    // Clear all aspects.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Then issue a draw call where the depth aspect is in feedback loop.  Depth should be cleared
    // before the render pass, but the color and stencil clears should still be optimized as loadOp.
    glDepthMask(GL_FALSE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glUseProgram(texProgram);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    glFinish();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_DEPTH_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Ensures an actual depth feedback loop (i.e, render and sample from same texture which is
// undefined behavior according to spec) works in a single RenderPass. This is adoptted from usage
// pattern from gangstar_vegas.
TEST_P(VulkanPerformanceCounterTest, DepthFeedbackLoopUsesSingleRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 4;

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());

    GLTexture colorTexture;
    glBindTexture(GL_TEXTURE_2D, colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    setupQuadVertexBuffer(0.5f, 1.0f);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    // Set up a depth texture and fill it with an arbitrary initial value.
    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, kSize, kSize, 0, GL_DEPTH_COMPONENT,
                 GL_UNSIGNED_INT, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, 0);

    GLFramebuffer depthAndColorFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, depthAndColorFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    GLFramebuffer depthOnlyFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, depthOnlyFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw to a first FBO to initialize the depth buffer.
    glBindFramebuffer(GL_FRAMEBUFFER, depthOnlyFBO);
    glEnable(GL_DEPTH_TEST);
    glUseProgram(redProgram);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // Start new RenderPass with depth write enabled and form the actual feedback loop.
    glBindFramebuffer(GL_FRAMEBUFFER, depthAndColorFBO);
    glDepthMask(true);
    glUseProgram(texProgram);
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Now set up the read-only feedback loop.
    glDepthMask(false);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);

    // Do a final write to depth to make sure we can switch out of read-only mode.
    glBindTexture(GL_TEXTURE_2D, 0);
    glDepthMask(GL_TRUE);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();
}

// Tests that invalidate followed by masked draws results in no load and store.
//
// - Scenario: invalidate, mask color, draw
TEST_P(VulkanPerformanceCounterTest, ColorInvalidateMaskDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    // Invalidate
    const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
    ASSERT_GL_NO_ERROR();

    // Mask color output
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

    // Draw
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass without color mask
    ++expected.renderPasses;
    ++expected.colorStoreOpStores;

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Test glFenceSync followed by glInvalidateFramebuffer should still allow storeOp being optimized
// out.
TEST_P(VulkanPerformanceCounterTest, FenceSyncAndColorInvalidate)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 0, 0, 0, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    // Draw
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Insert a fence which should trigger a deferred renderPass end
    GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

    // Invalidate FBO. This should still allow vulkan backend to optimize out the storeOp, even
    // though we just called glFenceSync .
    const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
    ASSERT_GL_NO_ERROR();

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
}
// Tests that invalidate followed by discarded draws results in no load and store.
//
// - Scenario: invalidate, rasterizer discard, draw
TEST_P(VulkanPerformanceCounterTest, ColorInvalidateDiscardDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    // Invalidate
    const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
    ASSERT_GL_NO_ERROR();

    // Mask color output
    glEnable(GL_RASTERIZER_DISCARD);

    // Draw
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass without color mask
    ++expected.renderPasses;
    ++expected.colorStoreOpStores;

    glDisable(GL_RASTERIZER_DISCARD);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that masked draws results in no load and store.
//
// - Scenario: mask color, draw
TEST_P(VulkanPerformanceCounterTest, ColorMaskedDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    // Initialize the color buffer
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Mask color output
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

    // Draw
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass without color mask
    ++expected.renderPasses;
    ++expected.colorLoadOpLoads;
    ++expected.colorStoreOpStores;

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that discarded draws results in no load and store.
//
// - Scenario: rasterizer discard, draw
TEST_P(VulkanPerformanceCounterTest, ColorDiscardDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    // Initialize the color buffer
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Mask color output
    glEnable(GL_RASTERIZER_DISCARD);

    // Draw
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass without color mask
    ++expected.renderPasses;
    ++expected.colorLoadOpLoads;
    ++expected.colorStoreOpStores;

    glDisable(GL_RASTERIZER_DISCARD);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Test that read-only color usage results in load but no store.
//
// - Scenario: mask color, framebuffer fetch draw
TEST_P(VulkanPerformanceCounterTest_ES31, ColorMaskedFramebufferFetchDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+1)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 0, 1, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    GLBuffer buffer;
    const GLColor kClearColor(40, 70, 100, 150);
    maskedFramebufferFetchDraw(kClearColor, buffer);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_NEAR(0, 0, kClearColor, 1);

    maskedFramebufferFetchDrawVerify(kClearColor, buffer);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that clear after masked draws is optimized to use loadOp
//
// - Scenario: clear, mask color, draw, clear
TEST_P(VulkanPerformanceCounterTest, ColorClearMaskedDrawThenClear)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    // No vkCmdClearAttachments should be issued.
    setExpectedCountersForColorOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    expected.colorClearAttachments = getPerfCounters().colorClearAttachments;

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    // Clear color first
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);

    // Mask color output
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

    // Draw
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Then clear color again.  This clear is moved up to loadOp, overriding the initial clear.
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glClearColor(0, 0, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_CLEAR_ATTACHMENTS_COUNTER(expected.colorClearAttachments,
                                     getPerfCounters().colorClearAttachments);
}

// Test that clear of read-only color is not reordered with the draw.
//
// - Scenario: mask color, framebuffer fetch draw, clear
TEST_P(VulkanPerformanceCounterTest_ES31, ColorMaskedFramebufferFetchDrawThenClear)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    // vkCmdClearAttachments should be used for the second clear.
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    expected.colorClearAttachments = getPerfCounters().colorClearAttachments + 1;

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    GLBuffer buffer;
    const GLColor kClearColor(40, 70, 100, 150);
    maskedFramebufferFetchDraw(kClearColor, buffer);

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    maskedFramebufferFetchDrawVerify(kClearColor, buffer);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_CLEAR_ATTACHMENTS_COUNTER(expected.colorClearAttachments,
                                     getPerfCounters().colorClearAttachments);
}

// Test that masked draw after a framebuffer fetch render pass doesn't load color.
//
// - Scenario: framebuffer fetch render pass, mask color, normal draw
TEST_P(VulkanPerformanceCounterTest_ES31, FramebufferFetchRenderPassThenColorMaskedDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+1)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 0, 1, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    GLBuffer buffer;
    const GLColor kClearColor(40, 70, 100, 150);
    maskedFramebufferFetchDraw(kClearColor, buffer);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_NEAR(0, 0, kClearColor, 1);

    maskedFramebufferFetchDrawVerify(kClearColor, buffer);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);

    // Start another render pass, and don't use framebuffer fetch.  Color is masked, so it should be
    // neither loaded nor stored.

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);

    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_NEAR(0, 0, kClearColor, 1);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that clear after unused depth/stencil is optimized to use loadOp
//
// - Scenario: disable depth/stencil, draw, clear
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilMaskedDrawThenClear)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    // disallowMixedDepthStencilLoadOpNoneAndLoad makes it quite complicated to set expectations
    // correct.
    ANGLE_SKIP_TEST_IF(hasSupportsTileMemoryOrSimulation() &&
                       hasDisallowMixedDepthStencilLoadOpNoneAndLoad());

    // This optimization is not implemented when this workaround is in effect.
    ANGLE_SKIP_TEST_IF(hasPreferDrawOverClearAttachments());

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 1, 0, &expected);

    // No vkCmdClearAttachments should be issued.
    expected.depthClearAttachments   = getPerfCounters().depthClearAttachments;
    expected.stencilClearAttachments = getPerfCounters().stencilClearAttachments;

    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupForDepthStencilOpsTest(&framebuffer, &texture, &renderbuffer);

    // Disable depth/stencil
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);

    // Issue a draw call
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);

    // Clear depth/stencil
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    if (hasSupportsTileMemoryOrSimulation())
    {
        // If tile memory is used, mid-renderPass clear will use draw instead of clear.
        expected.depthLoadOpClears   = 0;
        expected.stencilLoadOpClears = 0;
    }
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_CLEAR_ATTACHMENTS_COUNTER(expected.depthClearAttachments,
                                     getPerfCounters().depthClearAttachments);
    EXPECT_CLEAR_ATTACHMENTS_COUNTER(expected.stencilClearAttachments,
                                     getPerfCounters().depthClearAttachments);
}

// Tests that depth compare function change, get correct loadop for depth buffer
//
// - Scenario: depth test enabled, depth write mask = 0,
//   clear depth, draw red quad with compare function always,
//   and then  draw green quad with compare function less equal
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthFunctionDynamicChangeLoadOp)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    // This optimization is not implemented when this workaround is in effect.
    ANGLE_SKIP_TEST_IF(hasPreferDrawOverClearAttachments());

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupForColorDepthOpsTest(&framebuffer, &texture, &renderbuffer);

    // Clear color and depth.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // No depth write
    glDepthMask(GL_FALSE);
    // Depth function always
    glDepthFunc(GL_ALWAYS);

    // Draw read quad.
    ANGLE_GL_PROGRAM(redprogram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(redprogram, essl1_shaders::PositionAttrib(), 0.5f);

    // Depth function switch to less equal
    glDepthFunc(GL_LEQUAL);

    // Draw green quad.
    ANGLE_GL_PROGRAM(greenprogram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(greenprogram, essl1_shaders::PositionAttrib(), 0.7f);

    GLenum attachments = GL_DEPTH_ATTACHMENT;
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &attachments);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and check how many clears were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_CLEAR_ATTACHMENTS_COUNTER(expected.depthLoadOpClears,
                                     getPerfCounters().depthLoadOpClears);
}

// Tests that common PUBG MOBILE case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, disable, draw
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilInvalidateDisableDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);

    // Draw (since disabled, shouldn't change result)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 0, 0, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that alternative PUBG MOBILE case does not break render pass, and that counts are correct:
//
// - Scenario: disable, invalidate, draw
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DisableInvalidateDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);

    // Invalidate (storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Draw (since disabled, shouldn't change result)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 0, 0, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another case does not break render pass, and that counts are correct:
//
// - Scenario: disable, draw, invalidate, enable
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DisableDrawInvalidateEnable)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Note: setupClearAndDrawForDepthStencilOpsTest() did an enable and draw

    // Disable (since not invalidated, shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);

    // Draw (since not invalidated, shouldn't change result)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Enable (shouldn't change result)
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);
    // Note: The above enable calls will be ignored, since no drawing was done to force the enable
    // dirty bit to be processed

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass by reading back a pixel.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 0, 0, &expected);
    setAndIncrementDepthStencilStoreCountersForOpsTest(getPerfCounters(), 1, 0, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that common TRex case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilInvalidate)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 0, 0, &expected);
    setAndIncrementDepthStencilStoreCountersForOpsTest(getPerfCounters(), 1, 0, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Similar to Invalidate, but uses glInvalidateSubFramebuffer such that the given area covers the
// whole framebuffer.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilInvalidateSub)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateSubFramebuffer(GL_FRAMEBUFFER, 2, discards, -100, -100, kOpsTestSize + 200,
                               kOpsTestSize + 200);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 0, 0, &expected);
    setAndIncrementDepthStencilStoreCountersForOpsTest(getPerfCounters(), 1, 0, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Similar to InvalidateSub, but uses glInvalidateSubFramebuffer such that the given area does NOT
// covers the whole framebuffer.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilPartialInvalidateSub)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    // disallowMixedDepthStencilLoadOpNoneAndLoad makes it quite complicated to set expectations
    // correct.
    ANGLE_SKIP_TEST_IF(hasSupportsTileMemoryOrSimulation() &&
                       hasDisallowMixedDepthStencilLoadOpNoneAndLoad());

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 1, 0, &expected);

    // Create the framebuffer and make sure depth/stencil have valid contents.
    ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&drawRed, &framebuffer, &texture, &renderbuffer, true);

    // Break the render pass so depth/stencil values are stored.
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start a new render pass that is scissored.  Depth/stencil should be loaded.  The draw call is
    // followed by an invalidate, so store shouldn't happen.

    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 1, 0, 0, 0, &expected);

    glEnable(GL_SCISSOR_TEST);
    glScissor(kOpsTestSize / 8, kOpsTestSize / 4, kOpsTestSize / 2, kOpsTestSize / 3);

    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
    glDepthFunc(GL_ALWAYS);

    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateSubFramebuffer(GL_FRAMEBUFFER, 2, discards, kOpsTestSize / 8, kOpsTestSize / 8,
                               7 * kOpsTestSize / 8, 7 * kOpsTestSize / 8);

    // Break the render pass so depth/stencil values are discarded.
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::green);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start another render pass without scissor.  Because parts of the framebuffer attachments were
    // not invalidated, depth/stencil should be loaded.

    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 1, 0, 1, 0, &expected);

    glDisable(GL_SCISSOR_TEST);

    ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Verify results
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, draw
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilInvalidateDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, draw, disable
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilInvalidateDrawDisable)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    // http://anglebug.com/40096809
    ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
    // Note: this draw is just so that the disable dirty bits will be processed
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and then check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 1, 1, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, disable, draw, enable
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthStencilInvalidateDisableDrawEnable)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);

    // Draw (since disabled, shouldn't change result)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Enable (shouldn't change result)
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);
    // Note: The above enable calls will be ignored, since no drawing was done to force the enable
    // dirty bit to be processed

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 0, 0, &expected);
    setAndIncrementDepthStencilStoreCountersForOpsTest(getPerfCounters(), 1, 0, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, disable, draw, enable, draw
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthStencilInvalidateDisableDrawEnableDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    // disallowMixedDepthStencilLoadOpNoneAndLoad makes it quite complicated to set expectations
    // correct.
    ANGLE_SKIP_TEST_IF(hasSupportsTileMemoryOrSimulation() &&
                       hasDisallowMixedDepthStencilLoadOpNoneAndLoad());

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 1, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);

    // Draw (since disabled, shouldn't change result)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Enable (shouldn't change result)
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

    // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and then check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 1, 1, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, draw, disable, enable
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthStencilInvalidateDrawDisableEnable)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
    // Note: this draw is just so that the disable dirty bits will be processed
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Enable (shouldn't change result)
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);
    // Note: The above enable calls will be ignored, since no drawing was done to force the enable
    // dirty bit to be processed

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Break the render pass and then check how many loads and stores were actually done
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    // setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 1, 0, &expected);
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, draw, disable, enable, invalidate
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthStencilInvalidateDrawDisableEnableInvalidate)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
    // Note: this draw is just so that the disable dirty bits will be processed
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Enable (shouldn't change result)
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 0, 0, &expected);
    setAndIncrementDepthStencilStoreCountersForOpsTest(getPerfCounters(), 1, 0, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, draw, disable, enable, invalidate, draw
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthStencilInvalidateDrawDisableEnableInvalidateDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
    // Note: this draw is just so that the disable dirty bits will be processed
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Enable (shouldn't change result)
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    setAndIncrementDepthStencilStoreCountersForOpsTest(getPerfCounters(), 1, 0, &expected);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that another common (dEQP) case does not break render pass, and that counts are correct:
//
// - Scenario: invalidate, disable, enable, draw
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthStencilInvalidateDisableEnableDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Execute the scenario that this test is for:

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Disable (shouldn't change result)
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
    // Note: this draw is just so that the disable dirty bits will be processed
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Enable (shouldn't change result)
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Ensure that the render pass wasn't broken
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that an in renderpass clear after invalidate keeps content stored.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilInvalidateAndClear)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    // Clear should vkCmdClearAttachments
    expected.depthClearAttachments = getPerfCounters().depthClearAttachments + 1;

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, false);

    // Disable depth test but with depth mask enabled so that clear should still work.
    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Do in-renderpass clear. This should result in StoreOp=STORE; mContentDefined = true.
    glClearDepthf(1.0f);
    glClear(GL_DEPTH_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
    if (getPerfCounters().fallbackFromTileMemory > 0)
    {
        // Mid-renderPass clear will use draw instead of clearAttachments
        expected.depthClearAttachments = 0;
    }
    EXPECT_CLEAR_ATTACHMENTS_COUNTER(expected.depthClearAttachments,
                                     getPerfCounters().depthClearAttachments);

    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    // Bind FBO again and try to use the depth buffer without clear. This should result in
    // loadOp=LOAD and StoreOP=STORE
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glDisable(GL_STENCIL_TEST);
    ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    // Should pass depth test: (0.5+1.0)/2.0=0.75 < 1.0
    drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::blue);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that the draw path for clear after invalidate and disabling depth/stencil test keeps
// content stored.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthStencilInvalidateAndMaskedClear)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    // disallowMixedDepthStencilLoadOpNoneAndLoad makes it quite complicated to set expectations
    // correct.
    ANGLE_SKIP_TEST_IF(hasSupportsTileMemoryOrSimulation() &&
                       hasDisallowMixedDepthStencilLoadOpNoneAndLoad());

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 1, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer, true);

    // Invalidate (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Disable depth/stencil test but make stencil masked
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);
    glDepthMask(GL_TRUE);
    glStencilMask(0xF0);

    // Enable scissor for the draw path to be taken.
    glEnable(GL_SCISSOR_TEST);
    glScissor(kOpsTestSize / 4, kOpsTestSize / 4, kOpsTestSize / 2, kOpsTestSize / 2);

    // Do in-renderpass clear. This should result in StoreOp=STORE
    glClearDepthf(1.0f);
    glClearStencil(0x55);
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    ASSERT_GL_NO_ERROR();

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+1)
    // Note that depth write is enabled, while stencil is disabled.
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 1, 0, 0, 1, &expected);

    // Bind FBO again and try to use the depth buffer without clear. This should result in
    // loadOp=LOAD and StoreOP=STORE
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_EQUAL, 0x50, 0xF0);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(0xFF);
    ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.95f);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::blue);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that the renderpass is using depthFunc(GL_ALWAYS) and depthMask(GL_FALSE), it should not
// load or store depth value.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthFuncALWAYSWithDepthMaskDisabledShouldNotLoadStore)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    // disallowMixedDepthStencilLoadOpNoneAndLoad makes it quite complicated to set expectations
    // correct.
    ANGLE_SKIP_TEST_IF(hasSupportsTileMemoryOrSimulation() &&
                       hasDisallowMixedDepthStencilLoadOpNoneAndLoad());

    angle::VulkanPerfCounters expected;

    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupForDepthStencilOpsTest(&framebuffer, &texture, &renderbuffer);

    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 0, 1, 0, &expected);
    if (hasDisallowMixedDepthStencilLoadOpNoneAndLoad())
    {
        // stencil(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+1)
        setExpectedCountersForStencilOps(getPerfCounters(), 0, 1, 0, 0, 1, &expected);
    }
    else
    {
        // stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
        setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);
    }
    // Initialize the buffers with known value
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_ALWAYS);
    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.95f);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::red);
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1),
    //                 stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);
    glDepthFunc(GL_ALWAYS);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.95f);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::red);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that the renderpass is using depthFunc(GL_ALWAYS) and depthMask(GL_FALSE) and draw. Then it
// followed by glClear, it should not load or store depth value.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthFuncALWAYSWithDepthMaskDisabledThenClearShouldNotLoadStore)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    // disallowMixedDepthStencilLoadOpNoneAndLoad makes it quite complicated to set expectations
    // correct.
    ANGLE_SKIP_TEST_IF(hasDisallowMixedDepthStencilLoadOpNoneAndLoad());
    // This test is tricky to get expectations right with combination of nones and tile memory
    // support.
    ANGLE_SKIP_TEST_IF(hasSupportsTileMemoryOrSimulation() && !hasLoadOpNoneSupport());

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupForDepthStencilOpsTest(&framebuffer, &texture, &renderbuffer);

    // Initialize the buffers with known value
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_ALWAYS);
    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.95f);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::red);
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    if (hasPreferDrawOverClearAttachments())
    {
        // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
        setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    }
    else
    {
        // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
        setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    }
    // Expect stencil(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 1, 0, &expected);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);
    glDepthFunc(GL_ALWAYS);
    glEnable(GL_STENCIL_TEST);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.95f);
    glDepthMask(GL_TRUE);
    glClearDepthf(1);
    glClearStencil(0);
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glDepthFunc(GL_LEQUAL);
    glDepthMask(GL_FALSE);
    glEnable(GL_STENCIL_TEST);
    glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, 255);
    glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 255);
    glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(255);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.9f);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::red);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that the renderpass is using depthFunc(GL_NEVER) and depthMask(GL_FALSE), it should not
// load or store depth value.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthFuncNEVERWithDepthMaskDisabledShouldNotLoadStore)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupForDepthStencilOpsTest(&framebuffer, &texture, &renderbuffer);

    // Initialize the buffers with known value
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_ALWAYS);
    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.95f);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::red);

    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1),
    //                 stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);
    glDepthFunc(GL_NEVER);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.95f);
    EXPECT_PIXEL_COLOR_EQ(kOpsTestSize / 2, kOpsTestSize / 2, GLColor::red);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests whether depth-stencil ContentDefined will be correct when:
//
// - Scenario: invalidate, detach D/S texture and modify it, attach D/S texture, draw with blend
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthStencilInvalidateDetachModifyTexAttachDrawWithBlend)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    GLTexture colorTexture;
    glBindTexture(GL_TEXTURE_2D, colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);

    GLTexture depthStencilTexture;
    glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 2, 2, 0, GL_DEPTH_STENCIL,
                 GL_UNSIGNED_INT_24_8, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
                           depthStencilTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Clear and draw with depth-stencil enabled
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);
    glClearDepthf(0.99f);
    glEnable(GL_STENCIL_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Invalidate depth & stencil (should result: in storeOp = DONT_CARE; mContentDefined = false)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Check for the expected number of render passes, expected color, and other expected counters
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Detach depth-stencil attachment
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Modify depth-stencil
    constexpr uint32_t kDepthStencilInitialValue = 0xafffff00;
    uint32_t depthStencilData[4] = {kDepthStencilInitialValue, kDepthStencilInitialValue,
                                    kDepthStencilInitialValue, kDepthStencilInitialValue};
    glBindTexture(GL_TEXTURE_2D, depthStencilTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 2, 2, 0, GL_DEPTH_STENCIL,
                 GL_UNSIGNED_INT_24_8, depthStencilData);

    // Re-attach depth-stencil
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
                           depthStencilTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Draw again, showing that the modified depth-stencil value prevents a new color value
    //
    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+1)
    // Note that depth write is enabled, while stencil is disabled.
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 1, 0, 0, 1, &expected);
    drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    // Check for the expected number of render passes, expected color, and other expected counters
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Draw again, using a different depth value, so that the drawing takes place
    //
    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 1, 0, 0, 1, &expected);
    drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.2f);
    ASSERT_GL_NO_ERROR();
    // Check for the expected number of render passes, expected color, and other expected counters
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that a GLRenderbuffer can be deleted before the render pass ends, and that everything
// still works.
//
// - Scenario: invalidate
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       DepthStencilInvalidateDrawAndDeleteRenderbuffer)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    GLFramebuffer framebuffer;
    GLTexture texture;
    {
        // Declare the RAII-based GLRenderbuffer object within this set of curly braces, so that it
        // will be deleted early (at the close-curly-brace)
        GLRenderbuffer renderbuffer;
        setupClearAndDrawForDepthStencilOpsTest(&program, &framebuffer, &texture, &renderbuffer,
                                                false);

        // Invalidate (storeOp = DONT_CARE; mContentDefined = false)
        const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
        glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
        ASSERT_GL_NO_ERROR();

        // Draw (since enabled, should result: in storeOp = STORE; mContentDefined = true)
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
        ASSERT_GL_NO_ERROR();

        // Ensure that the render pass wasn't broken
        EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    }

    // The renderbuffer should now be deleted.

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Start and end another render pass, to check that the load ops are as expected
    setAndIncrementDepthStencilLoadCountersForOpsTest(getPerfCounters(), 0, 0, &expected);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    swapBuffers();
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
}

// Test that disabling color buffer after clear continues to use loadOp for it.
//
// - Scenario: clear color and depth, disable color, draw, enable color, draw
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps_ES31,
       ColorDisableThenDrawThenEnableThenDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupForColorDepthOpsTest(&framebuffer, &texture, &renderbuffer);

    // Expected:
    //   rpCount+1,
    //   depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    //   color(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 0, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForColorOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);

    // Clear color and depth first
    glClearColor(1, 0, 0, 1);
    glClearDepthf(0.123);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Disable color output
    GLenum drawBuffers[] = {GL_NONE};
    glDrawBuffers(1, drawBuffers);

    // Issue a draw call, only affecting depth
    glDepthFunc(GL_ALWAYS);
    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.75f);

    // Enable color output
    drawBuffers[0] = GL_COLOR_ATTACHMENT0;
    glDrawBuffers(1, drawBuffers);

    // Issue another draw call, verifying depth simultaneously
    glDepthFunc(GL_LESS);
    ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.74f);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Verify results and check how many loads and stores were actually done.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_OP_COUNTERS(getPerfCounters(), expected);
    ASSERT_GL_NO_ERROR();
}

// Tests that even if the app clears depth, it should be invalidated if there is no read.
TEST_P(VulkanPerformanceCounterTest, SwapShouldInvalidateDepthAfterClear)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    // Clear depth.
    glClear(GL_DEPTH_BUFFER_BIT);

    // Ensure we never read from depth.
    glDisable(GL_DEPTH_TEST);

    // Do one draw, then swap.
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedDepthClears = getPerfCounters().depthLoadOpClears;

    swapBuffers();

    uint64_t actualDepthClears = getPerfCounters().depthLoadOpClears;
    EXPECT_EQ(expectedDepthClears, actualDepthClears);
}

// Tests that masked color clears don't break the RP.
TEST_P(VulkanPerformanceCounterTest, MaskedColorClearDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // Mask color channels and clear the framebuffer multiple times.
    glClearColor(0.25f, 0.25f, 0.25f, 0.25f);
    glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
    glClear(GL_COLOR_BUFFER_BIT);

    glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
    glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
    glClear(GL_COLOR_BUFFER_BIT);

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
    glClear(GL_COLOR_BUFFER_BIT);

    glClearColor(0.75f, 0.75f, 0.75f, 0.75f);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
    glClear(GL_COLOR_BUFFER_BIT);

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);

    EXPECT_PIXEL_NEAR(0, 0, 63, 127, 255, 191, 1);
}

// Tests that masked color/depth/stencil clears don't break the RP.
TEST_P(VulkanPerformanceCounterTest, MaskedClearDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 64;

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer renderbuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              renderbuffer);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor());
    glUseProgram(program);
    GLint colorUniformLocation =
        glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(-1, colorUniformLocation);
    ASSERT_GL_NO_ERROR();

    // Clear the framebuffer with a draw call to start a render pass.
    glViewport(0, 0, kSize, kSize);
    glDepthFunc(GL_ALWAYS);
    glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f);

    // Issue a masked clear.
    glClearColor(0.25f, 1.0f, 0.25f, 1.25f);
    glClearDepthf(0.0f);
    glClearStencil(0x3F);
    glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
    glStencilMask(0xF0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Make sure the render pass wasn't broken.
    EXPECT_EQ(expectedRenderPassCount, getPerfCounters().renderPasses);

    // Verify that clear was done correctly.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::yellow);

    glDisable(GL_SCISSOR_TEST);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glStencilMask(0xFF);

    // Make sure depth = 0.0f, stencil = 0x35
    glDepthFunc(GL_GREATER);
    glStencilFunc(GL_EQUAL, 0x35, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.05f);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::blue);
}

// Tests that clear followed by scissored draw uses loadOp to clear.
TEST_P(VulkanPerformanceCounterTest, ClearThenScissoredDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;
    uint64_t expectedDepthClears     = getPerfCounters().depthLoadOpClears + 1;
    uint64_t expectedStencilClears   = getPerfCounters().stencilLoadOpClears + 1;

    constexpr GLsizei kSize = 64;

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer renderbuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              renderbuffer);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    // Clear depth/stencil
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(1.0f);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Issue a scissored draw call, expecting depth/stencil to be 1.0 and 0x55.
    glViewport(0, 0, kSize, kSize);
    glScissor(0, 0, kSize / 2, kSize);
    glEnable(GL_SCISSOR_TEST);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_EQUAL, 0x55, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(0xFF);

    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.95f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass.
    GLTexture copyTex;
    glBindTexture(GL_TEXTURE_2D, copyTex);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, kSize, kSize, 0);
    ASSERT_GL_NO_ERROR();

    // Make sure a single render pass was used and depth/stencil clear used loadOp=CLEAR.
    EXPECT_EQ(expectedRenderPassCount, getPerfCounters().renderPasses);
    EXPECT_EQ(expectedDepthClears, getPerfCounters().depthLoadOpClears);
    EXPECT_EQ(expectedStencilClears, getPerfCounters().stencilLoadOpClears);

    // Verify correctness.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, kSize - 1, GLColor::green);

    EXPECT_PIXEL_COLOR_EQ(kSize / 2, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
}

// Tests that scissored clears don't break the RP.
TEST_P(VulkanPerformanceCounterTest, ScissoredClearDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 64;

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer renderbuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              renderbuffer);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor());
    glUseProgram(program);
    GLint colorUniformLocation =
        glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(-1, colorUniformLocation);
    ASSERT_GL_NO_ERROR();

    // Clear the framebuffer with a draw call to start a render pass.
    glViewport(0, 0, kSize, kSize);
    glDepthFunc(GL_ALWAYS);
    glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f);

    // Issue a scissored clear.
    glEnable(GL_SCISSOR_TEST);
    glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClearDepthf(0.0f);
    glClearStencil(0x3F);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Make sure the render pass wasn't broken.
    EXPECT_EQ(expectedRenderPassCount, getPerfCounters().renderPasses);

    // Verify that clear was done correctly.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);

    EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::green);

    glDisable(GL_SCISSOR_TEST);

    // Make sure the border has depth = 1.0f, stencil = 0x55
    glDepthFunc(GL_LESS);
    glStencilFunc(GL_EQUAL, 0x55, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.95f);
    ASSERT_GL_NO_ERROR();

    // Make sure the center has depth = 0.0f, stencil = 0x3F
    glDepthFunc(GL_GREATER);
    glStencilFunc(GL_EQUAL, 0x3F, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.05f);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);

    EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::magenta);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::magenta);
}

// Tests that draw buffer change with all color channel mask off should not break renderpass
TEST_P(VulkanPerformanceCounterTest, DrawbufferChangeWithAllColorMaskDisabled)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor());
    glUseProgram(program);
    GLint colorUniformLocation =
        glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(-1, colorUniformLocation);
    ASSERT_GL_NO_ERROR();

    GLTexture textureRGBA;
    glBindTexture(GL_TEXTURE_2D, textureRGBA);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    GLTexture textureDepth;
    glBindTexture(GL_TEXTURE_2D, textureDepth);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 64, 64, 0, GL_DEPTH_COMPONENT,
                 GL_UNSIGNED_INT, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureRGBA, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureDepth, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // Draw into FBO
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);  // clear to green
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, 256, 256);
    glUniform4fv(colorUniformLocation, 1, GLColor::blue.toNormalizedVector().data());
    GLenum glDrawBuffers_bufs_1[] = {GL_COLOR_ATTACHMENT0};
    glDrawBuffers(1, glDrawBuffers_bufs_1);
    glEnable(GL_DEPTH_TEST);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    // Change draw buffer state and color mask
    GLenum glDrawBuffers_bufs_0[] = {GL_NONE};
    glDrawBuffers(1, glDrawBuffers_bufs_0);
    glColorMask(false, false, false, false);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.6f);
    // Change back draw buffer state and color mask
    glDrawBuffers(1, glDrawBuffers_bufs_1);
    glColorMask(true, true, true, true);
    glUniform4fv(colorUniformLocation, 1, GLColor::red.toNormalizedVector().data());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.7f);

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Tests the optimization that a glFlush call issued inside a renderpass will be skipped.
TEST_P(VulkanPerformanceCounterTest, InRenderpassFlushShouldNotBreakRenderpass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    glFlush();
    ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Tests switch from query enabled draw to query disabled draw should break renderpass (so that wait
// for query result will be available sooner).
TEST_P(VulkanPerformanceCounterTest,
       SwitchFromQueryEnabledDrawToQueryDisabledDrawShouldBreakRenderpass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    uint64_t renderPassCountBefore = getPerfCounters().renderPasses;

    GLQueryEXT query1, query2;
    // Draw inside query
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query1);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query2);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);
    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    // Draw outside his query
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.8f, 0.5f);

    GLuint results[2];
    // will block waiting for result
    glGetQueryObjectuivEXT(query1, GL_QUERY_RESULT_EXT, &results[0]);
    glGetQueryObjectuivEXT(query2, GL_QUERY_RESULT_EXT, &results[1]);
    EXPECT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses - renderPassCountBefore;
    if (hasSupportsTileMemoryOrSimulation() ||
        !isFeatureEnabled(Feature::PreferSubmitOnAnySamplesPassedQueryEnd))
    {
        // When tile memory is used we may not submit if depthStencil has valid data.
        EXPECT_EQ(1ul, actualRenderPassCount);
    }
    else
    {
        EXPECT_EQ(2ul, actualRenderPassCount);
    }
}

// Tests that depth/stencil texture clear/load works correctly.
TEST_P(VulkanPerformanceCounterTest, DepthStencilTextureClearAndLoad)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    // TODO: http://anglebug.com/42263870 Flaky test
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());

    uint64_t expectedDepthClearCount   = getPerfCounters().depthLoadOpClears + 1;
    uint64_t expectedDepthLoadCount    = getPerfCounters().depthLoadOpLoads + 3;
    uint64_t expectedStencilClearCount = getPerfCounters().stencilLoadOpClears + 1;
    uint64_t expectedStencilLoadCount  = getPerfCounters().stencilLoadOpLoads + 3;

    constexpr GLsizei kSize = 6;

    // Create framebuffer to draw into, with both color and depth attachments.
    GLTexture color;
    glBindTexture(GL_TEXTURE_2D, color);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLTexture depth;
    glBindTexture(GL_TEXTURE_2D, depth);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, kSize, kSize, 0, GL_DEPTH_STENCIL,
                 GL_UNSIGNED_INT_24_8_OES, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
    ASSERT_GL_NO_ERROR();

    // Set up texture for copy operation that breaks the render pass
    GLTexture copyTex;
    glBindTexture(GL_TEXTURE_2D, copyTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    // Set viewport and clear depth/stencil
    glViewport(0, 0, kSize, kSize);
    glClearDepthf(1);
    glClearStencil(0x55);
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // If depth is not cleared to 1, rendering would fail.
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glDepthMask(GL_FALSE);

    // If stencil is not clear to 0x55, rendering would fail.
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_EQUAL, 0x55, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(0xFF);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw red
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw green
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw blue
    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, kSize / 2, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw yellow
    glUniform4f(colorUniformLocation, 1.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, kSize / 2, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Verify the counters
    EXPECT_EQ(getPerfCounters().depthLoadOpClears, expectedDepthClearCount);
    EXPECT_EQ(getPerfCounters().depthLoadOpLoads, expectedDepthLoadCount);
    EXPECT_EQ(getPerfCounters().stencilLoadOpClears, expectedStencilClearCount);
    EXPECT_EQ(getPerfCounters().stencilLoadOpLoads, expectedStencilLoadCount);

    // Verify that copies were done correctly.
    GLFramebuffer verifyFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, verifyFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyTex, 0);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, kSize / 2, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::yellow);
}

// Tests that multisampled-render-to-texture depth/stencil textures don't ever load data.
TEST_P(VulkanPerformanceCounterTest, RenderToTextureDepthStencilTextureShouldNotLoad)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    // http://anglebug.com/42263651
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());

    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));

    uint64_t expectedDepthClearCount   = getPerfCounters().depthLoadOpClears + 1;
    uint64_t expectedDepthLoadCount    = getPerfCounters().depthLoadOpLoads;
    uint64_t expectedStencilClearCount = getPerfCounters().stencilLoadOpClears + 1;
    uint64_t expectedStencilLoadCount  = getPerfCounters().stencilLoadOpLoads;

    constexpr GLsizei kSize = 6;

    // Create multisampled framebuffer to draw into, with both color and depth attachments.
    GLTexture colorMS;
    glBindTexture(GL_TEXTURE_2D, colorMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLTexture depthMS;
    glBindTexture(GL_TEXTURE_2D, depthMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, kSize, kSize, 0, GL_DEPTH_STENCIL,
                 GL_UNSIGNED_INT_24_8_OES, nullptr);

    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         colorMS, 0, 4);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
                                         depthMS, 0, 4);
    ASSERT_GL_NO_ERROR();

    // Set up texture for copy operation that breaks the render pass
    GLTexture copyTex;
    glBindTexture(GL_TEXTURE_2D, copyTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    // Set viewport and clear depth
    glViewport(0, 0, kSize, kSize);
    glClearDepthf(1);
    glClearStencil(0x55);
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // If depth is not cleared to 1, rendering would fail.
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    // If stencil is not clear to 0x55, rendering would fail.
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_EQUAL, 0x55, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(0xFF);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw red
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw green
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw blue
    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, kSize / 2, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw yellow
    glUniform4f(colorUniformLocation, 1.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, kSize / 2, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Verify the counters
    EXPECT_EQ(getPerfCounters().depthLoadOpClears, expectedDepthClearCount);
    EXPECT_EQ(getPerfCounters().depthLoadOpLoads, expectedDepthLoadCount);
    EXPECT_EQ(getPerfCounters().stencilLoadOpClears, expectedStencilClearCount);
    EXPECT_EQ(getPerfCounters().stencilLoadOpLoads, expectedStencilLoadCount);

    // Verify that copies were done correctly.  Only the first copy can be verified because the
    // contents of the depth/stencil buffer is undefined after the first render pass break, meaning
    // it is unknown whether the three subsequent draw calls passed the depth or stencil tests.
    GLFramebuffer verifyFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, verifyFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyTex, 0);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(0, kSize / 2 - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, kSize / 2 - 1, GLColor::red);
}

// Tests that multisampled-render-to-texture depth/stencil renderbuffers don't ever load
// depth/stencil data.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       RenderToTextureDepthStencilRenderbufferShouldNotLoad)
{
    // http://anglebug.com/42263651
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());
    // http://anglebug.com/42263920
    ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());

    // http://crbug.com/1134286
    ANGLE_SKIP_TEST_IF(IsWindows7() && IsNVIDIA() && IsVulkan());

    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // This test creates 4 render passes. In the first render pass, color, depth and stencil are
    // cleared.  In the following render passes, they must be loaded.  However, given that the
    // attachments are multisampled-render-to-texture, loads are done through an unresolve
    // operation.  All 4 render passes resolve the attachments.

    // Expect rpCount+4, depth(Clears+1, Loads+3, LoadNones+0, Stores+3, StoreNones+0),
    // stencil(Clears+1, Loads+3, LoadNones+0, Stores+3, StoreNones+0). Note that the Loads and
    // Stores are from the resolve attachments.
    setExpectedCountersForDepthOps(getPerfCounters(), 4, 1, 3, 0, 3, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 3, 0, 3, 0, &expected);

    // Additionally, expect 4 resolves and 3 unresolves.
    setExpectedCountersForUnresolveResolveTest(getPerfCounters(), 3, 3, 3, 4, 4, 4, &expected);

    constexpr GLsizei kSize = 6;

    // Create multisampled framebuffer to draw into, with both color and depth attachments.
    GLTexture colorMS;
    glBindTexture(GL_TEXTURE_2D, colorMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer depthStencilMS;
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencilMS);
    glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);

    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         colorMS, 0, 4);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              depthStencilMS);
    ASSERT_GL_NO_ERROR();

    // Set up texture for copy operation that breaks the render pass
    GLTexture copyTex;
    glBindTexture(GL_TEXTURE_2D, copyTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    // Set viewport and clear color, depth and stencil
    glViewport(0, 0, kSize, kSize);
    glClearDepthf(1);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // If depth is not cleared to 1, rendering would fail.
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    // If stencil is not clear to 0x55, rendering would fail.
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_EQUAL, 0x55, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(0xFF);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw red
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.75f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw green
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw blue
    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.25f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, kSize / 2, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw yellow
    glUniform4f(colorUniformLocation, 1.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, kSize / 2, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Verify the counters
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_COUNTERS_FOR_UNRESOLVE_RESOLVE_TEST(getPerfCounters(), expected);

    // Verify that copies were done correctly.
    GLFramebuffer verifyFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, verifyFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyTex, 0);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, kSize / 2, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::yellow);
}

// Tests counters when multisampled-render-to-texture color/depth/stencil renderbuffers are
// invalidated.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, RenderToTextureInvalidate)
{
    // http://anglebug.com/42263651
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());

    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));

    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // This test creates 4 render passes. In the first render pass, color, depth and stencil are
    // cleared.  After every render pass, the attachments are invalidated.  In the following render
    // passes thus they are not loaded (rather unresolved, as the attachments are
    // multisampled-render-to-texture).  Due to the invalidate call, neither of the 4 render passes
    // should resolve the attachments.

    // Expect rpCount+4, color(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 4, 1, 0, 0, 0, 0, &expected);
    // Expect rpCount+4, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 4, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 0, 0, &expected);

    // Additionally, expect no resolve and unresolve.
    setExpectedCountersForUnresolveResolveTest(getPerfCounters(), 0, 0, 0, 0, 0, 0, &expected);

    constexpr GLsizei kSize = 6;

    // Create multisampled framebuffer to draw into, with both color and depth attachments.
    GLTexture colorMS;
    glBindTexture(GL_TEXTURE_2D, colorMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer depthStencilMS;
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencilMS);
    glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);

    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         colorMS, 0, 4);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              depthStencilMS);
    ASSERT_GL_NO_ERROR();

    // Set up texture for copy operation that breaks the render pass
    GLTexture copyTex;
    glBindTexture(GL_TEXTURE_2D, copyTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    // Set viewport and clear color, depth and stencil
    glViewport(0, 0, kSize, kSize);
    glClearColor(0, 0, 0, 1.0f);
    glClearDepthf(1);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Output depth/stencil, but disable testing so all draw calls succeed
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glStencilMask(0xFF);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw red
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.75f);
    ASSERT_GL_NO_ERROR();

    // Invalidate everything
    const GLenum discards[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, discards);

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw green
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Invalidate everything
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, discards);

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw blue
    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.25f);
    ASSERT_GL_NO_ERROR();

    // Invalidate everything
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, discards);

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, kSize / 2, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Draw yellow
    glUniform4f(colorUniformLocation, 1.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Invalidate everything
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, discards);

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, kSize / 2, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Verify the counters
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_COUNTERS_FOR_UNRESOLVE_RESOLVE_TEST(getPerfCounters(), expected);
}

// Tests counters when uninitialized multisampled-render-to-texture depth/stencil renderbuffers are
// unused but not invalidated.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       RenderToTextureUninitializedAndUnusedDepthStencil)
{
    // http://anglebug.com/42263651
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());

    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));

    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, no depth/stencil clear, load or store.
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    // Additionally, expect only color resolve.
    setExpectedCountersForUnresolveResolveTest(getPerfCounters(), 0, 0, 0, 1, 0, 0, &expected);

    constexpr GLsizei kSize = 6;

    // Create multisampled framebuffer to draw into, with both color and depth attachments.
    GLTexture colorMS;
    glBindTexture(GL_TEXTURE_2D, colorMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer depthStencilMS;
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencilMS);
    glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);

    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         colorMS, 0, 4);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              depthStencilMS);
    ASSERT_GL_NO_ERROR();

    // Set up texture for copy operation that breaks the render pass
    GLTexture copyTex;
    glBindTexture(GL_TEXTURE_2D, copyTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    // Set viewport and clear color only
    glViewport(0, 0, kSize, kSize);
    glClearColor(0, 0, 0, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // Disable depth/stencil testing.
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_STENCIL_TEST);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw red
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.75f);
    ASSERT_GL_NO_ERROR();

    // Break the render pass
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize / 2, kSize / 2);
    ASSERT_GL_NO_ERROR();

    // Verify the counters
    EXPECT_DEPTH_STENCIL_LOAD_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_COUNTERS_FOR_UNRESOLVE_RESOLVE_TEST(getPerfCounters(), expected);
}

// Tests that multisampled-render-to-texture depth/stencil renderbuffers resolve to be updated
// respectively.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       MultisampleDepthStencilResolveSeparately)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));

    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // This test creates 4 render passes. In the first render pass, color, depth and stencil are
    // cleared. In the following render passes, depth and stencil toggle between Load and Clear
    // respectively.

    constexpr GLsizei kSize = 6;

    // Create multisampled framebuffer to draw into, with both color and depth attachments.
    GLTexture colorMS;
    glBindTexture(GL_TEXTURE_2D, colorMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer depthStencilMS;
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencilMS);
    glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);

    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         colorMS, 0, 4);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              depthStencilMS);
    ASSERT_GL_NO_ERROR();

    // Set up texture for copy operation that breaks the render pass
    GLTexture copyTex;
    glBindTexture(GL_TEXTURE_2D, copyTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    // Set viewport and clear color, depth and stencil
    glViewport(0, 0, kSize, kSize);
    glClearColor(0, 0, 0, 0.0f);
    glClearDepthf(1.0);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Output depth/stencil but disable testing so all draw calls succeed
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);

    glEnable(GL_STENCIL_TEST);
    glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, 255);
    glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 255);
    glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(255);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // First render pass: The depthLoadOp and stencilLoadOp are Clear.
    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 1, 0, &expected);

    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.75f);
    ASSERT_GL_NO_ERROR();

    // Break the first render pass and verify the counters.
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize, kSize);
    ASSERT_GL_NO_ERROR();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Second render pass: The depthLoadOp and stencilLoadOp are Load.
    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 1, 0, 1, 0, &expected);

    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Break the second render pass and verify the counters.
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize, kSize);
    ASSERT_GL_NO_ERROR();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Clear depth, but not stencil buffer (loadOp D=CLEAR)
    glClear(GL_DEPTH_BUFFER_BIT);

    // Third render pass: The depthLoadOp is Clear and stencilLoadOp is Load.
    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 1, 0, 1, 0, &expected);

    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.25f);
    ASSERT_GL_NO_ERROR();

    // Break the third render pass and verify the counters.
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize, kSize);
    ASSERT_GL_NO_ERROR();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Clear stencil, but not depth buffer (loadOp S=CLEAR)
    glClear(GL_STENCIL_BUFFER_BIT);

    // Fourth render pass: The depthLoadOp is Load and stencilLoadOp is Clear.
    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 1, 0, &expected);

    glUniform4f(colorUniformLocation, 1.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Break the fourth render pass and verify the counters.
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize, kSize);
    ASSERT_GL_NO_ERROR();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Ensures we use read-only depth layout when there is no write
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, ReadOnlyDepthBufferLayout)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 64;

    angle::VulkanPerfCounters expected;

    // Create depth only FBO and fill depth texture to leftHalf=0.0 and rightHalf=1.0. This should
    // use writeable layout
    expected.readOnlyDepthStencilRenderPasses = getPerfCounters().readOnlyDepthStencilRenderPasses;

    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 0, 1, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    GLTexture depthTexture;
    glBindTexture(GL_TEXTURE_2D, depthTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, kSize, kSize, 0, GL_DEPTH_COMPONENT,
                 GL_UNSIGNED_INT, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    GLFramebuffer depthOnlyFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, depthOnlyFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);
    glDepthMask(GL_TRUE);
    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    glViewport(0, 0, kSize / 2, kSize);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.0f);
    glViewport(kSize / 2, 0, kSize / 2, kSize);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 1.0f);
    glViewport(0, 0, kSize, kSize);
    ASSERT_GL_NO_ERROR();

    // Because the layout counter is updated at end of renderpass, we need to issue a finish call
    // here to end the renderpass.
    glFinish();

    uint64_t actualReadOnlyDepthStencilCount = getPerfCounters().readOnlyDepthStencilRenderPasses;
    EXPECT_EQ(expected.readOnlyDepthStencilRenderPasses, actualReadOnlyDepthStencilCount);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Create a color+depth FBO and use depth as read only. This should use read only layout
    ++expected.readOnlyDepthStencilRenderPasses;
    // Expect rpCount+1, depth(Clears+0, Loads+1, LoadNones+0, Stores+0, StoreNones+1),
    // stencil(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 1, 0, 0, 1, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 0, 0, 0, &expected);

    GLTexture colorTexture;
    glBindTexture(GL_TEXTURE_2D, colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    GLFramebuffer depthAndColorFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, depthAndColorFBO);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    // Clear color to blue and draw a green quad with depth=0.5
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glDepthMask(GL_FALSE);

    angle::Vector4 clearColor = GLColor::blue.toNormalizedVector();
    glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    // The pixel check will end renderpass.
    EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(1 + kSize / 2, 1, GLColor::red);
    actualReadOnlyDepthStencilCount = getPerfCounters().readOnlyDepthStencilRenderPasses;
    EXPECT_EQ(expected.readOnlyDepthStencilRenderPasses, actualReadOnlyDepthStencilCount);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Ensures depth/stencil is not loaded after storeOp=DONT_CARE due to optimization (as opposed to
// invalidate)
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
       RenderPassAfterRenderPassWithoutDepthStencilWrite)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1),
    // stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    constexpr GLsizei kSize = 64;

    // Create FBO with color, depth and stencil.  Leave depth/stencil uninitialized.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLRenderbuffer renderbuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              renderbuffer);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ASSERT_GL_NO_ERROR();

    // Draw to the FBO, without enabling depth/stencil.
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::UniformColor());
    glUseProgram(program);
    GLint colorUniformLocation =
        glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(-1, colorUniformLocation);
    ASSERT_GL_NO_ERROR();

    glViewport(0, 0, kSize, kSize);
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f);

    // Break the render pass and ensure no depth/stencil load/store was done.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1),
    // stencil(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 0, 0, 1, 0, 1, &expected);

    // Draw again with similar conditions, and again make sure no load/store is done.
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f);

    // Break the render pass and ensure no depth/stencil load/store was done.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Ensures repeated clears of various kind (all attachments, some attachments, scissored, masked
// etc) don't break the render pass.
TEST_P(VulkanPerformanceCounterTest, ClearAfterClearDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    constexpr GLsizei kSize = 6;

    // Create a framebuffer to clear with both color and depth/stencil attachments.
    GLTexture color;
    glBindTexture(GL_TEXTURE_2D, color);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLTexture depth;
    glBindTexture(GL_TEXTURE_2D, depth);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, kSize, kSize, 0, GL_DEPTH_STENCIL,
                 GL_UNSIGNED_INT_24_8_OES, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
    ASSERT_GL_NO_ERROR();

    // Clear color and depth, but not stencil.
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepthf(0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Clear color and stencil, but not depth.
    glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
    glClearStencil(0x11);
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Clear depth and stencil, but not color.
    glClearDepthf(0.1f);
    glClearStencil(0x22);
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Clear masked color, and unmasked depth.
    glClearDepthf(0.2f);
    glClearColor(0.1f, 1.0f, 0.0f, 1.0f);
    glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Clear unmasked color, and masked stencil.
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glClearStencil(0x33);
    glStencilMask(0xF0);
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Clear unmasked depth and stencil.
    glClearDepthf(0.3f);
    glClearStencil(0x44);
    glStencilMask(0xFF);
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Clear with scissor.
    glEnable(GL_SCISSOR_TEST);
    glScissor(kSize / 3, kSize / 3, kSize / 3, kSize / 3);
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(1.0f);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Verify render pass count.
    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);

    // Make sure the result is correct.  The border of the image should be blue with depth 0.3f and
    // stencil 0x44.  The center is red with depth 1.0f and stencil 0x55.

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);

    EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3 - 1, kSize / 3, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3 - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3 - 1, 2 * kSize / 3 - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);

    glViewport(0, 0, kSize, kSize);
    glDisable(GL_SCISSOR_TEST);

    // Center: If depth is not cleared to 1, rendering would fail.
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    // Center: If stencil is not clear to 0x55, rendering would fail.
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_EQUAL, 0x55, 0xFF);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilMask(0xFF);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw green
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
    ASSERT_GL_NO_ERROR();

    // Verify that only the center has changed
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);

    EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3 - 1, kSize / 3, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3 - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3 - 1, 2 * kSize / 3 - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::green);

    // Border: If depth is not cleared to 0.3f, rendering would fail.
    glDepthFunc(GL_LESS);

    // Center: If stencil is not clear to 0x44, rendering would fail.
    glStencilFunc(GL_EQUAL, 0x44, 0xFF);

    // Draw yellow
    glUniform4f(colorUniformLocation, 1.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), -0.5f);
    ASSERT_GL_NO_ERROR();

    // Verify that only the border has changed
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::yellow);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::yellow);

    EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3 - 1, kSize / 3, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3 - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3 - 1, 2 * kSize / 3 - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::green);
}

// Ensures that changing the scissor size doesn't break the render pass.
TEST_P(VulkanPerformanceCounterTest, ScissorDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr GLsizei kSize = 16;

    // Create a framebuffer with a color attachment.
    GLTexture color;
    glBindTexture(GL_TEXTURE_2D, color);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
    ASSERT_GL_NO_ERROR();

    // First, issue a clear and make sure it's done.  Later we can verify that areas outside
    // scissors are not rendered to.
    glClearColor(0, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // This test starts with a small scissor and gradually grows it and issues draw calls and
    // various kinds of clears:
    //
    // - Clear the center to red
    //
    //     +----------------------+
    //     | K                    |
    //     |                      |
    //     |       +-----+        |
    //     |       |     |        |
    //     |       |  R  |        |
    //     |       |     |        |
    //     |       +-----+        |
    //     |                      |
    //     |                      |
    //     |                      |
    //     |                      |
    //     +----------------------+
    //
    // - Draw green to center right
    //
    //     +----------------------+
    //     |                      |
    //     |              +-------+
    //     |       +-----+|       |
    //     |       |     ||       |
    //     |       |  R  ||  G    |
    //     |       |     ||       |
    //     |       +-----+|       |
    //     |              |       |
    //     |              |       |
    //     |              |       |
    //     |              +-------+
    //     +----------------------+
    //
    // - Masked clear of center column, only outputting to the blue channel
    //
    //     +----------------------+
    //     |      +---+           |
    //     |      | B |   +-------+
    //     |      |+--+--+|       |
    //     |      ||  |  ||       |
    //     |      ||M |R ||  G    |
    //     |      ||  |  ||       |
    //     |      |+--+--+|       |
    //     |      |   |   |       |
    //     |      |   |   |       |
    //     |      |   |   |       |
    //     |      |   |   +-------+
    //     +------+---+-----------+
    //
    // - Masked draw of center row, only outputting to alpha.
    //
    //     +----------------------+
    //     | K    +---+ K         |
    //     |      | B |   +-------+
    //     |      |+--+--+|       |
    //     |      ||M |R ||   G   |
    //     | +----++--+--++-----+ |
    //     | |    ||TM|TR||     | |
    //     | | TK |+--+--+|  TG | |
    //     | |    |TB |TK |     | |
    //     | +----+---+---+-----+ |
    //     |      |   |   |   G   |
    //     | K    | B | K +-------+
    //     +------+---+-----------+
    //
    // Where: K=Black, R=Red, G=Green, B=Blue, M=Magenta, T=Transparent

    constexpr GLsizei kClearX      = kSize / 3;
    constexpr GLsizei kClearY      = kSize / 3;
    constexpr GLsizei kClearWidth  = kSize / 3;
    constexpr GLsizei kClearHeight = kSize / 3;

    constexpr GLsizei kDrawX      = kClearX + kClearWidth + 2;
    constexpr GLsizei kDrawY      = kSize / 5;
    constexpr GLsizei kDrawWidth  = kSize - kDrawX;
    constexpr GLsizei kDrawHeight = 7 * kSize / 10;

    constexpr GLsizei kMaskedClearX      = kSize / 4;
    constexpr GLsizei kMaskedClearY      = kSize / 8;
    constexpr GLsizei kMaskedClearWidth  = kSize / 4;
    constexpr GLsizei kMaskedClearHeight = 7 * kSize / 8;

    constexpr GLsizei kMaskedDrawX      = kSize / 8;
    constexpr GLsizei kMaskedDrawY      = kSize / 2;
    constexpr GLsizei kMaskedDrawWidth  = 6 * kSize / 8;
    constexpr GLsizei kMaskedDrawHeight = kSize / 4;

    glEnable(GL_SCISSOR_TEST);

    // Clear center to red
    glScissor(kClearX, kClearY, kClearWidth, kClearHeight);
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw green to center right
    glScissor(kDrawX, kDrawY, kDrawWidth, kDrawHeight);
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0);
    ASSERT_GL_NO_ERROR();

    // Masked blue-channel clear of center column
    glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
    glScissor(kMaskedClearX, kMaskedClearY, kMaskedClearWidth, kMaskedClearHeight);
    glClearColor(0.5f, 0.5f, 1.0f, 0.5f);
    glClear(GL_COLOR_BUFFER_BIT);

    // Masked alpha-channel draw of center row
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
    glScissor(kMaskedDrawX, kMaskedDrawY, kMaskedDrawWidth, kMaskedDrawHeight);
    glUniform4f(colorUniformLocation, 0.5f, 0.5f, 0.5f, 0.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0);
    ASSERT_GL_NO_ERROR();

    // Verify render pass count.
    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);

    // Make sure the result is correct:
    //
    //     +----------------------+  <-- 0
    //     | K    +---+ K         |  <-- kMaskedClearY
    //     |      | B |   +-------+  <-- kDrawY
    //     |      |+--+--+|       |  <-- kClearY
    //     |      ||M |R ||   G   |
    //     | +----++--+--++-----+ |  <-- kMaskedDrawY
    //     | |    ||TM|TR||     | |
    //     | | TK |+--+--+|  TG | |  <-- kClearY + kClearHeight
    //     | |    |TB |TK |     | |
    //     | +----+---+---+-----+ |  <-- kMaskedDrawY + kMaskedDrawHeight
    //     |      |   |   |   G   |
    //     | K    | B | K +-------+  <-- kDrawY + kDrawHeight
    //     +------+---+-----------+  <-- kSize == kMaskedClearY + kMaskedClearHeight
    //     | |    ||  |  ||     | |
    //     | |    ||  |  ||     |  \---> kSize == kDrawX + kDrawWidth
    //     | |    ||  |  ||      \-----> kMaskedDrawX + kMaskedDrawWidth
    //     | |    ||  |  | \-----------> kDrawX
    //     | |    ||  |   \------------> kClearX + kClearWidth
    //     | |    ||   \---------------> kMaskedClearX + kMaskedClearWidth
    //     | |    | \------------------> kClearX
    //     | |     \-------------------> kMaskedClearX
    //     |  \------------------------> kMaskedDrawX
    //      \--------------------------> 0

    constexpr GLsizei kClearX2       = kClearX + kClearWidth;
    constexpr GLsizei kClearY2       = kClearY + kClearHeight;
    constexpr GLsizei kDrawX2        = kDrawX + kDrawWidth;
    constexpr GLsizei kDrawY2        = kDrawY + kDrawHeight;
    constexpr GLsizei kMaskedClearX2 = kMaskedClearX + kMaskedClearWidth;
    constexpr GLsizei kMaskedClearY2 = kMaskedClearY + kMaskedClearHeight;
    constexpr GLsizei kMaskedDrawX2  = kMaskedDrawX + kMaskedDrawWidth;
    constexpr GLsizei kMaskedDrawY2  = kMaskedDrawY + kMaskedDrawHeight;

    constexpr GLColor kTransparentRed(255, 0, 0, 0);
    constexpr GLColor kTransparentGreen(0, 255, 0, 0);
    constexpr GLColor kTransparentBlue(0, 0, 255, 0);
    constexpr GLColor kTransparentMagenta(255, 0, 255, 0);

    // Verify the black areas.
    EXPECT_PIXEL_RECT_EQ(0, 0, kMaskedClearX, kMaskedDrawY, GLColor::black);
    EXPECT_PIXEL_RECT_EQ(0, kMaskedDrawY2, kMaskedClearX, kSize - kMaskedDrawY2, GLColor::black);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX2, 0, kSize - kMaskedClearX2, kDrawY, GLColor::black);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX2, kDrawY2, kSize - kMaskedClearX2, kSize - kDrawY2,
                         GLColor::black);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX, 0, kMaskedClearWidth, kMaskedClearY, GLColor::black);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX2, kDrawY, kDrawX - kMaskedClearX2, kClearY - kDrawY,
                         GLColor::black);
    EXPECT_PIXEL_RECT_EQ(kClearX2, kClearY, kDrawX - kClearX2, kMaskedDrawY - kClearY,
                         GLColor::black);
    EXPECT_PIXEL_RECT_EQ(0, kMaskedDrawY, kMaskedDrawX, kMaskedDrawHeight, GLColor::black);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX2, kMaskedDrawY2, kDrawX - kMaskedClearX2,
                         kSize - kMaskedDrawY2, GLColor::black);

    // Verify the red area:
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX2, kClearY, kClearX2 - kMaskedClearX2, kMaskedDrawY - kClearY,
                         GLColor::red);
    // Verify the transparent red area:
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX2, kMaskedDrawY, kClearX2 - kMaskedClearX2,
                         kClearY2 - kMaskedDrawY, kTransparentRed);
    // Verify the magenta area:
    EXPECT_PIXEL_RECT_EQ(kClearX, kClearY, kMaskedClearX2 - kClearX, kMaskedDrawY - kClearY,
                         GLColor::magenta);
    // Verify the transparent magenta area:
    EXPECT_PIXEL_RECT_EQ(kClearX, kMaskedDrawY, kMaskedClearX2 - kClearX, kClearY2 - kMaskedDrawY,
                         kTransparentMagenta);
    // Verify the green area:
    EXPECT_PIXEL_RECT_EQ(kDrawX, kDrawY, kDrawWidth, kMaskedDrawY - kDrawY, GLColor::green);
    EXPECT_PIXEL_RECT_EQ(kDrawX, kMaskedDrawY2, kDrawWidth, kDrawY2 - kMaskedDrawY2,
                         GLColor::green);
    EXPECT_PIXEL_RECT_EQ(kMaskedDrawX2, kMaskedDrawY, kDrawX2 - kMaskedDrawX2, kMaskedDrawHeight,
                         GLColor::green);
    // Verify the transparent green area:
    EXPECT_PIXEL_RECT_EQ(kDrawX, kMaskedDrawY, kMaskedDrawX2 - kDrawX, kMaskedDrawHeight,
                         kTransparentGreen);
    // Verify the blue area:
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX, kMaskedClearY, kMaskedClearWidth, kClearY - kMaskedClearY,
                         GLColor::blue);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX, kMaskedDrawY2, kMaskedClearWidth,
                         kMaskedClearY2 - kMaskedDrawY2, GLColor::blue);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX, kClearY, kClearX - kMaskedClearX, kMaskedDrawY - kClearY,
                         GLColor::blue);
    // Verify the transparent blue area:
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX, kClearY2, kMaskedClearWidth, kMaskedDrawY2 - kClearY2,
                         kTransparentBlue);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX, kMaskedDrawY, kClearX - kMaskedClearX,
                         kClearY2 - kMaskedDrawY, kTransparentBlue);
    // Verify the transparent black area:
    EXPECT_PIXEL_RECT_EQ(kMaskedDrawX, kMaskedDrawY, kMaskedClearX - kMaskedDrawX,
                         kMaskedDrawHeight, GLColor::transparentBlack);
    EXPECT_PIXEL_RECT_EQ(kMaskedClearX2, kClearY2, kDrawX - kMaskedClearX2,
                         kMaskedDrawY2 - kClearY2, GLColor::transparentBlack);
    EXPECT_PIXEL_RECT_EQ(kClearX2, kMaskedDrawY, kDrawX - kClearX2, kMaskedDrawHeight,
                         GLColor::transparentBlack);
}

// Tests that changing UBO bindings does not allocate new descriptor sets.
TEST_P(VulkanPerformanceCounterTest, ChangingUBOsHitsDescriptorSetCache)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    // Set up two UBOs, one filled with "1" and the second with "2".
    constexpr GLsizei kCount = 64;
    std::vector<GLint> data1(kCount, 1);
    std::vector<GLint> data2(kCount, 2);

    GLBuffer ubo1;
    glBindBuffer(GL_UNIFORM_BUFFER, ubo1);
    glBufferData(GL_UNIFORM_BUFFER, kCount * sizeof(data1[0]), data1.data(), GL_STATIC_DRAW);

    GLBuffer ubo2;
    glBindBuffer(GL_UNIFORM_BUFFER, ubo2);
    glBufferData(GL_UNIFORM_BUFFER, kCount * sizeof(data2[0]), data2.data(), GL_STATIC_DRAW);

    // Set up a program that verifies the contents of uniform blocks.
    constexpr char kVS[] = R"(#version 300 es
precision mediump float;
in vec4 position;
void main()
{
    gl_Position = position;
})";

    constexpr char kFS[] = R"(#version 300 es
precision mediump float;
uniform buf {
    int data[64/4];
};
uniform int checkValue;
out vec4 outColor;

void main()
{
    for (int i = 0; i < 64/4; ++i) {
        if (data[i] != checkValue) {
            outColor = vec4(1, 0, 0, 1);
            return;
        }
    }
    outColor = vec4(0, 1, 0, 1);
})";

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glUseProgram(program);
    ASSERT_GL_NO_ERROR();

    GLint uniLoc = glGetUniformLocation(program, "checkValue");
    ASSERT_NE(-1, uniLoc);

    GLuint blockIndex = glGetUniformBlockIndex(program, "buf");
    ASSERT_NE(blockIndex, GL_INVALID_INDEX);

    glUniformBlockBinding(program, blockIndex, 0);
    ASSERT_GL_NO_ERROR();

    // Set up the rest of the GL state.
    auto quadVerts = GetQuadVertices();
    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
                 GL_STATIC_DRAW);

    GLint posLoc = glGetAttribLocation(program, "position");
    ASSERT_NE(-1, posLoc);

    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLoc);

    // Draw a few times with each UBO. Stream out one pixel for post-render verification.
    constexpr int kIterations         = 5;
    constexpr GLsizei kPackBufferSize = sizeof(GLColor) * kIterations * 2;

    GLBuffer packBuffer;
    glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
    glBufferData(GL_PIXEL_PACK_BUFFER, kPackBufferSize, nullptr, GL_STREAM_READ);

    GLsizei offset = 0;

    uint64_t expectedUniformBuffersCacheMisses = 0;

    for (int iteration = 0; iteration < kIterations; ++iteration)
    {
        glUniform1i(uniLoc, 1);
        glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo1);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
                     reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(offset)));
        offset += sizeof(GLColor);
        glUniform1i(uniLoc, 2);
        glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo2);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
                     reinterpret_cast<GLvoid *>(static_cast<uintptr_t>(offset)));
        offset += sizeof(GLColor);

        // Capture the allocations counter after the first run.
        if (iteration == 0)
        {
            expectedUniformBuffersCacheMisses =
                getPerfCounters().uniformBuffersDescriptorSetCacheMisses;
        }
    }

    ASSERT_GL_NO_ERROR();
    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        EXPECT_GT(expectedUniformBuffersCacheMisses, 0u);
    }

    // Verify correctness first.
    std::vector<GLColor> expectedData(kIterations * 2, GLColor::green);
    std::vector<GLColor> actualData(kIterations * 2, GLColor::black);

    void *mapPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kPackBufferSize, GL_MAP_READ_BIT);
    ASSERT_NE(nullptr, mapPtr);
    memcpy(actualData.data(), mapPtr, kPackBufferSize);

    glUnmapBuffer(GL_PIXEL_PACK_BUFFER);

    EXPECT_EQ(expectedData, actualData);

    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        // Check for unnecessary descriptor set allocations.
        uint64_t actualUniformBuffersCacheMisses =
            getPerfCounters().uniformBuffersDescriptorSetCacheMisses;
        EXPECT_EQ(expectedUniformBuffersCacheMisses, actualUniformBuffersCacheMisses);
    }
}

// Test that mapping a buffer that the GPU is using as read-only ghosts the buffer, rather than
// waiting for the GPU access to complete before returning a pointer to the buffer.
void VulkanPerformanceCounterTest::mappingGpuReadOnlyBufferGhostsBuffer(BufferUpdate update)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    // 1. Create a buffer, map it, fill it with red
    // 2. Draw with buffer (GPU read-only)
    // 3. Map the same buffer and fill with white
    //    - This should ghost the buffer, rather than ending the render pass.
    // 4. Draw with buffer
    // 5. Update the buffer with glBufferSubData() or glCopyBufferSubData
    // 6. Draw with the buffer
    // The render pass should only be broken (counters.renderPasses == 0) due to the glReadPixels()
    // to verify the draw at the end.

    const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
                                                 GLColor::red};
    const std::array<GLColor, 4> kUpdateData1 = {GLColor::white, GLColor::white, GLColor::white,
                                                 GLColor::white};
    const std::array<GLColor, 4> kUpdateData2 = {GLColor::blue, GLColor::blue, GLColor::blue,
                                                 GLColor::blue};

    GLBuffer buffer;
    glBindBuffer(GL_UNIFORM_BUFFER, buffer);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
    ASSERT_GL_NO_ERROR();

    // Draw
    constexpr char kVerifyUBO[] = R"(#version 300 es
precision mediump float;
uniform block {
    uvec4 data;
} ubo;
uniform highp uint expect;
uniform vec4 successOutput;
out vec4 colorOut;
void main()
{
    if (all(equal(ubo.data, uvec4(expect))))
        colorOut = successOutput;
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);
    glUseProgram(verifyUbo);

    GLint expectLoc = glGetUniformLocation(verifyUbo, "expect");
    ASSERT_NE(-1, expectLoc);
    GLint successLoc = glGetUniformLocation(verifyUbo, "successOutput");
    ASSERT_NE(-1, successLoc);

    glUniform1ui(expectLoc, kInitialData[0].asUint());
    glUniform4f(successLoc, 0, 1, 0, 1);

    drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
    ASSERT_GL_NO_ERROR();

    // Map the buffer and update it.
    // This should ghost the buffer and avoid breaking the render pass, since the GPU is only
    // reading it.
    void *mappedBuffer =
        glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), GL_MAP_WRITE_BIT);
    // 'renderPasses == 0' here means the render pass was broken and a new one was started.
    ASSERT_EQ(getPerfCounters().renderPasses, 1u);
    ASSERT_EQ(getPerfCounters().buffersGhosted, 1u);

    memcpy(mappedBuffer, kUpdateData1.data(), sizeof(kInitialData));

    glUnmapBuffer(GL_UNIFORM_BUFFER);
    ASSERT_GL_NO_ERROR();

    // Verify that the buffer has the updated value.
    glUniform1ui(expectLoc, kUpdateData1[0].asUint());
    glUniform4f(successLoc, 0, 0, 1, 1);

    drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(getPerfCounters().renderPasses, 1u);

    // Update the buffer
    updateBuffer(update, GL_UNIFORM_BUFFER, 0, sizeof(kUpdateData2), kUpdateData2.data());
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(getPerfCounters().renderPasses, 1u);

    // Verify that the buffer has the updated value.
    glUniform1ui(expectLoc, kUpdateData2[0].asUint());
    glUniform4f(successLoc, 0, 1, 1, 1);

    drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
    ASSERT_GL_NO_ERROR();
    ASSERT_EQ(getPerfCounters().renderPasses, 1u);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
}

// Test that mapping a buffer that the GPU is using as read-only ghosts the buffer, rather than
// waiting for the GPU access to complete before returning a pointer to the buffer.  This test uses
// glBufferSubData to update the buffer.
TEST_P(VulkanPerformanceCounterTest, MappingGpuReadOnlyBufferGhostsBuffer_SubData)
{
    mappingGpuReadOnlyBufferGhostsBuffer(BufferUpdate::SubData);
}

// Same as MappingGpuReadOnlyBufferGhostsBuffer_SubData, but using glCopyBufferSubData to update the
// buffer.
TEST_P(VulkanPerformanceCounterTest, MappingGpuReadOnlyBufferGhostsBuffer_Copy)
{
    mappingGpuReadOnlyBufferGhostsBuffer(BufferUpdate::Copy);
}

void VulkanPerformanceCounterTest::partialBufferUpdateShouldNotBreakRenderPass(BufferUpdate update)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;
    if (!hasPreferCPUForBufferSubData())
    {
        ++expectedRenderPassCount;
    }

    const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::green, GLColor::blue,
                                                 GLColor::yellow};
    const std::array<GLColor, 1> kUpdateData1 = {GLColor::cyan};
    const std::array<GLColor, 3> kUpdateData2 = {GLColor::magenta, GLColor::black, GLColor::white};

    GLBuffer buffer;
    glBindBuffer(GL_UNIFORM_BUFFER, buffer);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
    ASSERT_GL_NO_ERROR();

    constexpr char kVS[] = R"(#version 300 es
precision highp float;
uniform float height;
void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kFS[] = R"(#version 300 es
precision highp float;
out vec4 colorOut;
uniform block {
    uvec4 data;
} ubo;
uniform uvec4 expect;
uniform vec4 successColor;
void main()
{
    if (all(equal(ubo.data, expect)))
        colorOut = successColor;
    else
        colorOut = vec4(0);
})";

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glUseProgram(program);

    GLint expectLoc = glGetUniformLocation(program, "expect");
    ASSERT_NE(-1, expectLoc);
    GLint successLoc = glGetUniformLocation(program, "successColor");
    ASSERT_NE(-1, successLoc);

    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);

    // Draw once, using the buffer in the render pass.
    glUniform4ui(expectLoc, kInitialData[0].asUint(), kInitialData[1].asUint(),
                 kInitialData[2].asUint(), kInitialData[3].asUint());
    glUniform4f(successLoc, 1, 0, 0, 1);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    // Upload a small part of the buffer, and draw again.
    updateBuffer(update, GL_UNIFORM_BUFFER, 0, sizeof(kUpdateData1), kUpdateData1.data());

    glUniform4ui(expectLoc, kUpdateData1[0].asUint(), kInitialData[1].asUint(),
                 kInitialData[2].asUint(), kInitialData[3].asUint());
    glUniform4f(successLoc, 0, 1, 0, 1);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    // Upload a large part of the buffer, and draw again.
    updateBuffer(update, GL_UNIFORM_BUFFER, sizeof(kUpdateData1), sizeof(kUpdateData2),
                 kUpdateData2.data());

    glUniform4ui(expectLoc, kUpdateData1[0].asUint(), kUpdateData2[0].asUint(),
                 kUpdateData2[1].asUint(), kUpdateData2[2].asUint());
    glUniform4f(successLoc, 0, 0, 1, 1);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    // Verify results
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
    ASSERT_GL_NO_ERROR();

    // Only one render pass should have been used.
    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
}

// Verifies that BufferSubData calls don't cause a render pass break when it only uses the buffer
// read-only.  This test uses glBufferSubData to update the buffer.
TEST_P(VulkanPerformanceCounterTest, PartialBufferUpdateShouldNotBreakRenderPass_SubData)
{
    partialBufferUpdateShouldNotBreakRenderPass(BufferUpdate::SubData);
}

// Same as PartialBufferUpdateShouldNotBreakRenderPass_SubData, but using glCopyBufferSubData to
// update the buffer.
TEST_P(VulkanPerformanceCounterTest, PartialBufferUpdateShouldNotBreakRenderPass_Copy)
{
    partialBufferUpdateShouldNotBreakRenderPass(BufferUpdate::Copy);
}

void VulkanPerformanceCounterTest::bufferSubDataShouldNotTriggerSyncState(BufferUpdate update)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    glUseProgram(testProgram);

    GLint posLoc = glGetAttribLocation(testProgram, essl1_shaders::PositionAttrib());
    ASSERT_NE(-1, posLoc);

    setupQuadVertexBuffer(0.5f, 1.0f);
    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);

    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    EXPECT_EQ(getPerfCounters().vertexArraySyncStateCalls, 1u);

    const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
    size_t bufferSize                          = sizeof(quadVertices[0]) * quadVertices.size();

    updateBuffer(update, GL_ARRAY_BUFFER, 0, bufferSize, quadVertices.data());

    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    EXPECT_EQ(getPerfCounters().vertexArraySyncStateCalls, 1u);

    // Verify the BufferData with a whole buffer size is treated like the SubData call.
    glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices[0]) * quadVertices.size(),
                 quadVertices.data(), GL_STATIC_DRAW);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    EXPECT_EQ(getPerfCounters().vertexArraySyncStateCalls, 1u);
}

// Verifies that BufferSubData calls don't trigger state updates for non-translated formats.  This
// test uses glBufferSubData to update the buffer.
TEST_P(VulkanPerformanceCounterTest, BufferSubDataShouldNotTriggerSyncState_SubData)
{
    bufferSubDataShouldNotTriggerSyncState(BufferUpdate::SubData);
}

// Same as BufferSubDataShouldNotTriggerSyncState_SubData, but using glCopyBufferSubData to update
// the buffer.
TEST_P(VulkanPerformanceCounterTest, BufferSubDataShouldNotTriggerSyncState_Copy)
{
    bufferSubDataShouldNotTriggerSyncState(BufferUpdate::Copy);
}

// Verifies that rendering to backbuffer discards depth/stencil.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, SwapShouldInvalidateDepthStencil)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 0, 0, &expected);

    // Clear to verify that _some_ counters did change (as opposed to for example all being reset on
    // swap)
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_ALWAYS);
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, 0x00, 0xFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Swap buffers to implicitely resolve
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Verifies that rendering to MSAA backbuffer discards depth/stencil.
TEST_P(VulkanPerformanceCounterTest_MSAA, SwapShouldInvalidateDepthStencil)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    // stencil(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForStencilOps(getPerfCounters(), 1, 0, 0, 0, 0, &expected);

    // Clear to verify that _some_ counters did change (as opposed to for example all being reset on
    // swap)
    glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_ALWAYS);
    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, 0x00, 0xFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Swap buffers to implicitely resolve
    swapBuffers();
    EXPECT_DEPTH_STENCIL_OP_COUNTERS(getPerfCounters(), expected);
}

// Verifies that multisample swapchain resolve occurs in subpass.
TEST_P(VulkanPerformanceCounterTest_MSAA, SwapShouldResolveWithSubpass)
{
    angle::VulkanPerfCounters expected;
    // Expect rpCount+1, color(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);

    uint64_t expectedResolvesSubpass = getPerfCounters().swapchainResolveInSubpass + 1;
    uint64_t expectedResolvesOutside = getPerfCounters().swapchainResolveOutsideSubpass;

    // Clear color.
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw green
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
    ASSERT_GL_NO_ERROR();

    // Swap buffers to implicitly resolve
    swapBuffers();
    EXPECT_EQ(getPerfCounters().swapchainResolveInSubpass, expectedResolvesSubpass);
    EXPECT_EQ(getPerfCounters().swapchainResolveOutsideSubpass, expectedResolvesOutside);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Verifies that in a multisample swapchain, drawing to the default FBO followed by user FBO and
// then swapping triggers the resolve outside the optimization subpass.
TEST_P(VulkanPerformanceCounterTest_MSAA, SwapAfterDrawToDifferentFBOsShouldResolveOutsideSubpass)
{
    constexpr GLsizei kSize = 16;
    angle::VulkanPerfCounters expected;
    // Expect rpCount+1, color(Clears+1, Loads+0, LoadNones+0, Stores+2, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 1, 0, 0, 2, 0, &expected);

    uint64_t expectedResolvesSubpass = getPerfCounters().swapchainResolveInSubpass;
    uint64_t expectedResolvesOutside = getPerfCounters().swapchainResolveOutsideSubpass + 1;

    // Create a framebuffer to clear.
    GLTexture color;
    glBindTexture(GL_TEXTURE_2D, color);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
    ASSERT_GL_NO_ERROR();

    // Clear color.
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Draw green to default framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
    ASSERT_GL_NO_ERROR();

    // Draw blue to the user framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
    ASSERT_GL_NO_ERROR();

    // Swap buffers to resolve outside the optimization subpass
    swapBuffers();
    EXPECT_EQ(getPerfCounters().swapchainResolveInSubpass, expectedResolvesSubpass);
    EXPECT_EQ(getPerfCounters().swapchainResolveOutsideSubpass, expectedResolvesOutside);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Verifies that in a multisample swapchain, subpass resolve only happens when the render pass
// covers the entire area.
TEST_P(VulkanPerformanceCounterTest_MSAA, ResolveWhenRenderPassNotEntireArea)
{
    constexpr GLsizei kSize = 16;
    angle::VulkanPerfCounters expected;
    // Expect rpCount+1, color(Clears+0, Loads+1, LoadNones+0, Stores+2, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 2, 0, &expected);

    uint64_t expectedResolvesSubpass = getPerfCounters().swapchainResolveInSubpass;
    uint64_t expectedResolvesOutside = getPerfCounters().swapchainResolveOutsideSubpass + 1;

    // Create a framebuffer to clear.
    GLTexture color;
    glBindTexture(GL_TEXTURE_2D, color);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    ASSERT_GL_NO_ERROR();

    // Clear color.
    glDisable(GL_SCISSOR_TEST);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);

    // Set up program
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Scissor the render area
    glEnable(GL_SCISSOR_TEST);
    glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);

    // Draw blue to the user framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
    ASSERT_GL_NO_ERROR();

    // Draw green to default framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
    ASSERT_GL_NO_ERROR();

    // Swap buffers, which should not resolve the image in subpass
    swapBuffers();
    EXPECT_EQ(getPerfCounters().swapchainResolveInSubpass, expectedResolvesSubpass);
    EXPECT_EQ(getPerfCounters().swapchainResolveOutsideSubpass, expectedResolvesOutside);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that uniform updates eventually stop updating descriptor sets.
TEST_P(VulkanPerformanceCounterTest, UniformUpdatesHitDescriptorSetCache)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(testProgram);
    GLint posLoc = glGetAttribLocation(testProgram, essl1_shaders::PositionAttrib());
    GLint uniLoc = glGetUniformLocation(testProgram, essl1_shaders::ColorUniform());

    std::array<Vector3, 6> quadVerts = GetQuadVertices();

    GLBuffer vbo;
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
                 GL_STATIC_DRAW);

    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);

    ASSERT_GL_NO_ERROR();

    // Choose a number of iterations sufficiently large to ensure all uniforms are cached.
    constexpr int kIterations = 2000;

    // First pass: cache all the uniforms.
    RNG rng;
    for (int iteration = 0; iteration < kIterations; ++iteration)
    {
        Vector3 randomVec3 = RandomVec3(rng.randomInt(), 0.0f, 1.0f);

        glUniform4f(uniLoc, randomVec3.x(), randomVec3.y(), randomVec3.z(), 1.0f);
        glDrawArrays(GL_TRIANGLES, 0, 6);

        GLColor expectedColor = GLColor(randomVec3);
        EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 5);
    }

    ASSERT_GL_NO_ERROR();

    uint64_t expectedCacheMisses = getPerfCounters().uniformsAndXfbDescriptorSetCacheMisses;
    GLint allocationsBefore      = getPerfCounters().descriptorSetAllocations;
    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        EXPECT_GT(expectedCacheMisses, 0u);
    }

    // Second pass: ensure all the uniforms are cached.
    for (int iteration = 0; iteration < kIterations; ++iteration)
    {
        Vector3 randomVec3 = RandomVec3(rng.randomInt(), 0.0f, 1.0f);

        glUniform4f(uniLoc, randomVec3.x(), randomVec3.y(), randomVec3.z(), 1.0f);
        glDrawArrays(GL_TRIANGLES, 0, 6);

        GLColor expectedColor = GLColor(randomVec3);
        EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 5);
    }

    ASSERT_GL_NO_ERROR();

    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        uint64_t actualCacheMisses = getPerfCounters().uniformsAndXfbDescriptorSetCacheMisses;
        EXPECT_EQ(expectedCacheMisses, actualCacheMisses);
    }
    else
    {
        // If cache is disabled, we still expect descriptorSets to be reused instead of keep
        // allocating new descriptorSets. The underline reuse logic is implementation detail (as of
        // now it will not reuse util the pool is full), but we expect it will not increasing for
        // every iteration.
        GLint descriptorSetAllocationsIncrease =
            getPerfCounters().descriptorSetAllocations - allocationsBefore;
        EXPECT_GE(kIterations - 1, descriptorSetAllocationsIncrease);
    }
}

// Test one texture sampled by fragment shader, then image load it by compute
// shader, at last fragment shader do something else.
TEST_P(VulkanPerformanceCounterTest_ES31, DrawDispatchImageReadDrawWithEndRP)
{

    constexpr char kVSSource[] = R"(#version 310 es
in vec4 a_position;
out vec2 v_texCoord;

void main()
{
    gl_Position = vec4(a_position.xy, 0.0, 1.0);
    v_texCoord = a_position.xy * 0.5 + vec2(0.5);
})";

    constexpr char kFSSource[] = R"(#version 310 es
precision mediump float;
uniform sampler2D u_tex2D;
in vec2 v_texCoord;
out vec4 out_FragColor;
void main()
{
    out_FragColor = texture(u_tex2D, v_texCoord);
})";

    constexpr char kFSSource1[] = R"(#version 310 es
precision mediump float;
out vec4 out_FragColor;
void main()
{
    out_FragColor = vec4(1.0);
})";

    constexpr char kCSSource[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(rgba32f, binding=0) readonly  uniform highp image2D uIn;
layout(std140, binding=0) buffer buf {
    vec4 outData;
};

void main()
{
    outData = imageLoad(uIn, ivec2(gl_LocalInvocationID.xy));
})";

    GLfloat initValue[4] = {1.0, 1.0, 1.0, 1.0};

    // Step 1: Set up a simple 2D Texture rendering loop.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, initValue);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    GLBuffer vertexBuffer;
    GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);

    ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
    glUseProgram(program);

    GLint posLoc = glGetAttribLocation(program, "a_position");
    ASSERT_NE(-1, posLoc);

    glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);
    ASSERT_GL_NO_ERROR();
    glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);

    GLBuffer ssbo;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    glBufferData(GL_SHADER_STORAGE_BUFFER, 16, nullptr, GL_STREAM_DRAW);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

    // This is actually suboptimal, and ideally only one render pass should be necessary.
    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 2;

    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Step 2: load this image through compute
    ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
    glUseProgram(csProgram);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);

    glDispatchCompute(1, 1, 1);
    EXPECT_GL_NO_ERROR();

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
        glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT));

    EXPECT_GL_NO_ERROR();
    for (unsigned int idx = 0; idx < 4; idx++)
    {
        EXPECT_EQ(1.0, *(ptr + idx));
    }

    // Step3
    ANGLE_GL_PROGRAM(program2, kVSSource, kFSSource1);
    glUseProgram(program2);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Test one texture sampled by fragment shader, followed by glReadPixels, then image
// load it by compute shader, and at last fragment shader do something else.
TEST_P(VulkanPerformanceCounterTest_ES31, DrawDispatchImageReadDrawWithoutEndRP)
{

    constexpr char kVSSource[] = R"(#version 310 es
in vec4 a_position;
out vec2 v_texCoord;

void main()
{
    gl_Position = vec4(a_position.xy, 0.0, 1.0);
    v_texCoord = a_position.xy * 0.5 + vec2(0.5);
})";

    constexpr char kFSSource[] = R"(#version 310 es
precision mediump float;
uniform sampler2D u_tex2D;
in vec2 v_texCoord;
out vec4 out_FragColor;
void main()
{
    out_FragColor = texture(u_tex2D, v_texCoord);
})";

    constexpr char kFSSource1[] = R"(#version 310 es
precision mediump float;
out vec4 out_FragColor;
void main()
{
    out_FragColor = vec4(1.0);
})";

    constexpr char kCSSource[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(rgba32f, binding=0) readonly  uniform highp image2D uIn;
layout(std140, binding=0) buffer buf {
    vec4 outData;
};

void main()
{
    outData = imageLoad(uIn, ivec2(gl_LocalInvocationID.xy));
})";

    GLfloat initValue[4] = {1.0, 1.0, 1.0, 1.0};

    // Step 1: Set up a simple 2D Texture rendering loop.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, initValue);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    GLBuffer vertexBuffer;
    GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);

    GLBuffer ssbo;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    glBufferData(GL_SHADER_STORAGE_BUFFER, 16, nullptr, GL_STREAM_DRAW);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

    ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
    glUseProgram(program);

    GLint posLoc = glGetAttribLocation(program, "a_position");
    ASSERT_NE(-1, posLoc);

    glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Call glReadPixels to reset the getPerfCounters().renderPasses
    std::vector<GLColor> actualColors(1);
    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, actualColors.data());

    // Ideally, the following "FS sample + CS image load + FS something", should
    // handle in one render pass.
    // Currently, we can ensure the first of "FS sample + CS image load" in one
    // render pass, but will start new render pass if following the last FS operations,
    // which need to be optimized further.
    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 2;

    // Now this texture owns none layout transition
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Step 2: load this image through compute
    ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
    glUseProgram(csProgram);

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
    glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);

    glDispatchCompute(1, 1, 1);
    EXPECT_GL_NO_ERROR();

    // Step3
    ANGLE_GL_PROGRAM(program2, kVSSource, kFSSource1);
    glUseProgram(program2);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Test that one texture sampled by fragment shader, compute shader and fragment
// shader sequentlly.
TEST_P(VulkanPerformanceCounterTest_ES31, TextureSampleByDrawDispatchDraw)
{
    constexpr char kVSSource[] = R"(#version 310 es
in vec4 a_position;
out vec2 v_texCoord;

void main()
{
gl_Position = vec4(a_position.xy, 0.0, 1.0);
v_texCoord = a_position.xy * 0.5 + vec2(0.5);
})";

    constexpr char kFSSource[] = R"(#version 310 es
uniform sampler2D u_tex2D;
precision highp float;
in vec2 v_texCoord;
out vec4 out_FragColor;
void main()
{
out_FragColor = texture(u_tex2D, v_texCoord);
})";

    constexpr char kCSSource[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
precision highp sampler2D;
uniform sampler2D tex;
layout(std140, binding=0) buffer buf {
vec4 outData;
};
void main()
{
uint x = gl_LocalInvocationID.x;
uint y = gl_LocalInvocationID.y;
outData = texture(tex, vec2(x, y));
})";

    GLfloat initValue[4] = {1.0, 1.0, 1.0, 1.0};

    // Step 1: Set up a simple 2D Texture rendering loop.
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_FLOAT, initValue);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    GLfloat vertices[] = {-1, -1, 1, -1, -1, 1, 1, 1};

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);

    ANGLE_GL_PROGRAM(program, kVSSource, kFSSource);
    glUseProgram(program);

    GLint posLoc = glGetAttribLocation(program, "a_position");
    ASSERT_NE(-1, posLoc);

    glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    ASSERT_GL_NO_ERROR();
    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // Step 2: sample this texture through compute
    GLBuffer ssbo;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    glBufferData(GL_SHADER_STORAGE_BUFFER, 16, nullptr, GL_STREAM_DRAW);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

    ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
    glUseProgram(csProgram);

    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(glGetUniformLocation(csProgram, "tex"), 0);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);

    glDispatchCompute(1, 1, 1);
    EXPECT_GL_NO_ERROR();

    // Step3: use the first program sample texture again
    glUseProgram(program);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    ASSERT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Verify a mid-render pass clear of a newly enabled attachment uses LOAD_OP_CLEAR.
TEST_P(VulkanPerformanceCounterTest, DisableThenMidRenderPassClear)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    // This optimization is not implemented when this workaround is in effect.
    ANGLE_SKIP_TEST_IF(hasPreferDrawOverClearAttachments());

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+1, Loads+0, LoadNones+0, Stores+2, StoreNones+0)
    // vkCmdClearAttachments should be used for color attachment 0.
    setExpectedCountersForColorOps(getPerfCounters(), 1, 1, 0, 0, 2, 0, &expected);
    expected.colorClearAttachments = getPerfCounters().colorClearAttachments + 1;

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    GLTexture textures[2];

    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);

    glBindTexture(GL_TEXTURE_2D, textures[1]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);

    // Only enable attachment 0.
    GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_NONE};
    glDrawBuffers(2, drawBuffers);

    // Draw red.
    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // Enable attachment 1.
    drawBuffers[1] = GL_COLOR_ATTACHMENT1;
    glDrawBuffers(2, drawBuffers);

    // Clear both attachments to green.
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    constexpr char kFS[] = R"(#version 300 es
precision highp float;
layout(location = 0) out vec4 my_FragColor0;
layout(location = 1) out vec4 my_FragColor1;
void main()
{
    my_FragColor0 = vec4(0.0, 0.0, 1.0, 1.0);
    my_FragColor1 = vec4(0.0, 0.0, 1.0, 1.0);
})";

    // Draw blue to both attachments.
    ANGLE_GL_PROGRAM(blueProgram, essl3_shaders::vs::Simple(), kFS);
    drawQuad(blueProgram, essl3_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Verify attachment 0.
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_EQ(0, 0, 0, 0, 255, 255);
    // Verify attachment 1.
    glReadBuffer(GL_COLOR_ATTACHMENT1);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_EQ(0, 0, 0, 0, 255, 255);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_CLEAR_ATTACHMENTS_COUNTER(expected.colorClearAttachments,
                                     getPerfCounters().colorClearAttachments);

    // Expect rpCount+1, color(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);

    GLFramebuffer fbo2;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);

    // Blend red
    drawQuad(redProgram, essl3_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Verify purple
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    EXPECT_PIXEL_EQ(0, 0, 255, 0, 255, 255);
    ASSERT_GL_NO_ERROR();

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Copy of ClearTest.InceptionScissorClears.
// Clears many small concentric rectangles using scissor regions. Verifies vkCmdClearAttachments()
// is used for the scissored clears, rather than vkCmdDraw().
TEST_P(VulkanPerformanceCounterTest, InceptionScissorClears)
{
    // https://issuetracker.google.com/166809097
    ANGLE_SKIP_TEST_IF(IsQualcomm() && IsVulkan());

    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);

    angle::RNG rng;

    constexpr GLuint kSize = 16;

    // Create a square user FBO so we have more control over the dimensions.
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    GLRenderbuffer rbo;
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    glViewport(0, 0, kSize, kSize);

    // Clear small concentric squares using scissor.
    std::vector<GLColor> expectedColors;
    // TODO(syoussefi): verify this
    [[maybe_unused]] uint64_t numScissoredClears = 0;
    for (GLuint index = 0; index < (kSize - 1) / 2; index++)
    {
        // Do the first clear without the scissor.
        if (index > 0)
        {
            glEnable(GL_SCISSOR_TEST);
            glScissor(index, index, kSize - (index * 2), kSize - (index * 2));
            ++numScissoredClears;
        }

        GLColor color = RandomColor(&rng);
        expectedColors.push_back(color);
        Vector4 floatColor = color.toNormalizedVector();
        glClearColor(floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
        glClear(GL_COLOR_BUFFER_BIT);
    }

    ASSERT_GL_NO_ERROR();

    // Make sure everything was done in a single renderpass.
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    std::vector<GLColor> actualColors(expectedColors.size());
    glReadPixels(0, kSize / 2, actualColors.size(), 1, GL_RGBA, GL_UNSIGNED_BYTE,
                 actualColors.data());

    EXPECT_EQ(expectedColors, actualColors);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Copy of ClearTest.Depth16Scissored.
// Clears many small concentric rectangles using scissor regions. Verifies vkCmdClearAttachments()
// is used for the scissored clears, rather than vkCmdDraw().
TEST_P(VulkanPerformanceCounterTest, Depth16Scissored)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    GLRenderbuffer renderbuffer;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    constexpr int kRenderbufferSize = 64;
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kRenderbufferSize,
                          kRenderbufferSize);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);

    glClearDepthf(0.0f);
    glClear(GL_DEPTH_BUFFER_BIT);

    glEnable(GL_SCISSOR_TEST);
    constexpr int kNumSteps = 13;
    // TODO(syoussefi): verify this
    [[maybe_unused]] uint64_t numScissoredClears = 0;
    for (int ndx = 1; ndx < kNumSteps; ndx++)
    {
        float perc = static_cast<float>(ndx) / static_cast<float>(kNumSteps);
        glScissor(0, 0, static_cast<int>(kRenderbufferSize * perc),
                  static_cast<int>(kRenderbufferSize * perc));
        glClearDepthf(perc);
        glClear(GL_DEPTH_BUFFER_BIT);
        ++numScissoredClears;
    }

    // Make sure everything was done in a single renderpass.
    EXPECT_EQ(getPerfCounters().renderPasses, 1u);
}

// Copy of ClearTest.InceptionScissorClears.
// Clears many small concentric rectangles using scissor regions.
TEST_P(VulkanPerformanceCounterTest, DrawThenInceptionScissorClears)
{
    // https://issuetracker.google.com/166809097
    ANGLE_SKIP_TEST_IF(IsQualcomm() && IsVulkan());

    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 0, 1, 0, &expected);

    angle::RNG rng;
    std::vector<GLColor> expectedColors;
    constexpr GLuint kSize = 16;

    // Create a square user FBO so we have more control over the dimensions.
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    GLRenderbuffer rbo;
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    glViewport(0, 0, kSize, kSize);

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    expectedColors.push_back(GLColor::red);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);

    // Expect rpCount+1, color(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    // TODO: Optimize scissored clears to use loadOp = CLEAR. anglebug.com/42263754
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);

    // Draw small concentric squares using scissor.
    // TODO(syoussefi): verify this
    [[maybe_unused]] uint64_t numScissoredClears = 0;
    // All clears are to a scissored render area.
    for (GLuint index = 1; index < (kSize - 1) / 2; index++)
    {
        glEnable(GL_SCISSOR_TEST);
        glScissor(index, index, kSize - (index * 2), kSize - (index * 2));
        ++numScissoredClears;

        GLColor color = RandomColor(&rng);
        expectedColors.push_back(color);
        Vector4 floatColor = color.toNormalizedVector();
        glClearColor(floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
        glClear(GL_COLOR_BUFFER_BIT);
    }

    ASSERT_GL_NO_ERROR();

    // Make sure everything was done in a single renderpass.
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Close the render pass to update the performance counters.
    std::vector<GLColor> actualColors(expectedColors.size());
    glReadPixels(0, kSize / 2, actualColors.size(), 1, GL_RGBA, GL_UNSIGNED_BYTE,
                 actualColors.data());
    EXPECT_EQ(expectedColors, actualColors);

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Test that color clears are respected after invalidate
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, ColorClearAfterInvalidate)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupForColorDepthOpsTest(&framebuffer, &texture, &renderbuffer);

    // Execute the scenario that this test is for:

    // color+depth invalidate, color+depth clear
    //
    // Expected:
    //   rpCount+1,
    //   depth(Clears+1, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    //   color(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 0, 1, 0, 0, 0, 0, &expected);
    setExpectedCountersForColorOps(getPerfCounters(), 1, 1, 0, 0, 1, 0, &expected);

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    // Invalidate (loadOp C=DONTCARE, D=DONTCARE)
    const GLenum discards[] = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, discards);
    ASSERT_GL_NO_ERROR();

    // Clear (loadOp C=CLEAR, D=CLEAR)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Save existing draw buffers
    GLint maxDrawBuffers = 0;
    glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
    std::vector<GLenum> savedDrawBuffers(maxDrawBuffers);
    for (int i = 0; i < maxDrawBuffers; i++)
        glGetIntegerv(GL_DRAW_BUFFER0 + i, (GLint *)&savedDrawBuffers[i]);

    // Draw depth-only
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    glDrawBuffers(0, nullptr);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    glDrawBuffers(maxDrawBuffers, savedDrawBuffers.data());
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    ASSERT_GL_NO_ERROR();

    // Invalidate depth only (storeOp should be C=STORE/D=CLEAR)
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done
    swapBuffers();
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    EXPECT_DEPTH_OP_COUNTERS(getPerfCounters(), expected);
    ASSERT_GL_NO_ERROR();
}

// Test that depth clears are picked up as loadOp even if a color blit is done in between.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, DepthClearThenColorBlitThenDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    GLFramebuffer framebuffer;
    GLTexture texture;
    GLRenderbuffer renderbuffer;
    setupForColorDepthOpsTest(&framebuffer, &texture, &renderbuffer);

    // Execute the scenario that this test is for:

    // color+depth clear, blit color as source, draw
    //
    // Expected:
    //   rpCount+1,
    //   depth(Clears+1, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    //   color(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForDepthOps(getPerfCounters(), 0, 1, 0, 0, 1, 0, &expected);
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glClearColor(0, 1, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Blit color into another FBO
    GLTexture destColor;
    glBindTexture(GL_TEXTURE_2D, destColor);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kOpsTestSize, kOpsTestSize);

    GLFramebuffer destFbo;
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFbo);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destColor, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);

    glBlitFramebuffer(0, 0, kOpsTestSize, kOpsTestSize, 0, 0, kOpsTestSize, kOpsTestSize,
                      GL_COLOR_BUFFER_BIT, GL_NEAREST);

    // Draw back to the original framebuffer
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
    drawQuad(program, essl1_shaders::PositionAttrib(), 1.f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    // Use swapBuffers and then check how many loads and stores were actually done.  The clear
    // applied to depth should be done as loadOp, not flushed during the blit.
    swapBuffers();
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
    adjustExpectedDepthStencilLoadStoreOpsForTileMemoryFallback(getPerfCounters(), &expected);
    EXPECT_DEPTH_OP_COUNTERS(getPerfCounters(), expected);
    ASSERT_GL_NO_ERROR();

    // Verify results
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Result of blit should be green
    glBindFramebuffer(GL_READ_FRAMEBUFFER, destFbo);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Ensure that image gets marked as defined after clear + invalidate + clear, and that we use
// LoadOp=Load for a renderpass which draws to it after the clear has been flushed with a blit.
TEST_P(VulkanPerformanceCounterTest, InvalidateThenRepeatedClearThenBlitThenDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    constexpr GLsizei kSize = 2;

    // tex[0] is what's being tested.  The others are helpers.
    GLTexture tex[3];
    for (int i = 0; i < 3; ++i)
    {
        glBindTexture(GL_TEXTURE_2D, tex[i]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
    }

    GLFramebuffer fbo[3];
    for (int i = 0; i < 3; ++i)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[i], 0);
    }

    // Expect rpCount+1, color(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);

    // Clear the image through fbo[0], and make sure the clear is flushed outside the render pass.
    glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Invalidate it such that the contents are marked as undefined. Note that regardless of the
    // marking, the image is cleared nevertheless.
    const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);

    // Clear it again to the same color.
    glClear(GL_COLOR_BUFFER_BIT);

    // Bind tex[0] to fbo[1] as the read fbo, and blit to fbo[2]
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[0], 0);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[2]);

    // Blit.  This causes the second clear of tex[0] to be flushed outside the render pass, which
    // may be optimized out.
    glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);

    // Switch back to fbo[0] and draw with blend.  If the second clear is dropped and the image
    // continues to be marked as invalidated, loadOp=DONT_CARE would be used instead of loadOp=LOAD.
    glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0);

    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Ensure that image gets marked as defined after clear + invalidate + clear, and that we use
// LoadOp=Load for a renderpass which draws to it after the clear has been flushed with read pixels.
TEST_P(VulkanPerformanceCounterTest, InvalidateThenRepeatedClearThenReadbackThenDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    constexpr GLsizei kSize = 2;

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);

    // Expect rpCount+1, color(Clears+0, Loads+1, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 1, 0, 1, 0, &expected);

    // Clear the image, and make sure the clear is flushed outside the render pass.
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Invalidate it such that the contents are marked as undefined.  Note that regarldess of the
    // marking, the image is cleared nevertheless.
    const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);

    // Clear it again to the same color, and make sure the clear is flushed outside the render pass,
    // which may be optimized out.
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Draw with blend.  If the second clear is dropped and the image continues to be marked as
    // invalidated, loadOp=DONT_CARE would be used instead of loadOp=LOAD.
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Test that draw after invalidate restores the contents of the color image.
TEST_P(VulkanPerformanceCounterTest, InvalidateThenDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    constexpr GLsizei kSize = 2;

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+0, Stores+1, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 0, 1, 0, &expected);

    ANGLE_GL_PROGRAM(blue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    drawQuad(blue, essl1_shaders::PositionAttrib(), 0);

    // Invalidate it such that the contents are marked as undefined
    const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);

    // Draw again.
    ANGLE_GL_PROGRAM(green, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(green, essl1_shaders::PositionAttrib(), 0);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Test that masked draw after invalidate does NOT restore the contents of the color image.
TEST_P(VulkanPerformanceCounterTest, InvalidateThenMaskedDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    constexpr GLsizei kSize = 2;

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);

    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 0, 0, 0, &expected);

    ANGLE_GL_PROGRAM(blue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    drawQuad(blue, essl1_shaders::PositionAttrib(), 0);

    // Invalidate it such that the contents are marked as undefined
    const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);

    // Draw again.
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    ANGLE_GL_PROGRAM(green, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(green, essl1_shaders::PositionAttrib(), 0);

    // Break the render pass
    glFinish();

    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);
}

// Tests that the submission counters count the implicit submission in eglSwapBuffers().
TEST_P(VulkanPerformanceCounterTest, VerifySubmitCountersForSwapBuffer)
{
    uint64_t expectedVkQueueSubmitCount      = getPerfCounters().vkQueueSubmitCallsTotal;
    uint64_t expectedCommandQueueSubmitCount = getPerfCounters().commandQueueSubmitCallsTotal;

    // One submission coming from clear and read back
    ++expectedVkQueueSubmitCount;
    ++expectedCommandQueueSubmitCount;

    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCount);
    EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCount);

    // One submission coming from draw and implicit submission from eglSwapBuffers
    ++expectedVkQueueSubmitCount;
    ++expectedCommandQueueSubmitCount;

    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 1.f);
    swapBuffers();

    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCount);
    EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCount);
}

// Tests that PreferSubmitAtFBOBoundary feature works properly. Bind to different FBO and should
// trigger submit of previous FBO. In this specific test, we switch to system default framebuffer
// which is always considered as "dirty".
TEST_P(VulkanPerformanceCounterTest, VerifySubmitCounterForSwitchUserFBOToSystemFramebuffer)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    uint64_t expectedCommandQueueSubmitCount = getPerfCounters().commandQueueSubmitCallsTotal;
    uint64_t expectedCommandQueueWaitSemaphoreCount =
        getPerfCounters().commandQueueWaitSemaphoresTotal;

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    // Draw
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    // One submission coming from glBindFramebuffer and draw
    ++expectedCommandQueueSubmitCount;
    // This submission should not wait for any semaphore.

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();

    EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCount);
    EXPECT_EQ(getPerfCounters().commandQueueWaitSemaphoresTotal,
              expectedCommandQueueWaitSemaphoreCount);

    // This submission must wait for ANI's semaphore
    ++expectedCommandQueueWaitSemaphoreCount;
    ++expectedCommandQueueSubmitCount;
    swapBuffers();
    EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCount);
    EXPECT_EQ(getPerfCounters().commandQueueWaitSemaphoresTotal,
              expectedCommandQueueWaitSemaphoreCount);
}

// Tests that PreferSubmitAtFBOBoundary feature works properly. Binding to a different FBO should
// trigger the submission of the previous FBO if enough workload has been accumulated. In this
// specific test, we test binding to a new user FBO after issuing the minimum amount of draw calls
// for submission.
TEST_P(VulkanPerformanceCounterTest, VerifySubmitCounterForSwitchUserFBOToDirtyUserFBO)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    uint64_t expectedCommandQueueSubmitCount = getPerfCounters().commandQueueSubmitCallsTotal;
    uint64_t expectedCommandQueueWaitSemaphoreCount =
        getPerfCounters().commandQueueWaitSemaphoresTotal;

    GLFramebuffer framebuffer1;
    GLTexture texture1;
    setupForColorOpsTest(&framebuffer1, &texture1);

    // Issue the draws. In case of preference to submit at FBO boundary, there is a minimum render
    // pass command count to submit. (Currently, the exception is if there is a clear or invalidate
    // command at the boundary, or if there are no in-flight commands. In those cases, the minimum
    // command count is ignored.)
    constexpr uint32_t kMinCommandCountToSubmit = 32;
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    for (uint32_t i = 0; i < kMinCommandCountToSubmit; i++)
    {
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    }
    ASSERT_GL_NO_ERROR();

    if (hasPreferSubmitAtFBOBoundary())
    {
        // One submission coming from glBindFramebuffer and draw calls.
        ++expectedCommandQueueSubmitCount;
        // This submission should not wait for any semaphore.
    }

    // Create and bind to a new FBO
    GLFramebuffer framebuffer2;
    GLTexture texture2;
    setupForColorOpsTest(&framebuffer2, &texture2);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    ++expectedCommandQueueSubmitCount;
    // This submission should not wait for ANI's semaphore
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCount);
    EXPECT_EQ(getPerfCounters().commandQueueWaitSemaphoresTotal,
              expectedCommandQueueWaitSemaphoreCount);
}

// Ensure that glFlush doesn't lead to vkQueueSubmit if there's nothing to submit.
TEST_P(VulkanPerformanceCounterTest, UnnecessaryFlushDoesntCauseSubmission)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    swapBuffers();
    uint64_t expectedVkQueueSubmitCalls = getPerfCounters().vkQueueSubmitCallsTotal;

    glFlush();
    glFlush();
    glFlush();

    // Nothing was recorded, so there shouldn't be anything to flush.
    glFinish();
    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCalls);

    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // One submission for the above readback
    ++expectedVkQueueSubmitCalls;

    glFinish();
    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCalls);

    glFlush();
    glFlush();
    glFlush();

    // No additional submissions since last one
    glFinish();
    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCalls);
}

// Ensure that glFenceSync doesn't lead to vkQueueSubmit if there's nothing to submit.
TEST_P(VulkanPerformanceCounterTest, SyncWihtoutCommandsDoesntCauseSubmission)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    swapBuffers();
    uint64_t expectedVkQueueSubmitCalls = getPerfCounters().vkQueueSubmitCallsTotal;

    glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

    // Nothing was recorded, so there shouldn't be anything to flush.
    glFinish();
    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expectedVkQueueSubmitCalls);
}

// In single-buffer mode, ensure that unnecessary eglSwapBuffers is completely ignored (i.e. doesn't
// lead to a command queue submission, consuming a submission serial).  Used to verify an
// optimization that ensures CPU throttling doesn't incur GPU bubbles with unnecessary
// eglSwapBuffers calls.
TEST_P(VulkanPerformanceCounterTest_SingleBuffer, SwapBuffersAfterFlushIgnored)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    // Set mode to single buffer
    EXPECT_EGL_TRUE(eglSurfaceAttrib(getEGLWindow()->getDisplay(), getEGLWindow()->getSurface(),
                                     EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER));

    // Swap buffers so mode switch takes effect.
    swapBuffers();
    uint64_t expectedCommandQueueSubmitCalls = getPerfCounters().commandQueueSubmitCallsTotal;

    // Further swap buffers should be ineffective.
    swapBuffers();
    swapBuffers();
    swapBuffers();
    swapBuffers();

    EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCalls);

    // Issue commands and flush them.
    glClearColor(1, 0, 0, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // One submission for the above readback
    ++expectedCommandQueueSubmitCalls;
    EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCalls);

    // Further swap buffers should again be ineffective.
    swapBuffers();
    swapBuffers();
    swapBuffers();
    swapBuffers();
    swapBuffers();

    EXPECT_EQ(getPerfCounters().commandQueueSubmitCallsTotal, expectedCommandQueueSubmitCalls);
}

// Verifies that we share Texture descriptor sets between programs.
TEST_P(VulkanPerformanceCounterTest, TextureDescriptorsAreShared)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(testProgram1, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    ANGLE_GL_PROGRAM(testProgram2, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());

    GLTexture texture1;
    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    setupQuadVertexBuffer(0.5f, 1.0f);

    glUseProgram(testProgram1);

    ASSERT_GL_NO_ERROR();

    glBindTexture(GL_TEXTURE_2D, texture1);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindTexture(GL_TEXTURE_2D, texture2);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    ASSERT_GL_NO_ERROR();

    GLuint expectedCacheMisses = getPerfCounters().textureDescriptorSetCacheMisses;
    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        EXPECT_GT(expectedCacheMisses, 0u);
    }

    glUseProgram(testProgram2);

    glBindTexture(GL_TEXTURE_2D, texture1);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindTexture(GL_TEXTURE_2D, texture2);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    ASSERT_GL_NO_ERROR();

    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        GLuint actualCacheMisses = getPerfCounters().textureDescriptorSetCacheMisses;
        EXPECT_EQ(expectedCacheMisses, actualCacheMisses);
    }
    else
    {
        GLint descriptorSetAllocations = getPerfCounters().descriptorSetAllocations;
        EXPECT_EQ(4, descriptorSetAllocations);
    }
}

// Verifies that we share Uniform Buffer descriptor sets between programs.
TEST_P(VulkanPerformanceCounterTest, UniformBufferDescriptorsAreShared)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr char kFS[] = R"(#version 300 es
precision mediump float;
out vec4 color;
uniform block {
   vec4 uniColor;
};

void main() {
    color = uniColor;
})";

    ANGLE_GL_PROGRAM(testProgram1, essl3_shaders::vs::Simple(), kFS);
    ANGLE_GL_PROGRAM(testProgram2, essl3_shaders::vs::Simple(), kFS);

    Vector4 red(1, 0, 0, 1);
    Vector4 green(0, 1, 0, 1);

    GLBuffer ubo1;
    glBindBuffer(GL_UNIFORM_BUFFER, ubo1);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(Vector4), red.data(), GL_STATIC_DRAW);

    GLBuffer ubo2;
    glBindBuffer(GL_UNIFORM_BUFFER, ubo2);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(Vector4), green.data(), GL_STATIC_DRAW);

    setupQuadVertexBuffer(0.5f, 1.0f);

    glUseProgram(testProgram1);

    ASSERT_GL_NO_ERROR();

    glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo1);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo2);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    ASSERT_GL_NO_ERROR();

    GLuint expectedCacheMisses = getPerfCounters().uniformBuffersDescriptorSetCacheMisses;
    GLuint totalAllocationsAtFirstProgram = getPerfCounters().descriptorSetAllocations;
    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        EXPECT_GT(expectedCacheMisses, 0u);
    }

    glUseProgram(testProgram2);

    glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo1);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo2);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    ASSERT_GL_NO_ERROR();

    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        GLuint actualCacheMisses = getPerfCounters().uniformBuffersDescriptorSetCacheMisses;
        EXPECT_EQ(expectedCacheMisses, actualCacheMisses);
    }
    else
    {
        // Because between program switch there is no submit and wait for finish, we expect draw
        // with second program will end up allocating same number of descriptorSets as the draws
        // with the first program.
        GLuint totalAllocationsAtSecondProgram = getPerfCounters().descriptorSetAllocations;
        EXPECT_EQ(totalAllocationsAtFirstProgram * 2, totalAllocationsAtSecondProgram);
    }
}

// Test modifying texture size and render to it does not cause VkFramebuffer cache explode
TEST_P(VulkanPerformanceCounterTest, ResizeFBOAttachedTexture)
{
    ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());

    int32_t framebufferCacheSizeBefore = getPerfCounters().framebufferCacheSize;
    GLTexture texture;
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    for (GLint texWidth = 1; texWidth <= 10; texWidth++)
    {
        for (GLint texHeight = 1; texHeight <= 10; texHeight++)
        {
            // Allocate texture
            glBindTexture(GL_TEXTURE_2D, texture);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA,
                         GL_UNSIGNED_BYTE, nullptr);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
            ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

            // Draw to FBO backed by the texture
            glUseProgram(blueProgram);
            drawQuad(blueProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
            ASSERT_GL_NO_ERROR();
            EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
        }
    }
    int32_t framebufferCacheSizeAfter    = getPerfCounters().framebufferCacheSize;
    int32_t framebufferCacheSizeIncrease = framebufferCacheSizeAfter - framebufferCacheSizeBefore;
    int32_t expectedFramebufferCacheSizeIncrease = (hasSupportsImagelessFramebuffer()) ? 0 : 1;
    printf("\tframebufferCacheCountIncrease:%u\n", framebufferCacheSizeIncrease);
    // We should not cache obsolete VkImages. Only current VkImage should be cached.
    EXPECT_EQ(framebufferCacheSizeIncrease, expectedFramebufferCacheSizeIncrease);
}

// Test calling glTexParameteri(GL_TEXTURE_SWIZZLE_*) on a texture that attached to FBO with the
// same value did not cause VkFramebuffer cache explode
TEST_P(VulkanPerformanceCounterTest, SetTextureSwizzleWithSameValueOnFBOAttachedTexture)
{
    ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());

    // Allocate texture
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    int32_t framebufferCacheSizeBefore = getPerfCounters().framebufferCacheSize;
    for (GLint loop = 0; loop < 10; loop++)
    {
        // Draw to FBO
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glUseProgram(blueProgram);
        drawQuad(blueProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);

        // Sample from texture
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
        drawQuad(textureProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    }
    // Now make fbo current and read out cache size and verify it does not grow just because of
    // swizzle update even though there is no actual change.
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glUseProgram(blueProgram);
    drawQuad(blueProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
    ASSERT_GL_NO_ERROR();
    int32_t framebufferCacheSizeAfter    = getPerfCounters().framebufferCacheSize;
    int32_t framebufferCacheSizeIncrease = framebufferCacheSizeAfter - framebufferCacheSizeBefore;
    int32_t expectedFramebufferCacheSizeIncrease = (hasSupportsImagelessFramebuffer()) ? 0 : 1;
    // This should not cause frame buffer cache increase.
    EXPECT_EQ(framebufferCacheSizeIncrease, expectedFramebufferCacheSizeIncrease);
}

// Test calling glTexParameteri(GL_TEXTURE_SWIZZLE_*) on a texture that attached to FBO with
// different value did not cause VkFramebuffer cache explode
TEST_P(VulkanPerformanceCounterTest, SetTextureSwizzleWithDifferentValueOnFBOAttachedTexture)
{
    ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());

    // Allocate texture
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    GLColor expectedColors[] = {GLColor::black,   GLColor::black,  GLColor::blue,  GLColor::black,
                                GLColor::black,   GLColor::blue,   GLColor::green, GLColor::green,
                                GLColor::cyan,    GLColor::black,  GLColor::black, GLColor::blue,
                                GLColor::black,   GLColor::black,  GLColor::blue,  GLColor::green,
                                GLColor::green,   GLColor::cyan,   GLColor::red,   GLColor::red,
                                GLColor::magenta, GLColor::red,    GLColor::red,   GLColor::magenta,
                                GLColor::yellow,  GLColor::yellow, GLColor::white};
    int32_t framebufferCacheSizeBefore = getPerfCounters().framebufferCacheSize;
    int loop                           = 0;
    for (GLenum swizzle_R = GL_RED; swizzle_R <= GL_BLUE; swizzle_R++)
    {
        for (GLenum swizzle_G = GL_RED; swizzle_G <= GL_BLUE; swizzle_G++)
        {
            for (GLenum swizzle_B = GL_RED; swizzle_B <= GL_BLUE; swizzle_B++)
            {
                // Draw to FBO
                glBindFramebuffer(GL_FRAMEBUFFER, fbo);
                glUseProgram(blueProgram);
                drawQuad(blueProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);

                // Sample from texture
                glBindFramebuffer(GL_FRAMEBUFFER, 0);
                glClearColor(1, 0, 0, 1);
                glClear(GL_COLOR_BUFFER_BIT);
                glBindTexture(GL_TEXTURE_2D, texture);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, swizzle_R);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, swizzle_G);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, swizzle_B);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
                drawQuad(textureProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
                EXPECT_PIXEL_COLOR_EQ(0, 0, expectedColors[loop]);
                loop++;
            }
        }
    }
    // Now make fbo current and read out cache size and verify it does not grow just because of
    // swizzle update even though there is no actual change.
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glUseProgram(blueProgram);
    drawQuad(blueProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
    ASSERT_GL_NO_ERROR();
    int32_t framebufferCacheSizeAfter    = getPerfCounters().framebufferCacheSize;
    int32_t framebufferCacheSizeIncrease = framebufferCacheSizeAfter - framebufferCacheSizeBefore;
    int32_t expectedFramebufferCacheSizeIncrease = (hasSupportsImagelessFramebuffer()) ? 0 : 1;
    // This should not cause frame buffer cache increase.
    EXPECT_EQ(framebufferCacheSizeIncrease, expectedFramebufferCacheSizeIncrease);
}

// Test calling glEGLImageTargetTexture2DOES repeatedly with same arguments will not leak
// DescriptorSets. This is the same usage pattern surafceflinger is doing with notification shades
// except with AHB.
TEST_P(VulkanPerformanceCounterTest, Source2DAndRepeatedlyRespecifyTarget2DWithSameParameter)
{
    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image") ||
                       !IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_image_base") ||
                       !IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_gl_texture_2D_image"));

    ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());

    // Create a source 2D texture
    GLTexture sourceTexture;
    glBindTexture(GL_TEXTURE_2D, sourceTexture);
    GLubyte kLinearColor[] = {132, 55, 219, 255};
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 static_cast<void *>(&kLinearColor));
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    // Create an eglImage from the source texture
    constexpr EGLint kDefaultAttribs[] = {EGL_IMAGE_PRESERVED, EGL_TRUE, EGL_NONE};
    EGLClientBuffer clientBuffer =
        reinterpret_cast<EGLClientBuffer>(static_cast<size_t>(sourceTexture));
    EGLImageKHR image = eglCreateImageKHR(window->getDisplay(), window->getContext(),
                                          EGL_GL_TEXTURE_2D_KHR, clientBuffer, kDefaultAttribs);
    ASSERT_EGL_SUCCESS();

    // Create the target in a loop
    GLTexture targetTexture;
    constexpr size_t kMaxLoop            = 20;
    GLint descriptorSetAllocationsBefore = 0;
    GLint textureDescriptorSetCacheTotalSizeBefore =
        getPerfCounters().textureDescriptorSetCacheTotalSize;
    for (size_t loop = 0; loop < kMaxLoop; loop++)
    {
        //  Create a target texture from the image
        glBindTexture(GL_TEXTURE_2D, targetTexture);
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);

        // Disable mipmapping
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        // Draw a quad with the target texture
        glBindTexture(GL_TEXTURE_2D, targetTexture);
        drawQuad(textureProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
        // Expect that the rendered quad's color is the same as the reference color with a tolerance
        // of 1
        EXPECT_PIXEL_NEAR(0, 0, kLinearColor[0], kLinearColor[1], kLinearColor[2], kLinearColor[3],
                          1);
        if (loop == 0)
        {
            descriptorSetAllocationsBefore = getPerfCounters().descriptorSetAllocations;
        }
    }
    size_t descriptorSetAllocationsIncrease =
        getPerfCounters().descriptorSetAllocations - descriptorSetAllocationsBefore;
    GLint textureDescriptorSetCacheTotalSizeIncrease =
        getPerfCounters().textureDescriptorSetCacheTotalSize -
        textureDescriptorSetCacheTotalSizeBefore;

    if (isFeatureEnabled(Feature::DescriptorSetCache))
    {
        // We don't expect descriptorSet cache to keep growing
        EXPECT_EQ(1, textureDescriptorSetCacheTotalSizeIncrease);
    }
    else
    {
        // Because we call EXPECT_PIXEL_NEAR which will wait for draw to finish, we don't expect
        // descriptorSet allocation to keep growing. The underline reuse logic is implementation
        // detail (as of now it will not reuse util the pool is full), but we expect it will not
        // increasing for every iteration.
        EXPECT_GE(kMaxLoop - 1, descriptorSetAllocationsIncrease);
    }
    // Clean up
    eglDestroyImageKHR(window->getDisplay(), image);
}

// Test create, use and then destroy a texture does not increase number of DescriptoprSets.
// DesriptorSet should be destroyed promptly. We are seeing this type of usage pattern in
// surfaceflinger, except that the texture is created from AHB (and AHB keeps changing as well).
TEST_P(VulkanPerformanceCounterTest, CreateDestroyTextureDoesNotIncreaseDescriptporSetCache)
{
    ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());

    // Respecify texture in a loop
    GLubyte kLinearColor[]    = {132, 55, 219, 255};
    constexpr size_t kMaxLoop = 2;
    GLint textureDescriptorSetCacheTotalSizeBefore =
        getPerfCounters().textureDescriptorSetCacheTotalSize;
    for (size_t loop = 0; loop < kMaxLoop; loop++)
    {
        // Create a 2D texture
        GLTexture sourceTexture;
        glBindTexture(GL_TEXTURE_2D, sourceTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     static_cast<void *>(&kLinearColor));
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        drawQuad(textureProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
        // Expect that the rendered quad's color is the same as the reference color with a tolerance
        // of 1
        EXPECT_PIXEL_NEAR(0, 0, kLinearColor[0], kLinearColor[1], kLinearColor[2], kLinearColor[3],
                          1);
    }
    GLint textureDescriptorSetCacheTotalSizeIncrease =
        getPerfCounters().textureDescriptorSetCacheTotalSize -
        textureDescriptorSetCacheTotalSizeBefore;

    // We don't expect descriptorSet cache to keep growing
    EXPECT_EQ(0, textureDescriptorSetCacheTotalSizeIncrease);
}

// Similar to CreateDestroyTextureDoesNotIncreaseDescriptporSetCache, but for shader image.
TEST_P(VulkanPerformanceCounterTest_ES31,
       CreateDestroyTextureDoesNotIncreaseComputeShaderDescriptporSetCache)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr char kCS[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(r32ui, binding = 0) readonly uniform highp uimage2D uImage_1;
layout(r32ui, binding = 1) writeonly uniform highp uimage2D uImage_2;
void main()
{
    uvec4 value = imageLoad(uImage_1, ivec2(gl_LocalInvocationID.xy));
    imageStore(uImage_2, ivec2(gl_LocalInvocationID.xy), value);
})";
    ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
    glUseProgram(program);

    constexpr int kWidth = 1, kHeight = 1;
    constexpr GLuint kInputValues[2][1] = {{200}, {100}};
    constexpr size_t kMaxLoop           = 20;
    GLint shaderResourceDescriptorSetCacheTotalSizeBefore =
        getPerfCounters().shaderResourcesDescriptorSetCacheTotalSize;
    for (size_t loop = 0; loop < kMaxLoop; loop++)
    {
        // Respecify texture in a loop
        GLTexture texture0;
        glBindTexture(GL_TEXTURE_2D, texture0);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
                        kInputValues[0]);

        GLTexture texture1;
        glBindTexture(GL_TEXTURE_2D, texture1);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kWidth, kHeight);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
                        kInputValues[1]);

        glBindImageTexture(0, texture0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
        glBindImageTexture(1, texture1, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
        glDispatchCompute(1, 1, 1);
    }
    glFinish();
    GLint shaderResourceDescriptorSetCacheTotalSizeIncrease =
        getPerfCounters().shaderResourcesDescriptorSetCacheTotalSize -
        shaderResourceDescriptorSetCacheTotalSizeBefore;

    // We don't expect descriptorSet cache to keep growing
    EXPECT_EQ(0, shaderResourceDescriptorSetCacheTotalSizeIncrease);
}

// Similar to CreateDestroyTextureDoesNotIncreaseDescriptporSetCache, but for atomic acounter
// buffer.
TEST_P(VulkanPerformanceCounterTest_ES31, DestroyAtomicCounterBufferAlsoDestroyDescriptporSetCache)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    constexpr char kFS[] =
        "#version 310 es\n"
        "precision highp float;\n"
        "layout(binding = 0, offset = 4) uniform atomic_uint ac;\n"
        "out highp vec4 my_color;\n"
        "void main()\n"
        "{\n"
        "    uint a1 = atomicCounter(ac);\n"
        "    my_color = vec4(float(a1)/255.0, 0.0, 0.0, 1.0);\n"
        "}\n";
    ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);

    // Warm up. Make a draw to ensure other descriptorSets are created if needed.
    GLBuffer intialBuffer;
    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, intialBuffer);
    uint32_t bufferData[3] = {0, 0u, 0u};
    glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
    glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, intialBuffer);
    drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
    GLColor expectedColor = GLColor::black;
    EXPECT_PIXEL_COLOR_EQ(0, 0, expectedColor);

    GLint DescriptorSetCacheTotalSizeBefore = getPerfCounters().descriptorSetCacheTotalSize;

    // Create atomic counter buffer and use it and then destroy it.
    constexpr int kBufferCount = 16;
    GLBuffer paddingBuffers[kBufferCount];
    for (uint32_t i = 0; i < kBufferCount; i++)
    {
        // Allocate a padding buffer so that atomicCounterBuffer will be allocated in different
        // offset
        glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, paddingBuffers[i]);
        glBufferData(GL_ATOMIC_COUNTER_BUFFER, 256, nullptr, GL_STATIC_DRAW);
        // Allocate, use, destroy atomic counter buffer
        GLBuffer atomicCounterBuffer;
        glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicCounterBuffer);
        bufferData[1] = i;
        glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
        glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicCounterBuffer);
        drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
        expectedColor.R = bufferData[1];
        EXPECT_PIXEL_COLOR_EQ(0, 0, expectedColor);
    }
    ASSERT_GL_NO_ERROR();

    GLint DescriptorSetCacheTotalSizeIncrease =
        getPerfCounters().descriptorSetCacheTotalSize - DescriptorSetCacheTotalSizeBefore;
    // We expect most of descriptorSet caches for temporary atomic counter buffers gets destroyed.
    // Give extra room in case a new descriptorSet is allocated due to a new driver uniform buffer
    // gets allocated.
    EXPECT_LT(DescriptorSetCacheTotalSizeIncrease, 2);
}

// Regression test for a bug in the Vulkan backend, where a perf warning added after
// serials for outside render pass commands were exhausted led to an assertion failure.
// http://issuetracker.google.com/375661776
TEST_P(VulkanPerformanceCounterTest_ES31, RunOutOfReservedOutsideRenderPassSerial)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // Step 1: Draw to start a render pass.
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);

    // Step 2: Switch to fbo and clear it to set mRenderPassCommandBuffer to null,
    // but keep the render pass open.
    GLTexture fbTexture;
    glBindTexture(GL_TEXTURE_2D, fbTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbTexture, 0);

    glClear(GL_COLOR_BUFFER_BIT);

    // Step 3: Run > kMaxReservedOutsideRenderPassQueueSerials compute with glMemoryBarrier
    // to trigger the "Running out of reserved outsideRenderPass queueSerial" path.
    constexpr char kCSSource[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(std140, binding=0) buffer buf {
vec4 outData;
};
void main()
{
outData = vec4(1.0, 1.0, 1.0, 1.0);
})";

    ANGLE_GL_COMPUTE_PROGRAM(csProgram, kCSSource);
    glUseProgram(csProgram);

    GLBuffer ssbo;
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    glBufferData(GL_SHADER_STORAGE_BUFFER, 16, nullptr, GL_STREAM_DRAW);

    for (int i = 0; i < 100; i++)
    {
        glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
        glDispatchCompute(1, 1, 1);
    }
    EXPECT_GL_NO_ERROR();

    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
}

// Test that post-render-pass-to-swapchain glFenceSync followed by eglSwapBuffers incurs only a
// single submission.
TEST_P(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps, FenceThenSwapBuffers)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    angle::VulkanPerfCounters expected;

    // Expect rpCount+1, depth(Clears+0, Loads+0, LoadNones+0, Stores+0, StoreNones+0),
    setExpectedCountersForDepthOps(getPerfCounters(), 1, 0, 0, 0, 0, 0, &expected);
    expected.vkQueueSubmitCallsTotal = getPerfCounters().vkQueueSubmitCallsTotal + 1;

    // Start a render pass and render to the surface.  Enable depth write so the depth/stencil image
    // is written to.
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // Issue a fence
    glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

    EXPECT_EQ(getPerfCounters().renderPasses, expected.renderPasses);

    // Swap buffers.  The depth/stencil attachment's storeOp should be optimized to DONT_CARE.  This
    // would not have been possible if the previous glFenceSync caused a submission.
    swapBuffers();

    EXPECT_EQ(getPerfCounters().vkQueueSubmitCallsTotal, expected.vkQueueSubmitCallsTotal);
    EXPECT_DEPTH_OP_COUNTERS(getPerfCounters(), expected);
}

// Verify that ending transform feedback after a render pass is closed, doesn't cause the following
// render pass to close when the transform feedback buffer is used.
TEST_P(VulkanPerformanceCounterTest, EndXfbAfterRenderPassClosed)
{
    // There should be two render passes; one for the transform feedback draw, one for the other two
    // draw calls.
    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 2;

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // Set the program's transform feedback varyings (just gl_Position)
    std::vector<std::string> tfVaryings;
    tfVaryings.push_back("gl_Position");
    ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(drawRed, essl3_shaders::vs::SimpleForPoints(),
                                        essl3_shaders::fs::Red(), tfVaryings,
                                        GL_INTERLEAVED_ATTRIBS);

    glUseProgram(drawRed);
    GLint positionLocation = glGetAttribLocation(drawRed, essl1_shaders::PositionAttrib());

    const GLfloat vertices[] = {
        -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f,
        -0.5f, 0.5f, 0.5f, 0.5f,  -0.5f, 0.5f, 0.5f, 0.5f,  0.5f,
    };

    glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glEnableVertexAttribArray(positionLocation);

    // Bind the buffer for transform feedback output and start transform feedback
    GLBuffer xfbBuffer;
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 100, nullptr, GL_STATIC_DRAW);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfbBuffer);
    glBeginTransformFeedback(GL_POINTS);

    glDrawArrays(GL_POINTS, 0, 6);

    // Break the render pass
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);

    // End transform feedback after the render pass is closed
    glEndTransformFeedback();

    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
    EXPECT_GL_NO_ERROR();

    // Issue an unrelated draw call.
    ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
    drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.0f);

    // Issue a draw call using the transform feedback buffer.
    glBindBuffer(GL_ARRAY_BUFFER, xfbBuffer);
    glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(positionLocation);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(drawRed);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    const int w = getWindowWidth();
    const int h = getWindowHeight();

    EXPECT_PIXEL_RECT_EQ(0, 0, w, h / 4, GLColor::black);
    EXPECT_PIXEL_RECT_EQ(0, 3 * h / 4, w, h / 4, GLColor::black);
    EXPECT_PIXEL_RECT_EQ(0, h / 4, w / 4, h / 2, GLColor::black);
    EXPECT_PIXEL_RECT_EQ(3 * w / 4, h / 4, w / 4, h / 2, GLColor::black);

    EXPECT_PIXEL_RECT_EQ(w / 4, h / 4, w / 2, h / 2, GLColor::red);
    EXPECT_GL_NO_ERROR();

    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);
}

// Verify that monolithic pipeline handles correctly replace the linked pipelines, if
// VK_EXT_graphics_pipeline_library is supported.
TEST_P(VulkanPerformanceCounterTest, AsyncMonolithicPipelineCreation)
{
    const bool hasAsyncMonolithicPipelineCreation =
        isFeatureEnabled(Feature::SupportsGraphicsPipelineLibrary) &&
        isFeatureEnabled(Feature::PreferMonolithicPipelinesOverLibraries);
    ANGLE_SKIP_TEST_IF(!hasAsyncMonolithicPipelineCreation);

    uint64_t expectedMonolithicPipelineCreationCount =
        getPerfCounters().monolithicPipelineCreation + 2;

    // Create two programs:
    ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());

    // Ping pong between the programs, letting async monolithic pipeline creation happen.
    uint32_t drawCount                 = 0;
    constexpr uint32_t kDrawCountLimit = 200;

    while (getPerfCounters().monolithicPipelineCreation < expectedMonolithicPipelineCreationCount)
    {
        drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.0f);
        drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.0f);

        ++drawCount;
        if (drawCount > kDrawCountLimit)
        {
            drawCount = 0;
            EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
        }
    }

    // Make sure the monolithic pipelines are replaced correctly
    drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}

// Verify that changing framebuffer and back doesn't break the render pass.
TEST_P(VulkanPerformanceCounterTest, FBOChangeAndBackDoesNotBreakRenderPass)
{
    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);

    // Verify render pass count.
    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}

// Verify that changing framebuffer and issue a (nop or deferred) clear and change framebuffer back
// doesn't break the render pass.
TEST_P(VulkanPerformanceCounterTest, FBOChangeAndClearAndBackDoesNotBreakRenderPass)
{
    // switch to FBO and issue clear on fbo and then switch back to default framebuffer
    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);  // clear to green
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);

    // switch to FBO and issue a deferred clear on fbo and then switch back to default framebuffer
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0);

    // Verify render pass count.
    EXPECT_EQ(getPerfCounters().renderPasses, expectedRenderPassCount);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}

// Test that just switching programs without breaking the renderpass
// doesn't cause updates to GraphicsDriverUniforms
TEST_P(VulkanPerformanceCounterTest, NoUpdatesToGraphicsDriverUniformsOnProgramChange)
{
    // Create 2 programs and switch between them
    ANGLE_GL_PROGRAM(program1, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    ANGLE_GL_PROGRAM(program2, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());

    GLFramebuffer framebuffer;
    GLTexture texture;
    setupForColorOpsTest(&framebuffer, &texture);

    glUseProgram(program1);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuad(program1, essl1_shaders::PositionAttrib(), 0);
    uint64_t program1Count = getPerfCounters().graphicsDriverUniformsUpdated;

    glUseProgram(program2);
    drawQuad(program2, essl1_shaders::PositionAttrib(), 0);
    uint64_t program2Count = getPerfCounters().graphicsDriverUniformsUpdated;

    // Verify vkCmdUpdatePushConstants perf counter
    EXPECT_EQ(program1Count, program2Count);

    glUseProgram(program1);
    drawQuad(program1, essl1_shaders::PositionAttrib(), 0);
    program1Count = getPerfCounters().graphicsDriverUniformsUpdated;

    // Verify vkCmdUpdatePushConstants perf counter
    EXPECT_EQ(program1Count, program2Count);

    // Verify pixel color
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Now that we have broken the render pass expect a call to vkCmdUpdatePushConstants
    // even if using the same program
    glUseProgram(program1);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuad(program1, essl1_shaders::PositionAttrib(), 0);
    program1Count = getPerfCounters().graphicsDriverUniformsUpdated;

    // Verify vkCmdUpdatePushConstants perf counter
    EXPECT_EQ(program1Count, program2Count + 1);
}

// This is test for optimization in vulkan backend. efootball_pes_2021 usage shows this usage
// pattern and we expect implementation to reuse the storage for performance.
TEST_P(VulkanPerformanceCounterTest,
       BufferDataWithSizeFollowedByZeroAndThenSizeAgainShouldReuseStorage)
{
    GLBuffer buffer;
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    constexpr size_t count = 288;
    std::array<uint32_t, count> data;
    constexpr size_t bufferSize = data.size() * sizeof(uint32_t);
    data.fill(0x1234567);

    glBufferData(GL_ARRAY_BUFFER, bufferSize, data.data(), GL_DYNAMIC_DRAW);
    glBufferData(GL_ARRAY_BUFFER, 0, nullptr, GL_DYNAMIC_DRAW);
    // This should get back the original storage with proper BufferVk optimization
    data.fill(0x89abcdef);
    uint64_t expectedSuballocationCalls = getPerfCounters().bufferSuballocationCalls;
    glBufferData(GL_ARRAY_BUFFER, bufferSize, data.data(), GL_DYNAMIC_DRAW);
    EXPECT_EQ(getPerfCounters().bufferSuballocationCalls, expectedSuballocationCalls);

    uint32_t *mapPtr = reinterpret_cast<uint32_t *>(
        glMapBufferRange(GL_ARRAY_BUFFER, 0, bufferSize, GL_MAP_READ_BIT));
    ASSERT_NE(nullptr, mapPtr);
    EXPECT_EQ(0x89abcdef, mapPtr[0]);
    EXPECT_EQ(0x89abcdef, mapPtr[count - 1]);
    glUnmapBuffer(GL_ARRAY_BUFFER);
    ASSERT_GL_NO_ERROR();
}

// Regression test for a bug where submitting the outside command buffer during flushing staged
// updates did not properly update the command buffer state.
TEST_P(VulkanPerformanceCounterTest, SubmittingOutsideCommandBufferAssertIsOpen)
{
    // If VK_EXT_host_image_copy is used, uploads will all be done on the CPU and there would be no
    // submissions.
    ANGLE_SKIP_TEST_IF(hasSupportsHostImageCopy());

    GLTexture tex;
    GLFramebuffer fbo;
    setupForColorOpsTest(&fbo, &tex);

    uint64_t submitCommandsCount = getPerfCounters().vkQueueSubmitCallsTotal;

    ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());
    glUseProgram(textureProgram);
    GLint textureLoc = glGetUniformLocation(textureProgram, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, textureLoc);
    glUniform1i(textureLoc, 0);

    // This loop should update texture with multiple staged updates. When kMaxBufferToImageCopySize
    // threshold reached, outside command buffer will be submitted in the middle of staged updates
    // flushing.
    constexpr GLsizei kMaxOutsideRPCommandsSubmitCount = 10;
    constexpr GLsizei kTexDim                          = 1024;
    constexpr GLint kMaxSubOffset                      = 10;
    std::vector<GLColor> kInitialData(kTexDim * kTexDim, GLColor::green);
    while (getPerfCounters().vkQueueSubmitCallsTotal <
           submitCommandsCount + kMaxOutsideRPCommandsSubmitCount)
    {
        GLTexture newTexture;
        glBindTexture(GL_TEXTURE_2D, newTexture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        // Provide data for the texture without previously defining a storage.
        // This should prevent immediate staged update flushing.
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexDim, kTexDim, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     kInitialData.data());
        // Append staged updates...
        for (GLsizei offset = 1; offset <= kMaxSubOffset; ++offset)
        {
            glTexSubImage2D(GL_TEXTURE_2D, 0, offset, offset, kTexDim - offset, kTexDim - offset,
                            GL_RGBA, GL_UNSIGNED_BYTE, kInitialData.data());
        }
        // This will flush multiple staged updates
        drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f);
        ASSERT_GL_NO_ERROR();
    }

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Demonstrate the WAW syncVal bug https://anglebug.com/400789178
TEST_P(VulkanPerformanceCounterTest, DepthBufferWriteThenReadThenWriteInThreeRenderPasses)
{
    ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());

    constexpr GLsizei kWidth  = 4;
    constexpr GLsizei kHeight = 4;

    GLTexture colorTexture1;
    glBindTexture(GL_TEXTURE_2D, colorTexture1);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);

    GLTexture colorTexture2;
    glBindTexture(GL_TEXTURE_2D, colorTexture2);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);

    GLRenderbuffer depthStencil;
    glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kWidth, kHeight);

    GLFramebuffer fbo1;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture1, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencil);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencil);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    glViewport(0, 0, kWidth, kHeight);

    GLFramebuffer fbo2;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture2, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencil);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencil);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    glViewport(0, 0, kWidth, kHeight);

    GLfloat depthValue = 0.0f;
    // Draw to fbo1 with depth buffer write
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(depthValue * 0.5f + 0.5f);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), depthValue);

    // Draw to fbo2 with read only depth buffer
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    glClear(GL_COLOR_BUFFER_BIT);
    glDepthMask(GL_FALSE);
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), depthValue);

    std::array<GLenum, 2> attachments = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 2, attachments.data());

    // Draw to fbo1 with depth buffer write
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    glDepthMask(GL_TRUE);
    drawQuad(drawBlue, essl1_shaders::PositionAttrib(), depthValue);
    glFinish();
}

// Verifies that clear followed by eglSwapBuffers() on multisampled FBO does not result
// extra resolve pass, if the surface is double-buffered and when the egl swap behavior
// is EGL_BUFFER_DESTROYED
TEST_P(VulkanPerformanceCounterTest_MSAA, SwapAfterClearOnMultisampledFBOShouldNotResolve)
{
    // Skip test if
    // 1) the EGL Surface is single-buffered or
    // 2) the EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED
    EGLint renderBufferType;
    eglQuerySurface(getEGLWindow()->getDisplay(), getEGLWindow()->getSurface(), EGL_RENDER_BUFFER,
                    &renderBufferType);
    EGLint swapBehavior;
    eglQuerySurface(getEGLWindow()->getDisplay(), getEGLWindow()->getSurface(), EGL_SWAP_BEHAVIOR,
                    &swapBehavior);
    ANGLE_SKIP_TEST_IF(
        !(renderBufferType == EGL_BACK_BUFFER && swapBehavior == EGL_BUFFER_DESTROYED));

    uint32_t expectedResolvesSubpass = getPerfCounters().swapchainResolveInSubpass;
    uint32_t expectedResolvesOutside = getPerfCounters().swapchainResolveOutsideSubpass;
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    swapBuffers();
    EXPECT_EQ(getPerfCounters().swapchainResolveInSubpass, expectedResolvesSubpass);
    EXPECT_EQ(getPerfCounters().swapchainResolveOutsideSubpass, expectedResolvesOutside);
}

// MSAA draw and the blit that uses sub-pass resolve and then followed by masked clear
TEST_P(VulkanPerformanceCounterTest_MSAA, MultisampleDrawThenBlitThenMaskedClear)
{
    // http://anglebug.com/40096654
    ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());

    ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
    ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());

    constexpr GLsizei kWidth  = 256;
    constexpr GLsizei kHeight = 256;
    // Setup framebufferResolved and clear to black
    GLRenderbuffer colorResolved;
    glBindRenderbuffer(GL_RENDERBUFFER, colorResolved);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kWidth, kHeight);
    GLFramebuffer framebufferResolved;
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorResolved);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::black);

    uint64_t renderPassesBefore = getPerfCounters().renderPasses;

    // Setup framebufferMS, clear color/depth attachments, and draw quad
    GLsizei kSamples = 2;
    GLRenderbuffer depthMS;
    glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, kSamples, GL_DEPTH_COMPONENT24,
                                     kSamples * kWidth, kSamples * kHeight);
    GLRenderbuffer colorMS;
    glBindRenderbuffer(GL_RENDERBUFFER, colorMS);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, kSamples, GL_RGBA8, kSamples * kWidth,
                                     kSamples * kHeight);
    GLFramebuffer framebufferMS;
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS);
    // Clear depth buffer to 0.5 and color to blue.
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    GLfloat depthValue = 0.0f;
    glClearDepthf(depthValue * 0.5f + 0.5f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    drawQuadToVerifyDepthValue(drawGreen, drawRed, depthValue);

    // Resolve the color buffer to make sure the above draw worked correctly, which in turn implies
    // that the multi-sampled depth clear worked.
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS);
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
                      GL_NEAREST);

    // Blit should reuse the render pass of draw.
    EXPECT_EQ(1u, getPerfCounters().renderPasses - renderPassesBefore);

    // Bind framebufferMS and do masked clear of blue channel
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS);
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glColorMask(false, false, true, false);
    glClear(GL_COLOR_BUFFER_BIT);

    // Masked clear should not reuse the previous render pass.
    EXPECT_EQ(2u, getPerfCounters().renderPasses - renderPassesBefore);

    // Now verify the data
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS);
    // This should use resolveColorWithCommand
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
                      GL_NEAREST);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferResolved);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
    EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::blue);
    EXPECT_EQ(2u, getPerfCounters().renderPasses - renderPassesBefore);
}

// Test that swapchain does not get necessary recreation with 90 or 270 emulated pre-rotation
TEST_P(VulkanPerformanceCounterTest_Prerotation, swapchainCreateCounterTest)
{
    uint64_t expectedSwapchainCreateCounter = getPerfCounters().swapchainCreate;
    for (uint32_t i = 0; i < 10; ++i)
    {
        swapBuffers();
    }
    EXPECT_EQ(getPerfCounters().swapchainCreate, expectedSwapchainCreateCounter);
}

// Test that fully overwriting a sampled texture does not close the render pass due to texture
// ghosting.
TEST_P(VulkanPerformanceCounterTest, TextureOverwriteDoesNotBreakRenderPass)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program);
    GLint textureLoc = glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, textureLoc);

    constexpr uint32_t kWidth  = 16;
    constexpr uint32_t kHeight = 24;

    const std::vector<GLColor> texDataRed(kWidth * kHeight, GLColor::red);
    const std::vector<GLColor> texDataGreen(kWidth * kHeight, GLColor::green);

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 texDataRed.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

    // Draw multiple times, completely overwriting the texture each time.
    for (uint32_t i = 0; i < 10; ++i)
    {
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
                        i % 2 == 0 ? texDataGreen.data() : texDataRed.data());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    }

    // There should be only one render pass.
    uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
    EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);

    // For completeness, verify rendering results.
    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
}

// Demonstrate usage pattern seeing in asphalt_9 and ensure we use one render pass for maximum
// performance
TEST_P(VulkanPerformanceCounterTest, ClearThenBlitThenDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    GLProgram drawRed, drawGreen;
    drawRed.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawGreen.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());

    constexpr uint32_t kWidth  = 4;
    constexpr uint32_t kHeight = 4;

    // Initialize two FBOs with red color and depthValue
    GLTexture colorTextures[2];
    GLRenderbuffer depthStencils[2];
    GLFramebuffer fbos[2];
    GLfloat depthValue  = 0.0f;
    GLuint stencilValue = 0x55;
    for (size_t i = 0; i < 2; i++)
    {
        setupColorTextureAndDepthBuffer(colorTextures[i], depthStencils[i], GL_DEPTH24_STENCIL8,
                                        kWidth, kHeight);
        setupFBO(colorTextures[i], depthStencils[i], depthStencils[i], fbos[i], kWidth, kHeight);

        glDepthMask(GL_TRUE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_ALWAYS);
        glStencilMask(0xFF);
        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_ALWAYS, stencilValue, 0xFF);
        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), depthValue);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
    }

    uint64_t renderPassesBefore = getPerfCounters().renderPasses;

    // Clear
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepthf(1.0f);
    glClearStencil(0x00);
    glDepthMask(GL_TRUE);
    glStencilMask(0xFF);
    glDisable(GL_SCISSOR_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // Blit depth buffer from fbo1 to fbo0
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[1]);
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_DEPTH_BUFFER_BIT,
                      GL_NEAREST);

    // Verify depth value
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    drawQuadToVerifyDepthValue(drawGreen, drawRed, depthValue);

    // There should be only one render pass.
    EXPECT_EQ(1u, getPerfCounters().renderPasses - renderPassesBefore);

    // verify stencil results.
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuadToVerifyStencilValue(drawGreen, 0x00);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
}

// Similar to ClearThenBlitThenDraw, but with scissor changes
TEST_P(VulkanPerformanceCounterTest, ScissoredDrawThenBlitThenDraw)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    GLProgram drawRed, drawGreen, drawBlue;
    drawRed.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawGreen.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawBlue.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());

    constexpr uint32_t kWidth  = 64;
    constexpr uint32_t kHeight = 64;

    // Initialize two FBOs with red color and depth and stencil value
    GLTexture colorTextures[2];
    GLRenderbuffer depthStencils[2];
    GLFramebuffer fbos[2];
    std::array<GLfloat, 2> depthValues = {0.0f, 0.5f};
    GLuint stencilValue                = 0x55;
    for (size_t i = 0; i < 2; i++)
    {
        setupColorTextureAndDepthBuffer(colorTextures[i], depthStencils[i], GL_DEPTH24_STENCIL8,
                                        kWidth, kHeight);
        setupFBO(colorTextures[i], depthStencils[i], depthStencils[i], fbos[i], kWidth, kHeight);

        glDepthMask(GL_TRUE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_ALWAYS);
        glStencilMask(0xFF);
        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_ALWAYS, stencilValue, 0xFF);
        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), depthValues[i]);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
    }

    uint64_t renderPassesBefore = getPerfCounters().renderPasses;

    // Draw with viewport/scissor set to small rect. It should fail depth test.
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    glDepthFunc(GL_LESS);
    glViewport(kWidth / 2, kHeight / 2, 1, 1);
    glEnable(GL_SCISSOR_TEST);
    glScissor(kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2);
    drawQuad(drawBlue, essl1_shaders::PositionAttrib(), depthValues[0] + 0.1f);

    // Mid render pass blit depth/stencil buffer from fbo1 to fbo0 with scissor disabled. It should
    // cover th whole framebuffer.
    glDisable(GL_SCISSOR_TEST);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[1]);
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_DEPTH_BUFFER_BIT,
                      GL_NEAREST);

    // Draw again without modify any viewport/scissor state. It should still fail depth test.
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    drawQuad(drawBlue, essl1_shaders::PositionAttrib(), depthValues[1] + 0.1f);

    // end render pass.
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
    // There should be only one render pass.
    EXPECT_EQ(1u, getPerfCounters().renderPasses - renderPassesBefore);

    // Verify depth value. It should contain fbos[1]'s depth value if blit successful.
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glViewport(0, 0, kWidth, kHeight);
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuadToVerifyDepthValue(drawGreen, drawRed, depthValues[1]);
    // verify stencil results.
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuadToVerifyStencilValue(drawGreen, stencilValue);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
}

// Test interaction between transform feedback and mid render pass blit
TEST_P(VulkanPerformanceCounterTest, DrawThenBlitThenDrawWithXFB)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    GLProgram drawRed;
    drawRed.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    constexpr uint32_t kWidth  = 4;
    constexpr uint32_t kHeight = 4;

    // Initialize two FBOs with red color and depthValue
    GLTexture colorTextures[2];
    GLRenderbuffer depthStencils[2];
    GLFramebuffer fbos[2];
    GLfloat depthValue  = 0.0f;
    GLuint stencilValue = 0x55;
    for (size_t i = 0; i < 2; i++)
    {
        setupColorTextureAndDepthBuffer(colorTextures[i], depthStencils[i], GL_DEPTH24_STENCIL8,
                                        kWidth, kHeight);
        setupFBO(colorTextures[i], depthStencils[i], depthStencils[i], fbos[i], kWidth, kHeight);

        glDepthMask(GL_TRUE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_ALWAYS);
        glStencilMask(0xFF);
        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_ALWAYS, stencilValue, 0xFF);
        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), depthValue);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
    }

    uint64_t renderPassesBefore = getPerfCounters().renderPasses;

    std::vector<std::string> tfVaryings = {"gl_Position"};
    ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(xfbProgram, essl1_shaders::vs::Simple(),
                                        essl1_shaders::fs::Red(), tfVaryings,
                                        GL_INTERLEAVED_ATTRIBS);
    glUseProgram(xfbProgram);

    GLBuffer xfbBuffer;
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfbBuffer);
    glBeginTransformFeedback(GL_TRIANGLES);

    // Draw
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    drawQuad(xfbProgram, essl1_shaders::PositionAttrib(), depthValue);

    // Blit depth buffer from fbo1 to fbo0
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[1]);
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_DEPTH_BUFFER_BIT,
                      GL_NEAREST);

    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    drawQuad(xfbProgram, essl1_shaders::PositionAttrib(), depthValue);

    glEndTransformFeedback();
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
    EXPECT_GL_NO_ERROR();

    // XFB should prevent ANGLE to use mid render pass blit
    EXPECT_LT(1u, getPerfCounters().renderPasses - renderPassesBefore);

    // Ensure that triangles were actually captured correctly.
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
    // We have two quads
    GLuint quadCount = 2;
    // Each quad have two triangles, each triangle have 3 vertices, each vertex have 4 floats.
    GLuint vertexCount = 2 * 3 * 4;
    void *mappedBuffer = glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
                                          quadCount * vertexCount * sizeof(float), GL_MAP_READ_BIT);
    ASSERT_NE(nullptr, mappedBuffer);

    const GLfloat expect[] = {
        // clang-format off
        -1.0f, 1.0f, depthValue, 1.0f,
        -1.0f, -1.0f, depthValue, 1.0f,
        1.0f, -1.0f, depthValue, 1.0f,

        -1.0f, 1.0f, depthValue, 1.0f,
        1.0f,  -1.0f, depthValue, 1.0f,
        1.0f, 1.0f,  depthValue, 1.0f,
        // clang-format on
    };

    float *mappedFloats = static_cast<float *>(mappedBuffer);
    for (uint32_t quadIndex = 0; quadIndex < quadCount; quadIndex++)
    {
        for (uint32_t i = 0; i < vertexCount; ++i)
        {
            EXPECT_EQ(*mappedFloats, expect[i]);
            mappedFloats++;
        }
    }
    glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
}

// Test interaction between occlusion query and mid render pass blit
TEST_P(VulkanPerformanceCounterTest, DrawThenBlitThenDrawWithQuery)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    GLProgram drawRed, drawGreen;
    drawRed.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawGreen.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());

    constexpr uint32_t kWidth  = 4;
    constexpr uint32_t kHeight = 4;

    // Initialize two FBOs
    GLTexture colorTextures[2];
    GLRenderbuffer depthStencils[2];
    GLFramebuffer fbos[2];
    std::array<GLfloat, 2> depthValues = {0.0f, 0.5};
    for (size_t i = 0; i < 2; i++)
    {
        setupColorTextureAndDepthBuffer(colorTextures[i], depthStencils[i], GL_DEPTH24_STENCIL8,
                                        kWidth, kHeight);
        setupFBO(colorTextures[i], depthStencils[i], depthStencils[i], fbos[i], kWidth, kHeight);

        glDepthMask(GL_TRUE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_ALWAYS);
        drawQuad(drawGreen, essl1_shaders::PositionAttrib(), depthValues[i]);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
    }

    uint64_t renderPassesBefore = getPerfCounters().renderPasses;

    GLQueryEXT query;
    glBeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, query);

    // Draw with depthValue+0.1f, this should fail depth test.
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    glDepthFunc(GL_LESS);
    drawQuad(drawRed, essl1_shaders::PositionAttrib(), depthValues[0] + 0.1f);

    // Blit depth buffer from fbo1 to fbo0
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[1]);
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_DEPTH_BUFFER_BIT,
                      GL_NEAREST);

    // Draw with depthValue+0.2f, this should still fail depth test if blit successful.
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    glDepthFunc(GL_GREATER);
    drawQuad(drawRed, essl1_shaders::PositionAttrib(), depthValues[0] + 0.2f);

    glEndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
    EXPECT_GL_NO_ERROR();
    // Query should prevent ANGLE from using mid render pass blit
    EXPECT_LT(1u, getPerfCounters().renderPasses - renderPassesBefore);

    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);

    GLuint result = GL_TRUE;
    glGetQueryObjectuivEXT(query, GL_QUERY_RESULT_EXT, &result);
    EXPECT_GL_FALSE(result);
}

// Test draw with same GL state after mid render pass blit works properly
TEST_P(VulkanPerformanceCounterTest, DrawThenBlitThenDrawWithSameProgram)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    auto quadVertices = GetQuadVertices();
    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(quadVertices[0]),
                 quadVertices.data(), GL_STATIC_DRAW);

    GLProgram drawRed;
    drawRed.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    const GLint positionLocation = glGetAttribLocation(drawRed, essl1_shaders::PositionAttrib());
    ASSERT_NE(-1, positionLocation);
    glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(positionLocation);

    GLProgram drawGreen;
    drawGreen.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    ASSERT(positionLocation == glGetAttribLocation(drawGreen, essl1_shaders::PositionAttrib()));

    constexpr uint32_t kWidth  = 4;
    constexpr uint32_t kHeight = 4;

    // Initialize two FBOs with red color and depthValue
    GLTexture colorTextures[2];
    GLRenderbuffer depthStencils[2];
    GLFramebuffer fbos[2];
    std::array<GLfloat, 2> depthValues = {0.0f, 0.5};
    for (size_t i = 0; i < 2; i++)
    {
        setupColorTextureAndDepthBuffer(colorTextures[i], depthStencils[i], GL_DEPTH24_STENCIL8,
                                        kWidth, kHeight);
        setupFBO(colorTextures[i], depthStencils[i], depthStencils[i], fbos[i], kWidth, kHeight);

        glDepthMask(GL_TRUE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_ALWAYS);
        glUseProgram(drawRed);
        drawWithDepthValue(quadVertices, 0.75f);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
    }

    uint64_t renderPassesBefore = getPerfCounters().renderPasses;

    // Draw with depthValue+0.1f, this should fail depth test.
    glUseProgram(drawGreen);
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    glDepthFunc(GL_LESS);
    drawWithDepthValue(quadVertices, depthValues[0] + 0.1f);

    // Blit depth buffer from fbo1 to fbo0
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos[1]);
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_DEPTH_BUFFER_BIT,
                      GL_NEAREST);

    // Draw with depthValues[1] - 0.1f, this should still pass depth test if blit successful, but
    // fail if blit is unsuccessful.
    glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
    drawWithDepthValue(quadVertices, depthValues[1] - 0.1f);

    // ANGLE should use mid render pass blit
    EXPECT_EQ(1u, getPerfCounters().renderPasses - renderPassesBefore);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
}

// Verifies whether, when GL_RASTERIZER_DISCARD is enabled and no glClear is issued,
// the Vulkan color attachment uses VK_ATTACHMENT_LOAD_OP_NONE and VK_ATTACHMENT_STORE_OP_NONE,
// as no actual rendering or clearing is expected.
TEST_P(VulkanPerformanceCounterTest_RGBSurface, UnrenderedSurfaceShouldNotClear)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!hasLoadOpNoneSupport());

    // Use default EGL window, display, surface, and context.
    EGLWindow *window  = getEGLWindow();
    EGLDisplay dpy     = window->getDisplay();
    EGLSurface surface = window->getSurface();
    EGLContext context = window->getContext();

    // Make the default context current.
    EXPECT_TRUE(eglMakeCurrent(dpy, surface, surface, context));
    ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";

    angle::VulkanPerfCounters expected;
    // Expect rpCount+1, color(Clears+0, Loads+0, LoadNones+1, Stores+0, StoreNones+1)
    setExpectedCountersForColorOps(getPerfCounters(), 1, 0, 0, 1, 0, 1, &expected);

    glEnable(GL_RASTERIZER_DISCARD);
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    glDisable(GL_RASTERIZER_DISCARD);

    // Validate no GL errors and check performance counters.
    ASSERT_GL_NO_ERROR();
    EXPECT_EQ(expected.renderPasses, getPerfCounters().renderPasses);
    glFinish();
    EXPECT_COLOR_OP_COUNTERS(getPerfCounters(), expected);

    // Restore original context (optional if already using default).
    eglMakeCurrent(dpy, window->getSurface(), window->getSurface(), window->getContext());
}

class VulkanPerformanceCounterTest_TileMemory : public VulkanPerformanceCounterTest
{
  protected:
    VulkanPerformanceCounterTest_TileMemory() : VulkanPerformanceCounterTest()
    {
        setWindowWidth(64);
        setWindowHeight(64);
        setConfigDepthBits(24);
    }

    void setupPrograms()
    {
        drawRed.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        ASSERT_TRUE(drawRed.valid());
        drawGreen.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        ASSERT_TRUE(drawGreen.valid());
        drawBlue.makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
        ASSERT_TRUE(drawBlue.valid());
    }

    void setupColorTexturesAndDepthBuffer(GLTexture &colorTexture1,
                                          GLTexture &colorTexture2,
                                          GLRenderbuffer &depthStencil,
                                          GLenum depthStencilFormat,
                                          GLsizei width,
                                          GLsizei height)
    {
        glBindTexture(GL_TEXTURE_2D, colorTexture1);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);

        glBindTexture(GL_TEXTURE_2D, colorTexture2);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);

        glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
        glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
    }

    void drawQuadToVerifyDepthStencilValue(GLfloat depthValue, GLint stencilValue)
    {
        glStencilMask(0x0);
        glEnable(GL_STENCIL_TEST);
        glStencilFunc(GL_EQUAL, stencilValue, 0xFF);

        GLfloat kErrorTolerance = 0.01f;
        // Don't modify depth buffer
        glDepthMask(GL_FALSE);
        glEnable(GL_DEPTH_TEST);
        // This should pass
        glDepthFunc(GL_LESS);
        drawQuad(drawGreen, essl1_shaders::PositionAttrib(), depthValue - kErrorTolerance);
        // This should fail
        drawQuad(drawRed, essl1_shaders::PositionAttrib(), depthValue + kErrorTolerance);
        glDepthFunc(GL_GREATER);
        drawQuad(drawBlue, essl1_shaders::PositionAttrib(), depthValue - kErrorTolerance);
    }

    void oneDepthStencilBufferUsedInOneRenderPassAndThenInvalidate(GLenum depthStencilFormat)
    {
        setupPrograms();

        constexpr GLsizei kWidth  = 4;
        constexpr GLsizei kHeight = 4;
        bool hasStencil           = depthStencilFormat == GL_DEPTH24_STENCIL8 ? true : false;

        uint64_t tileMemoryImageCountBefore = getPerfCounters().tileMemoryImages;

        GLTexture colorTexture;
        GLRenderbuffer depthStencil;
        setupColorTextureAndDepthBuffer(colorTexture, depthStencil, depthStencilFormat, kWidth,
                                        kHeight);
        GLFramebuffer fbo;
        if (hasStencil)
        {
            setupFBO(colorTexture, depthStencil, depthStencil, fbo, kWidth, kHeight);
        }
        else
        {
            setupFBO(colorTexture, depthStencil, 0, fbo, kWidth, kHeight);
        }

        uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 1;

        GLfloat depthValue = 0.0f;
        // Clear color/depth/stencil buffers
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClearDepthf(depthValue * 0.5f + 0.5f);
        glClearStencil(0x55);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        glEnable(GL_DEPTH_TEST);

        if (hasStencil)
        {
            drawQuadToVerifyDepthStencilValue(depthValue, 0x55);
        }
        else
        {
            drawQuadToVerifyDepthValue(drawGreen, drawRed, depthValue);
        }

        std::array<GLenum, 2> attachments = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
        glInvalidateFramebuffer(GL_FRAMEBUFFER, attachments.size(), attachments.data());
        EXPECT_GL_NO_ERROR();

        // There should be only one render pass.
        uint64_t actualRenderPassCount = getPerfCounters().renderPasses;
        EXPECT_EQ(expectedRenderPassCount, actualRenderPassCount);
        // For completeness, verify rendering results.
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);

        EXPECT_EQ(1u, getPerfCounters().tileMemoryImages - tileMemoryImageCountBefore);
        EXPECT_EQ(0u, getPerfCounters().fallbackFromTileMemory);
    }

    GLProgram drawRed;
    GLProgram drawGreen;
    GLProgram drawBlue;
};

// Test that depth buffer of window surface should use tile memory since EGL spec says data is
// invalid after swapBuffer.
TEST_P(VulkanPerformanceCounterTest_TileMemory, SurfaceDepthStencilBufferShouldUseTileMemory)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);

    // Clear color to red and the depth/stencil buffer to 1.0
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(0.5f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDepthRangef(-1, 1);
    EXPECT_GL_NO_ERROR();

    glDepthMask(GL_TRUE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), -1.0f);

    swapBuffers();

    // depthStencil should be using tile memory
    EXPECT_EQ(1u, getPerfCounters().tileMemoryImages);
    EXPECT_EQ(0u, getPerfCounters().fallbackFromTileMemory);
}

// Test that depth buffer of FBO should use tile memory if invalidateFramebuffer is called.
TEST_P(VulkanPerformanceCounterTest_TileMemory, OneDSBufferUsedInOneRenderPassThenInvalidate_D24S8)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    oneDepthStencilBufferUsedInOneRenderPassAndThenInvalidate(GL_DEPTH24_STENCIL8);
}

// Test that depth buffer of FBO should use tile memory if invalidateFramebuffer is called.
TEST_P(VulkanPerformanceCounterTest_TileMemory, OneDSBufferUsedInOneRenderPassThenInvalidate_D24)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    oneDepthStencilBufferUsedInOneRenderPassAndThenInvalidate(GL_DEPTH_COMPONENT24);
}

// Test that depth buffer of FBO should use tile memory if invalidateFramebuffer is called.
TEST_P(VulkanPerformanceCounterTest_TileMemory, OneDSBufferUsedInOneRenderPassThenInvalidate_D16)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    oneDepthStencilBufferUsedInOneRenderPassAndThenInvalidate(GL_DEPTH_COMPONENT16);
}

// depth buffer of FBO should use tile memory if was valid in first render pass but invalidate in
// second render pass.
TEST_P(VulkanPerformanceCounterTest_TileMemory, OneDSBufferUsedInTwoRenderPassesThenInvalidate)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    setupPrograms();

    // Surface's depth buffer should also using tile memory.
    uint64_t expectedTileMemoryImageCount = getPerfCounters().tileMemoryImages + 1;

    constexpr GLsizei kWidth  = 4;
    constexpr GLsizei kHeight = 4;

    GLTexture colorTexture1, colorTexture2;
    GLRenderbuffer depthStencil;
    setupColorTexturesAndDepthBuffer(colorTexture1, colorTexture2, depthStencil,
                                     GL_DEPTH24_STENCIL8, kWidth, kHeight);

    // Setup two fbos share the same depth stencil buffer
    GLFramebuffer fbo1, fbo2;
    setupFBO(colorTexture1, depthStencil, depthStencil, fbo1, kWidth, kHeight);
    setupFBO(colorTexture2, depthStencil, depthStencil, fbo2, kWidth, kHeight);

    uint64_t expectedRenderPassCount = getPerfCounters().renderPasses + 2;

    GLfloat depthValue = 0.0f;
    // draw to fbo1, keep depth buffer valid
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(depthValue * 0.5f + 0.5f);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    drawQuadToVerifyDepthStencilValue(depthValue, 0x55);

    // draw to fbo2 without modifying depth buffer, and invalidate depth buffer
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuadToVerifyDepthStencilValue(depthValue, 0x55);
    std::array<GLenum, 2> attachments = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 2, attachments.data());
    EXPECT_GL_NO_ERROR();

    // There should be two render pass.
    EXPECT_EQ(expectedRenderPassCount, getPerfCounters().renderPasses);

    // For completeness, verify rendering results.
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);

    // depthStencil should also be using tile memory
    EXPECT_EQ(expectedTileMemoryImageCount, getPerfCounters().tileMemoryImages);
    EXPECT_EQ(0u, getPerfCounters().fallbackFromTileMemory);
}

// Similar to OneDepthStencilRenderBufferUsedInTwoRenderPasses, but repeat. This will create many
// render passes that uses depthStencil buffers which could allocate in tile memory heap and exceed
// heap capacity and fail. They may fallback to regular memory but should still work.
TEST_P(VulkanPerformanceCounterTest_TileMemory, ManyDSBufferUsedInOneSubmit)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    setupPrograms();

    constexpr GLsizei kWidth      = 1024;
    constexpr GLsizei kHeight     = 1024;
    constexpr size_t kRepeatCount = 10;

    std::array<GLTexture, kRepeatCount> colorTextures1, colorTextures2;
    std::array<GLRenderbuffer, kRepeatCount> depthStencils;
    std::array<GLFramebuffer, kRepeatCount> fbos1, fbos2;

    // Surface's depth buffer should also using tile memory.
    uint64_t expectedMaxTileMemoryImageCount = getPerfCounters().tileMemoryImages + kRepeatCount;
    uint64_t expectedMinTileMemoryImageCount = getPerfCounters().tileMemoryImages + 1;
    uint64_t expectedRenderPassCount         = getPerfCounters().renderPasses + 2 * kRepeatCount;

    std::array<GLenum, 2> attachments = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    GLfloat depthValue                = 0.0f;
    for (size_t i = 0; i < kRepeatCount; i++)
    {
        setupColorTexturesAndDepthBuffer(colorTextures1[i], colorTextures2[i], depthStencils[i],
                                         GL_DEPTH24_STENCIL8, kWidth, kHeight);
        setupFBO(colorTextures1[i], depthStencils[i], depthStencils[i], fbos1[i], kWidth, kHeight);
        setupFBO(colorTextures2[i], depthStencils[i], depthStencils[i], fbos2[i], kWidth, kHeight);

        // Clear color/depth/stencil buffer
        glBindFramebuffer(GL_FRAMEBUFFER, fbos1[i]);
        glDepthMask(GL_TRUE);
        glStencilMask(0xFF);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClearDepthf(depthValue * 0.5f + 0.5f);
        glClearStencil(0x55);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        drawQuadToVerifyDepthStencilValue(depthValue, 0x55);

        // draw to fbo2 without modifying depth buffer, and invalidate depth buffer
        glBindFramebuffer(GL_FRAMEBUFFER, fbos2[i]);
        glClear(GL_COLOR_BUFFER_BIT);
        drawQuadToVerifyDepthStencilValue(depthValue, 0x55);
        glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, attachments.size(), attachments.data());
    }

    // There should be two render pass for every kRepeatCount loop.
    EXPECT_EQ(expectedRenderPassCount, getPerfCounters().renderPasses);
    // depthStencil should also be using tile memory
    EXPECT_LE(getPerfCounters().tileMemoryImages, expectedMaxTileMemoryImageCount);
    EXPECT_GE(getPerfCounters().tileMemoryImages, expectedMinTileMemoryImageCount);

    // For completeness, verify rendering results.
    for (size_t i = 0; i < kRepeatCount; i++)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, fbos1[i]);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
        glBindFramebuffer(GL_FRAMEBUFFER, fbos2[i]);
        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
    }
    EXPECT_EQ(0u, getPerfCounters().fallbackFromTileMemory);
}

// Test that depth buffer of FBO that uses tile memory will switch back to regular memory if it has
// valid data across submissions
TEST_P(VulkanPerformanceCounterTest_TileMemory, OneDSBufferUsedInTwoRenderPassesWithTwoSubmission)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    setupPrograms();

    uint64_t tileMemoryStartingImageCount = getPerfCounters().tileMemoryImages;

    constexpr GLsizei kWidth  = 4;
    constexpr GLsizei kHeight = 4;

    GLTexture colorTexture1, colorTexture2;
    GLRenderbuffer depthStencil;
    setupColorTexturesAndDepthBuffer(colorTexture1, colorTexture2, depthStencil,
                                     GL_DEPTH24_STENCIL8, kWidth, kHeight);

    // Setup two fbos share the same depth stencil buffer
    GLFramebuffer fbo1, fbo2;
    setupFBO(colorTexture1, depthStencil, depthStencil, fbo1, kWidth, kHeight);
    setupFBO(colorTexture2, depthStencil, depthStencil, fbo2, kWidth, kHeight);

    GLfloat depthValue = 0.0f;
    // draw to fbo1, keep depth buffer valid
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(depthValue * 0.5f + 0.5f);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    drawQuadToVerifyDepthStencilValue(depthValue, 0x55);
    EXPECT_GL_NO_ERROR();
    // depthStencil should also be using tile memory
    EXPECT_EQ(tileMemoryStartingImageCount + 1, getPerfCounters().tileMemoryImages);
    EXPECT_EQ(0u, getPerfCounters().fallbackFromTileMemory);
    // Submit
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
    // depthStencil should not be using tile memory
    EXPECT_EQ(tileMemoryStartingImageCount, getPerfCounters().tileMemoryImages);
    EXPECT_EQ(1u, getPerfCounters().fallbackFromTileMemory);

    // draw to fbo2 without modifying depth buffer
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
    glClear(GL_COLOR_BUFFER_BIT);
    // Verify depth has correct value
    drawQuadToVerifyDepthValue(drawGreen, drawRed, depthValue);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
    glClear(GL_COLOR_BUFFER_BIT);
    // Verify stencil has correct value
    drawQuadToVerifyStencilValue(drawGreen, 0x55);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
}

// Test that depth buffer of surface that uses tile memory will switch back to regular memory if it
// has valid data across submissions
TEST_P(VulkanPerformanceCounterTest_TileMemory,
       SurfaceDepthBufferUsedInTwoRenderPassesWithTwoSubmission)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    setupPrograms();

    GLfloat depthValue = 0.0f;
    // draw to depth depth buffer and keep data valid
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(depthValue * 0.5f + 0.5f);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    drawQuadToVerifyDepthValue(drawGreen, drawRed, depthValue);
    EXPECT_GL_NO_ERROR();
    // depthStencil should also be using tile memory
    EXPECT_EQ(1u, getPerfCounters().tileMemoryImages);
    EXPECT_EQ(0u, getPerfCounters().fallbackFromTileMemory);
    // Submit
    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
    // depthStencil should not be using tile memory
    EXPECT_EQ(0u, getPerfCounters().tileMemoryImages);
    EXPECT_EQ(1u, getPerfCounters().fallbackFromTileMemory);

    // draw again without modifying depth buffer
    glClear(GL_COLOR_BUFFER_BIT);
    // Verify depth buffer has correct value
    drawQuadToVerifyDepthValue(drawGreen, drawRed, depthValue);
    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
}

// Regression test for UAF in finalizeImageWithTileMemory after readPixels triggered
// fallbackFromTileMemory.
TEST_P(VulkanPerformanceCounterTest_TileMemory, DepthBufferPBOReadThenDelete)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_read_depth_stencil"));

    setupPrograms();

    GLenum depthStencilFormat = GL_DEPTH24_STENCIL8;
    constexpr GLsizei kWidth  = 256;
    constexpr GLsizei kHeight = 256;

    uint64_t tileMemoryImageCountBefore = getPerfCounters().tileMemoryImages;

    GLTexture colorTexture;
    GLRenderbuffer depthStencil;
    setupColorTextureAndDepthBuffer(colorTexture, depthStencil, depthStencilFormat, kWidth,
                                    kHeight);
    GLFramebuffer fbo;
    setupFBO(colorTexture, depthStencil, depthStencil, fbo, kWidth, kHeight);

    GLfloat depthValue = 0.0f;
    // Clear color/depth/stencil buffers
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(depthValue * 0.5f + 0.5f);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    drawQuadToVerifyDepthValue(drawGreen, drawRed, depthValue);
    EXPECT_EQ(1u, getPerfCounters().tileMemoryImages - tileMemoryImageCountBefore);

    // PBO read
    GLBuffer pbo;
    glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);
    glBufferData(GL_PIXEL_PACK_BUFFER, kWidth * kHeight * sizeof(uint32_t), nullptr,
                 GL_DYNAMIC_READ);
    glReadPixels(0, 0, kWidth, kHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
    EXPECT_GL_NO_ERROR();

    // Delete depthBuffer
    depthStencil.reset();

    std::array<GLenum, 2> attachments = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
    glInvalidateFramebuffer(GL_FRAMEBUFFER, attachments.size(), attachments.data());

    // For completeness, verify rendering results.
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
    EXPECT_GL_NO_ERROR();
}

// Test blit depth buffer works, similar to
// dEQP-GLES3.functional.fbo.blit.depth_stencil.depth32_basic.
TEST_P(VulkanPerformanceCounterTest_TileMemory, BlitGradientDepthBuffer)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    constexpr GLsizei kWidth  = 128;
    constexpr GLsizei kHeight = 128;

    setupPrograms();

    GLTexture srcColorTexture, dstColorTexture;
    GLRenderbuffer srcDepthStencil, dstDepthStencil;
    setupColorTexturesAndDepthBuffer(srcColorTexture, dstColorTexture, srcDepthStencil,
                                     GL_DEPTH_COMPONENT32F, kWidth, kHeight);
    glBindRenderbuffer(GL_RENDERBUFFER, dstDepthStencil);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32F, kWidth, kHeight);

    // Create frame buffers and clear depth to 1.0f
    GLFramebuffer srcFbo, dstFbo;
    setupFBO(srcColorTexture, srcDepthStencil, 0, srcFbo, kWidth, kHeight);
    glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
    setupFBO(dstColorTexture, dstDepthStencil, 0, dstFbo, kWidth, kHeight);
    glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);

    // Fill source with gradient depth value: depth = [-1..1]
    const std::array<angle::Vector3, 4> kGradientQuadVertices = {
        {angle::Vector3(-1.0f, -1.0f, -1.0f), angle::Vector3(-1.0f, 1.0f, 0.0f),
         angle::Vector3(1.0f, -1.0f, 0.0f), angle::Vector3(1.0f, 1.0f, 1.0f)}};
    const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
    glBindFramebuffer(GL_FRAMEBUFFER, srcFbo);
    glViewport(0, 0, kWidth, kHeight);
    glEnable(GL_DEPTH_TEST);
    glUseProgram(drawRed);
    int32_t posLoc = glGetAttribLocation(drawRed, essl1_shaders::PositionAttrib());
    glEnableVertexAttribArray(posLoc);
    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, kGradientQuadVertices.data());
    glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(indices[0]), GL_UNSIGNED_SHORT,
                   &indices[0]);

    glBindFramebuffer(GL_FRAMEBUFFER, dstFbo);
    drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);

    // Perform copy.
    glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFbo);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFbo);
    glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_DEPTH_BUFFER_BIT,
                      GL_NEAREST);

    // Render blue color where depth < 0, decrement on depth failure.
    glBindFramebuffer(GL_FRAMEBUFFER, dstFbo);
    drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();

    std::vector<GLColor> resultData(kWidth * kHeight);
    glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, resultData.data());

    // The top left triangle should fail depth test, thus keep the dstFbo color which is
    // gradientData.
    bool topLeftTriangleIsGreen = true;
    for (int y = 0; y < kHeight && topLeftTriangleIsGreen; y++)
    {
        for (int x = 0; x < (kWidth - y); x++)
        {
            if (resultData[y * kWidth + x] != GLColor::green)
            {
                topLeftTriangleIsGreen = false;
                break;
            }
        }
    }
    EXPECT_EQ(topLeftTriangleIsGreen, true);

    // The bottom right triangle should pass depth test, thus render blue.
    bool bottomRightTriangleIsBlue = true;
    for (int y = 0; y < kHeight && bottomRightTriangleIsBlue; y++)
    {
        for (int x = (kWidth - y); x < kWidth; x++)
        {
            if (resultData[y * kWidth + x] != GLColor::blue)
            {
                bottomRightTriangleIsBlue = false;
                break;
            }
        }
    }
    EXPECT_EQ(bottomRightTriangleIsBlue, true);
}

// Similar to OneDSBufferUsedInOneRenderPassThenInvalidate_D24S8, add sample from cubemap texture
// which on some GPU, it may trigger finishImpl call.
TEST_P(VulkanPerformanceCounterTest_TileMemory,
       OneDSBufferUsedInOneRenderPassThenSampleFromCubemapTexture)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));
    ANGLE_SKIP_TEST_IF(!isFeatureEnabled(Feature::SimulateTileMemoryForTesting) &&
                       !isFeatureEnabled(Feature::SupportsTileMemoryHeap));

    setupPrograms();

    const char kCubemapTextureFS[] = R"(precision highp float;
            uniform samplerCube texCube;
            varying vec2 v_texCoord;
            void main()
            {
                vec3 cubecoord = vec3(1, v_texCoord);
                gl_FragColor = textureCube(texCube, cubecoord);
            })";

    constexpr GLsizei kWidth  = 4;
    constexpr GLsizei kHeight = 4;

    uint64_t tileMemoryImageCountBefore = getPerfCounters().tileMemoryImages;
    uint64_t renderPassCountBefore      = getPerfCounters().renderPasses;

    // Create a cubemap texture. This will create a texture with mHasBeenBoundAsAttachment=false.
    GLTexture cubeMapTexture;
    glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapTexture);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexStorage2D(GL_TEXTURE_CUBE_MAP, 7, GL_RGB5_A1, 64, 64);
    std::array<uint16_t, 64 * 64> textureData;
    textureData.fill(0xF801);
    for (GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
         target++)
    {
        glTexSubImage2D(target, 0, 0, 0, 64, 64, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,
                        reinterpret_cast<const GLubyte *>(textureData.data()));
    }
    // This will make the cubemap texture's mHasBeenBoundAsAttachment=true.
    GLFramebuffer fboWithCubemapTexture;
    glBindFramebuffer(GL_FRAMEBUFFER, fboWithCubemapTexture);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
                           cubeMapTexture, 0);

    // Create FBO, it's depthStencil buffer should allocated with tile memory.
    GLTexture colorTexture;
    GLRenderbuffer depthStencil;
    setupColorTextureAndDepthBuffer(colorTexture, depthStencil, GL_DEPTH24_STENCIL8, kWidth,
                                    kHeight);
    GLFramebuffer fbo;
    setupFBO(colorTexture, depthStencil, depthStencil, fbo, kWidth, kHeight);

    // Start renderPass
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClearDepthf(0.5f);
    glClearStencil(0x55);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    drawQuadToVerifyDepthStencilValue(0.0f, 0x55);
    EXPECT_GL_NO_ERROR();

    // There should be only one render pass.
    uint64_t renderPassCount = getPerfCounters().renderPasses - renderPassCountBefore;
    EXPECT_EQ(1u, renderPassCount);
    EXPECT_EQ(1u, getPerfCounters().tileMemoryImages - tileMemoryImageCountBefore);
    EXPECT_EQ(0u, getPerfCounters().fallbackFromTileMemory);

    // Sample from cubeMapTexture. This may trigger submitCommands on some GPUs that has to recreate
    // VkImage for cubemap texture due to mHasBeenBoundAsAttachment==true and trigger a finishImpl
    // call due to data copy back.
    ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), kCubemapTextureFS);
    glUseProgram(texProgram);
    glBindTexture(GL_TEXTURE_CUBE_MAP, cubeMapTexture);
    glDisable(GL_STENCIL_TEST);
    glDepthMask(GL_TRUE);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_ALWAYS);
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuad(texProgram, essl1_shaders::PositionAttrib(), 0.6f);
    drawQuadToVerifyDepthValue(drawGreen, drawRed, 0.6f);
    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
}

class VulkanPerformanceCounterTest_ClipDistance : public VulkanPerformanceCounterTest
{};

// Switch clip distance should update driver uniforms.
TEST_P(VulkanPerformanceCounterTest_ClipDistance, ToggleClipDistanceShouldUpdateDriverUniform)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(kPerfMonitorExtensionName));

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    constexpr GLsizei kWidth  = 4;
    constexpr GLsizei kHeight = 4;

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB565, kWidth, kHeight);
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    glViewport(0, 0, kWidth, kHeight);

    glDisable(GL_CLIP_DISTANCE0_EXT);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    uint64_t program1Count = getPerfCounters().graphicsDriverUniformsUpdated;
    glEnable(GL_CLIP_DISTANCE0_EXT);
    drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
    uint64_t program2Count = getPerfCounters().graphicsDriverUniformsUpdated;
    EXPECT_EQ(program2Count, program1Count + 1);
    ASSERT_GL_NO_ERROR();
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest);
ANGLE_INSTANTIATE_TEST(
    VulkanPerformanceCounterTest,
    ES3_VULKAN(),
    ES3_VULKAN().enable(Feature::PadBuffersToMaxVertexAttribStride),
    ES3_VULKAN_SWIFTSHADER().enable(Feature::PreferMonolithicPipelinesOverLibraries),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .enable(Feature::SlowDownMonolithicPipelineCreationForTesting),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .disable(Feature::MergeProgramPipelineCachesToGlobalCache));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
    VulkanPerformanceCounterTest_DepthStencilLoadStoreOps);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps,
                       ES3_VULKAN(),
                       ES3_VULKAN().enable(Feature::SimulateTileMemoryForTesting),
                       ES3_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest_ES31);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_ES31, ES31_VULKAN(), ES31_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(
    VulkanPerformanceCounterTest_DepthStencilLoadStoreOps_ES31);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_DepthStencilLoadStoreOps_ES31,
                       ES31_VULKAN(),
                       ES3_VULKAN().enable(Feature::SimulateTileMemoryForTesting),
                       ES31_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest_MSAA);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_MSAA,
                       ES3_VULKAN(),
                       ES3_VULKAN_SWIFTSHADER(),
                       ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
                       ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
                       ES3_VULKAN().enable(Feature::EmulatedPrerotation270));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest_Prerotation);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_Prerotation,
                       ES3_VULKAN(),
                       ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
                       ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
                       ES3_VULKAN().enable(Feature::EmulatedPrerotation270));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest_SingleBuffer);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_SingleBuffer, ES3_VULKAN());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest_RGBSurface);
ANGLE_INSTANTIATE_TEST(
    VulkanPerformanceCounterTest_RGBSurface,
    ES3_VULKAN(),
    ES3_VULKAN().enable(Feature::PadBuffersToMaxVertexAttribStride),
    ES3_VULKAN_SWIFTSHADER().enable(Feature::PreferMonolithicPipelinesOverLibraries),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .enable(Feature::SlowDownMonolithicPipelineCreationForTesting),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .disable(Feature::MergeProgramPipelineCachesToGlobalCache));

// Enable SimulateTileMemoryForTesting feature to get some test coverage on bots. Note that if both
// SimulateTileMemoryForTesting and SupportsTileMemoryHeap are enabled, SupportsTileMemoryHeap will
// take precedence.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest_TileMemory);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_TileMemory,
                       ES3_VULKAN(),
                       ES3_VULKAN().enable(Feature::SimulateTileMemoryForTesting),
                       ES3_VULKAN()
                           .enable(Feature::SimulateTileMemoryForTesting)
                           .disable(Feature::SupportsImagelessFramebuffer),
                       ES3_VULKAN_SWIFTSHADER().enable(Feature::SimulateTileMemoryForTesting));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanPerformanceCounterTest_ClipDistance);
ANGLE_INSTANTIATE_TEST(VulkanPerformanceCounterTest_ClipDistance, ES3_VULKAN_SWIFTSHADER());
}  // anonymous namespace
