/*
 * Copyright (c) 2015-2026 The Khronos Group Inc.
 * Copyright (c) 2015-2026 Valve Corporation
 * Copyright (c) 2015-2026 LunarG, Inc.
 * Copyright (c) 2015-2026 Google, Inc.
 * Modifications Copyright (C) 2020-2021 Advanced Micro Devices, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

#include "utils/cast_utils.h"
#include "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"
#include <algorithm>
#include <cstdint>

class NegativeQuery : public QueryTest {};

TEST_F(NegativeQuery, PerformanceCreation) {
    TEST_DESCRIPTION("Create performance query without support");
    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::performanceCounterQueryPools);
    RETURN_IF_SKIP(Init());

    auto queueFamilyProperties = m_device->Physical().queue_properties_;
    uint32_t queueFamilyIndex = queueFamilyProperties.size();
    std::vector<VkPerformanceCounterKHR> counters;

    for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
        uint32_t nCounters;

        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, nullptr, nullptr);
        if (nCounters == 0) continue;

        counters.resize(nCounters);
        for (auto& c : counters) {
            c = vku::InitStructHelper();
        }
        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, &counters[0], nullptr);
        queueFamilyIndex = idx;
        break;
    }

    if (counters.empty()) {
        GTEST_SKIP() << "No queue reported any performance counter.";
    }

    VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci = vku::InitStructHelper();
    perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
    perf_query_pool_ci.counterIndexCount = counters.size();
    std::vector<uint32_t> counterIndices;
    for (uint32_t c = 0; c < counters.size(); c++) counterIndices.push_back(c);
    perf_query_pool_ci.pCounterIndices = &counterIndices[0];
    VkQueryPoolCreateInfo query_pool_ci = vku::InitStructHelper();
    query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
    query_pool_ci.queryCount = 1;

    vkt::QueryPool query_pool;

    // Missing pNext
    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-03222");
    query_pool.Init(*m_device, query_pool_ci);
    m_errorMonitor->VerifyFound();

    query_pool_ci.pNext = &perf_query_pool_ci;

    // Invalid counter indices
    counterIndices.push_back(counters.size());
    perf_query_pool_ci.counterIndexCount++;
    perf_query_pool_ci.pCounterIndices = counterIndices.data();
    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolPerformanceCreateInfoKHR-pCounterIndices-03321");
    query_pool.Init(*m_device, query_pool_ci);
    m_errorMonitor->VerifyFound();
    perf_query_pool_ci.counterIndexCount--;
    counterIndices.pop_back();

    // Success
    query_pool.Init(*m_device, query_pool_ci);

    m_command_buffer.Begin();

    // Missing acquire lock
    {
        m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryPool-03223");
        vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
        m_errorMonitor->VerifyFound();
    }

    m_command_buffer.End();
}

TEST_F(NegativeQuery, PerformanceCounterCommandbufferScope) {
    TEST_DESCRIPTION("Insert a performance query begin/end with respect to the command buffer counter scope");

    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::performanceCounterQueryPools);
    RETURN_IF_SKIP(Init());

    auto queueFamilyProperties = m_device->Physical().queue_properties_;
    uint32_t queueFamilyIndex = queueFamilyProperties.size();
    std::vector<VkPerformanceCounterKHR> counters;
    std::vector<uint32_t> counterIndices;

    // Find a single counter with VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR scope.
    for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
        uint32_t nCounters;

        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, nullptr, nullptr);
        if (nCounters == 0) continue;

        counters.resize(nCounters);
        for (auto& c : counters) {
            c = vku::InitStructHelper();
        }
        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, &counters[0], nullptr);
        queueFamilyIndex = idx;

        for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
            if (counters[counterIdx].scope == VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR) {
                counterIndices.push_back(counterIdx);
                break;
            }
        }

        if (counterIndices.empty()) {
            counters.clear();
            continue;
        }
        break;
    }

    if (counterIndices.empty()) {
        GTEST_SKIP() << "No queue reported any performance counter with command buffer scope.";
    }

    VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci = vku::InitStructHelper();
    perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
    perf_query_pool_ci.counterIndexCount = counterIndices.size();
    perf_query_pool_ci.pCounterIndices = &counterIndices[0];
    VkQueryPoolCreateInfo query_pool_ci = vku::InitStructHelper(&perf_query_pool_ci);
    query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
    query_pool_ci.queryCount = 1;
    vkt::QueryPool query_pool(*m_device, query_pool_ci);

    VkQueue queue = VK_NULL_HANDLE;
    vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);

    {
        VkAcquireProfilingLockInfoKHR lock_info = vku::InitStructHelper();
        VkResult result = vk::AcquireProfilingLockKHR(device(), &lock_info);
        ASSERT_TRUE(result == VK_SUCCESS);
    }

    // Not the first command.
    {
        vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
        m_command_buffer.Begin();
        vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
        vk::CmdFillBuffer(m_command_buffer, buffer, 0, 4096, 0);

        m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryPool-03224");
        vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
        m_errorMonitor->VerifyFound();

        m_command_buffer.End();

        VkSubmitInfo submit_info = vku::InitStructHelper();
        submit_info.waitSemaphoreCount = 0;
        submit_info.pWaitSemaphores = NULL;
        submit_info.pWaitDstStageMask = NULL;
        submit_info.commandBufferCount = 1;
        submit_info.pCommandBuffers = &m_command_buffer.handle();
        submit_info.signalSemaphoreCount = 0;
        submit_info.pSignalSemaphores = NULL;
        vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
        vk::QueueWaitIdle(queue);
    }

    // Not last command.
    {
        vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

        m_command_buffer.Begin();
        vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
        vk::CmdEndQuery(m_command_buffer, query_pool, 0);
        vk::CmdFillBuffer(m_command_buffer, buffer, 0, 4096, 0);
        m_command_buffer.End();

        VkSubmitInfo submit_info = vku::InitStructHelper();
        submit_info.waitSemaphoreCount = 0;
        submit_info.pWaitSemaphores = NULL;
        submit_info.pWaitDstStageMask = NULL;
        submit_info.commandBufferCount = 1;
        submit_info.pCommandBuffers = &m_command_buffer.handle();
        submit_info.signalSemaphoreCount = 0;
        submit_info.pSignalSemaphores = NULL;
        m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-queryPool-03227");
        vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
        m_errorMonitor->VerifyFound();
    }

    vk::ReleaseProfilingLockKHR(device());
}

TEST_F(NegativeQuery, PerformanceCounterRenderPassScope) {
    TEST_DESCRIPTION("Insert a performance query begin/end with respect to the render pass counter scope");

    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::performanceCounterQueryPools);
    RETURN_IF_SKIP(Init());

    auto queueFamilyProperties = m_device->Physical().queue_properties_;
    uint32_t queueFamilyIndex = queueFamilyProperties.size();
    std::vector<VkPerformanceCounterKHR> counters;
    std::vector<uint32_t> counterIndices;

    // Find a single counter with VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR scope.
    for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
        uint32_t nCounters;

        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, nullptr, nullptr);
        if (nCounters == 0) continue;

        counters.resize(nCounters);
        for (auto& c : counters) {
            c = vku::InitStructHelper();
        }
        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, &counters[0], nullptr);
        queueFamilyIndex = idx;

        for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
            if (counters[counterIdx].scope == VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR) {
                counterIndices.push_back(counterIdx);
                break;
            }
        }

        if (counterIndices.empty()) {
            counters.clear();
            continue;
        }
        break;
    }

    if (counterIndices.empty()) {
        GTEST_SKIP() << "No queue reported any performance counter with render pass scope.";
    }

    InitRenderTarget();

    VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci = vku::InitStructHelper();
    perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
    perf_query_pool_ci.counterIndexCount = counterIndices.size();
    perf_query_pool_ci.pCounterIndices = &counterIndices[0];
    VkQueryPoolCreateInfo query_pool_ci = vku::InitStructHelper(&perf_query_pool_ci);
    query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
    query_pool_ci.queryCount = 1;
    vkt::QueryPool query_pool(*m_device, query_pool_ci);

    VkQueue queue = VK_NULL_HANDLE;
    vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);

    {
        VkAcquireProfilingLockInfoKHR lock_info = vku::InitStructHelper();
        VkResult result = vk::AcquireProfilingLockKHR(device(), &lock_info);
        ASSERT_TRUE(result == VK_SUCCESS);
    }

    // Inside a render pass.
    {
        m_command_buffer.Begin();
        m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);

        m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryPool-03225");
        vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
        m_errorMonitor->VerifyFound();

        m_command_buffer.EndRenderPass();
        m_command_buffer.End();

        VkSubmitInfo submit_info = vku::InitStructHelper();
        submit_info.waitSemaphoreCount = 0;
        submit_info.pWaitSemaphores = NULL;
        submit_info.pWaitDstStageMask = NULL;
        submit_info.commandBufferCount = 1;
        submit_info.pCommandBuffers = &m_command_buffer.handle();
        submit_info.signalSemaphoreCount = 0;
        submit_info.pSignalSemaphores = NULL;
        vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
        vk::QueueWaitIdle(queue);
    }

    vk::ReleaseProfilingLockKHR(device());
}

TEST_F(NegativeQuery, PerformanceReleaseProfileLockBeforeSubmit) {
    TEST_DESCRIPTION("Verify that we get an error if we release the profiling lock during the recording of performance queries");

    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::performanceCounterQueryPools);
    RETURN_IF_SKIP(Init());

    auto queueFamilyProperties = m_device->Physical().queue_properties_;
    uint32_t queueFamilyIndex = queueFamilyProperties.size();
    std::vector<VkPerformanceCounterKHR> counters;
    std::vector<uint32_t> counterIndices;

    // Find a single counter with VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR scope.
    for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
        uint32_t nCounters;

        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, nullptr, nullptr);
        if (nCounters == 0) continue;

        counters.resize(nCounters);
        for (auto& c : counters) {
            c = vku::InitStructHelper();
        }
        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, &counters[0], nullptr);
        queueFamilyIndex = idx;

        for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
            if (counters[counterIdx].scope == VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR) {
                counterIndices.push_back(counterIdx);
                break;
            }
        }

        if (counterIndices.empty()) {
            counters.clear();
            continue;
        }
        break;
    }

    if (counterIndices.empty()) {
        GTEST_SKIP() << "No queue reported any performance counter with render pass scope.";
    }

    InitRenderTarget();

    VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci = vku::InitStructHelper();
    perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
    perf_query_pool_ci.counterIndexCount = counterIndices.size();
    perf_query_pool_ci.pCounterIndices = &counterIndices[0];
    VkQueryPoolCreateInfo query_pool_ci = vku::InitStructHelper(&perf_query_pool_ci);
    query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
    query_pool_ci.queryCount = 1;
    vkt::QueryPool query_pool(*m_device, query_pool_ci);

    VkQueue queue = VK_NULL_HANDLE;
    vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);

    {
        VkAcquireProfilingLockInfoKHR lock_info = vku::InitStructHelper();
        VkResult result = vk::AcquireProfilingLockKHR(device(), &lock_info);
        ASSERT_TRUE(result == VK_SUCCESS);
    }

    {
        m_command_buffer.Reset();
        m_command_buffer.Begin();
        vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
        m_command_buffer.End();

        VkSubmitInfo submit_info = vku::InitStructHelper();
        submit_info.waitSemaphoreCount = 0;
        submit_info.pWaitSemaphores = NULL;
        submit_info.pWaitDstStageMask = NULL;
        submit_info.commandBufferCount = 1;
        submit_info.pCommandBuffers = &m_command_buffer.handle();
        submit_info.signalSemaphoreCount = 0;
        submit_info.pSignalSemaphores = NULL;

        vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
        vk::QueueWaitIdle(queue);
    }

    {
        vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

        m_command_buffer.Reset();
        m_command_buffer.Begin();

        vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);

        // Release while recording.
        vk::ReleaseProfilingLockKHR(device());
        {
            VkAcquireProfilingLockInfoKHR lock_info = vku::InitStructHelper();
            VkResult result = vk::AcquireProfilingLockKHR(device(), &lock_info);
            ASSERT_TRUE(result == VK_SUCCESS);
        }

        vk::CmdEndQuery(m_command_buffer, query_pool, 0);

        m_command_buffer.End();

        VkSubmitInfo submit_info = vku::InitStructHelper();
        submit_info.waitSemaphoreCount = 0;
        submit_info.pWaitSemaphores = NULL;
        submit_info.pWaitDstStageMask = NULL;
        submit_info.commandBufferCount = 1;
        submit_info.pCommandBuffers = &m_command_buffer.handle();
        submit_info.signalSemaphoreCount = 0;
        submit_info.pSignalSemaphores = NULL;

        m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-03220");
        vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
        m_errorMonitor->VerifyFound();

        vk::QueueWaitIdle(queue);
    }

    vk::ReleaseProfilingLockKHR(device());
}

TEST_F(NegativeQuery, PerformanceIncompletePasses) {
    TEST_DESCRIPTION("Verify that we get an error if we don't submit a command buffer for each passes before getting the results.");
    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
    AddOptionalExtensions(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);

    // Vulkan 1.1 is a dependency of VK_KHR_video_queue, but both the version and the extension
    // is optional from the point of view of this test case
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredFeature(vkt::Feature::hostQueryReset);
    AddRequiredFeature(vkt::Feature::performanceCounterQueryPools);
    RETURN_IF_SKIP(Init());

    if (IsPlatformMockICD()) {
        GTEST_SKIP() << "vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR doesn't match up with profile queues";
    }

    VkPhysicalDevicePerformanceQueryPropertiesKHR perf_query_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(perf_query_props);

    auto queueFamilyProperties = m_device->Physical().queue_properties_;
    uint32_t queueFamilyIndex = queueFamilyProperties.size();
    std::vector<VkPerformanceCounterKHR> counters;
    std::vector<uint32_t> counterIndices;
    uint32_t nPasses = 0;

    // Find all counters with VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR scope.
    for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
        uint32_t nCounters;

        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, nullptr, nullptr);
        if (nCounters == 0) continue;

        counters.resize(nCounters);
        for (auto& c : counters) {
            c = vku::InitStructHelper();
        }
        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, &counters[0], nullptr);
        queueFamilyIndex = idx;

        for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
            if (counters[counterIdx].scope == VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR) counterIndices.push_back(counterIdx);
        }
        if (counterIndices.empty()) continue;  // might not be a scope command

        VkQueryPoolPerformanceCreateInfoKHR create_info = vku::InitStructHelper();
        create_info.queueFamilyIndex = idx;
        create_info.counterIndexCount = counterIndices.size();
        create_info.pCounterIndices = &counterIndices[0];

        vk::GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(Gpu(), &create_info, &nPasses);

        if (nPasses < 2) {
            counters.clear();
            continue;
        }
        break;
    }

    if (counterIndices.empty()) {
        GTEST_SKIP() << "No queue reported a set of counters that needs more than one pass.";
    }

    InitRenderTarget();

    VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci = vku::InitStructHelper();
    perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
    perf_query_pool_ci.counterIndexCount = counterIndices.size();
    perf_query_pool_ci.pCounterIndices = &counterIndices[0];
    VkQueryPoolCreateInfo query_pool_ci = vku::InitStructHelper(&perf_query_pool_ci);
    query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
    query_pool_ci.queryCount = 1;
    vkt::QueryPool query_pool(*m_device, query_pool_ci);

    VkQueue queue = VK_NULL_HANDLE;
    vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);

    {
        VkAcquireProfilingLockInfoKHR lock_info = vku::InitStructHelper();
        VkResult result = vk::AcquireProfilingLockKHR(device(), &lock_info);
        ASSERT_TRUE(result == VK_SUCCESS);
    }

    {
        const VkDeviceSize buf_size =
            std::max((VkDeviceSize)4096, (VkDeviceSize)(sizeof(VkPerformanceCounterResultKHR) * counterIndices.size()));
        vkt::Buffer buffer(*m_device, buf_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

        VkCommandBufferBeginInfo command_buffer_begin_info = vku::InitStructHelper();
        command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;

        vk::ResetQueryPoolEXT(device(), query_pool, 0, 1);

        m_command_buffer.Begin(&command_buffer_begin_info);
        vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
        vk::CmdFillBuffer(m_command_buffer, buffer, 0, buf_size, 0);
        vk::CmdEndQuery(m_command_buffer, query_pool, 0);
        m_command_buffer.End();

        // Invalid pass index
        {
            VkPerformanceQuerySubmitInfoKHR perf_submit_info = vku::InitStructHelper();
            perf_submit_info.counterPassIndex = nPasses;
            VkSubmitInfo submit_info = vku::InitStructHelper(&perf_submit_info);
            submit_info.waitSemaphoreCount = 0;
            submit_info.pWaitSemaphores = NULL;
            submit_info.pWaitDstStageMask = NULL;
            submit_info.commandBufferCount = 1;
            submit_info.pCommandBuffers = &m_command_buffer.handle();
            submit_info.signalSemaphoreCount = 0;
            submit_info.pSignalSemaphores = NULL;

            m_errorMonitor->SetDesiredError("VUID-VkPerformanceQuerySubmitInfoKHR-counterPassIndex-03221");
            vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
            m_errorMonitor->VerifyFound();
        }

        // Leave the last pass out.
        for (uint32_t passIdx = 0; passIdx < (nPasses - 1); passIdx++) {
            VkPerformanceQuerySubmitInfoKHR perf_submit_info = vku::InitStructHelper();
            perf_submit_info.counterPassIndex = passIdx;
            VkSubmitInfo submit_info = vku::InitStructHelper(&perf_submit_info);
            submit_info.waitSemaphoreCount = 0;
            submit_info.pWaitSemaphores = NULL;
            submit_info.pWaitDstStageMask = NULL;
            submit_info.commandBufferCount = 1;
            submit_info.pCommandBuffers = &m_command_buffer.handle();
            submit_info.signalSemaphoreCount = 0;
            submit_info.pSignalSemaphores = NULL;

            vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
        }

        vk::QueueWaitIdle(queue);

        std::vector<VkPerformanceCounterResultKHR> results;
        results.resize(counterIndices.size());

        m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-09441");
        vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
                                sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_WAIT_BIT);
        m_errorMonitor->VerifyFound();

        // submit the last pass
        {
            VkPerformanceQuerySubmitInfoKHR perf_submit_info = vku::InitStructHelper();
            perf_submit_info.counterPassIndex = nPasses - 1;
            VkSubmitInfo submit_info = vku::InitStructHelper(&perf_submit_info);
            submit_info.waitSemaphoreCount = 0;
            submit_info.pWaitSemaphores = NULL;
            submit_info.pWaitDstStageMask = NULL;
            submit_info.commandBufferCount = 1;
            submit_info.pCommandBuffers = &m_command_buffer.handle();
            submit_info.signalSemaphoreCount = 0;
            submit_info.pSignalSemaphores = NULL;

            vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
        }

        vk::QueueWaitIdle(queue);

        // The stride is too small to return the data
        if (counterIndices.size() > 2) {
            m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-04519");
            vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
                                    sizeof(VkPerformanceCounterResultKHR) * (results.size() - 1), 0);
            m_errorMonitor->VerifyFound();
        }

        // Invalid stride
        {
            std::vector<VkPerformanceCounterResultKHR> results_invalid_stride;
            results_invalid_stride.resize(counterIndices.size() * 2);
            m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-03229");
            vk::GetQueryPoolResults(
                device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results_invalid_stride.size(),
                &results_invalid_stride[0], sizeof(VkPerformanceCounterResultKHR) * results_invalid_stride.size() + 4,
                VK_QUERY_RESULT_WAIT_BIT);
            m_errorMonitor->VerifyFound();
        }

        // Invalid flags for vkCmdCopyQueryPoolResults
        if (perf_query_props.allowCommandBufferQueryCopies) {
            m_command_buffer.Begin(&command_buffer_begin_info);
            m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-queryType-09440");
            vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 0,
                                        sizeof(VkPerformanceCounterResultKHR) * results.size(),
                                        VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
            m_errorMonitor->VerifyFound();
            m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-queryType-09440");
            vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 0,
                                        sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_PARTIAL_BIT);
            m_errorMonitor->VerifyFound();
            m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-queryType-09440");
            vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 0,
                                        sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_64_BIT);
            m_errorMonitor->VerifyFound();
            if (IsExtensionsEnabled(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME)) {
                m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-queryType-09440");
                vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 0,
                                            sizeof(VkPerformanceCounterResultKHR) * results.size(),
                                            VK_QUERY_RESULT_WITH_STATUS_BIT_KHR);
                m_errorMonitor->VerifyFound();
            }
            m_command_buffer.End();
        }

        // Invalid flags for vkGetQueryPoolResults
        m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-09440");
        vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
                                sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
        m_errorMonitor->VerifyFound();
        m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-09440");
        vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
                                sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_PARTIAL_BIT);
        m_errorMonitor->VerifyFound();
        m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-09440");
        vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
                                sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_64_BIT);
        m_errorMonitor->VerifyFound();
        if (IsExtensionsEnabled(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME)) {
            m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-11874");
            vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
                                    sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_WITH_STATUS_BIT_KHR);
            m_errorMonitor->VerifyFound();
        }

        vk::GetQueryPoolResults(device(), query_pool, 0, 1, sizeof(VkPerformanceCounterResultKHR) * results.size(), &results[0],
                                sizeof(VkPerformanceCounterResultKHR) * results.size(), VK_QUERY_RESULT_WAIT_BIT);
    }

    vk::ReleaseProfilingLockKHR(device());
}

TEST_F(NegativeQuery, PerformanceResetAndBegin) {
    TEST_DESCRIPTION("Verify that we get an error if we reset & begin a performance query within the same primary command buffer.");
    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::hostQueryReset);
    AddRequiredFeature(vkt::Feature::performanceCounterQueryPools);
    RETURN_IF_SKIP(Init());

    auto queueFamilyProperties = m_device->Physical().queue_properties_;
    uint32_t queueFamilyIndex = queueFamilyProperties.size();
    std::vector<VkPerformanceCounterKHR> counters;
    std::vector<uint32_t> counterIndices;

    // Find a single counter with VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR scope.
    for (uint32_t idx = 0; idx < queueFamilyProperties.size(); idx++) {
        uint32_t nCounters;

        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, nullptr, nullptr);
        if (nCounters == 0) continue;

        counters.resize(nCounters);
        for (auto& c : counters) {
            c = vku::InitStructHelper();
        }
        vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(Gpu(), idx, &nCounters, &counters[0], nullptr);
        queueFamilyIndex = idx;

        for (uint32_t counterIdx = 0; counterIdx < counters.size(); counterIdx++) {
            if (counters[counterIdx].scope == VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR) {
                counterIndices.push_back(counterIdx);
                break;
            }
        }
        break;
    }

    if (counterIndices.empty()) {
        GTEST_SKIP() << "No queue reported a set of counters that needs more than one pass.";
    }

    InitRenderTarget();

    VkQueryPoolPerformanceCreateInfoKHR perf_query_pool_ci = vku::InitStructHelper();
    perf_query_pool_ci.queueFamilyIndex = queueFamilyIndex;
    perf_query_pool_ci.counterIndexCount = counterIndices.size();
    perf_query_pool_ci.pCounterIndices = &counterIndices[0];
    VkQueryPoolCreateInfo query_pool_ci = vku::InitStructHelper(&perf_query_pool_ci);
    query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
    query_pool_ci.queryCount = 1;
    vkt::QueryPool query_pool(*m_device, query_pool_ci);

    VkQueue queue = VK_NULL_HANDLE;
    vk::GetDeviceQueue(device(), queueFamilyIndex, 0, &queue);

    {
        VkAcquireProfilingLockInfoKHR lock_info = vku::InitStructHelper();
        VkResult result = vk::AcquireProfilingLockKHR(device(), &lock_info);
        ASSERT_TRUE(result == VK_SUCCESS);
    }

    {
        vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

        VkCommandBufferBeginInfo command_buffer_begin_info = vku::InitStructHelper();
        command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;

        m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-None-02863");

        m_command_buffer.Reset();
        m_command_buffer.Begin(&command_buffer_begin_info);
        vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
        vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
        vk::CmdEndQuery(m_command_buffer, query_pool, 0);
        m_command_buffer.End();

        {
            VkPerformanceQuerySubmitInfoKHR perf_submit_info = vku::InitStructHelper();
            perf_submit_info.counterPassIndex = 0;
            VkSubmitInfo submit_info = vku::InitStructHelper(&perf_submit_info);
            submit_info.waitSemaphoreCount = 0;
            submit_info.pWaitSemaphores = NULL;
            submit_info.pWaitDstStageMask = NULL;
            submit_info.commandBufferCount = 1;
            submit_info.pCommandBuffers = &m_command_buffer.handle();
            submit_info.signalSemaphoreCount = 0;
            submit_info.pSignalSemaphores = NULL;

            vk::QueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
        }

        vk::QueueWaitIdle(queue);
        m_errorMonitor->VerifyFound();
    }

    vk::ReleaseProfilingLockKHR(device());
}

TEST_F(NegativeQuery, HostResetNotEnabled) {
    TEST_DESCRIPTION("Use vkResetQueryPoolEXT without enabling the feature");

    AddRequiredExtensions(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);

    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    m_errorMonitor->SetDesiredError("VUID-vkResetQueryPool-None-02665");
    vk::ResetQueryPoolEXT(device(), query_pool, 0, 1);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, HostResetFirstQuery) {
    TEST_DESCRIPTION("Bad firstQuery in vkResetQueryPoolEXT");

    AddRequiredExtensions(VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME);
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredFeature(vkt::Feature::hostQueryReset);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    m_errorMonitor->SetDesiredError("VUID-vkResetQueryPool-firstQuery-09436");
    vk::ResetQueryPoolEXT(device(), query_pool, 1, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, HostResetBadRange) {
    TEST_DESCRIPTION("Bad range in vkResetQueryPoolEXT");

    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredFeature(vkt::Feature::hostQueryReset);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    m_errorMonitor->SetDesiredError("VUID-vkResetQueryPool-firstQuery-09437");
    vk::ResetQueryPool(device(), query_pool, 0, 2);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, HostResetQueryPool) {
    TEST_DESCRIPTION("Invalid queryPool in vkResetQueryPoolEXT");

    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredFeature(vkt::Feature::hostQueryReset);
    RETURN_IF_SKIP(Init());

    // Create and destroy a query pool.
    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);
    VkQueryPool bad_pool = query_pool;
    query_pool.Destroy();

    // Attempt to reuse the query pool handle.
    m_errorMonitor->SetDesiredError("VUID-vkResetQueryPool-queryPool-parameter");
    vk::ResetQueryPool(device(), bad_pool, 0, 1);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, HostResetDevice) {
    TEST_DESCRIPTION("Device not matching queryPool in vkResetQueryPoolEXT");

    SetTargetApiVersion(VK_API_VERSION_1_2);
    RETURN_IF_SKIP(InitFramework());

    VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset_features = vku::InitStructHelper();
    GetPhysicalDeviceFeatures2(host_query_reset_features);
    RETURN_IF_SKIP(InitState(nullptr, &host_query_reset_features));

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    // Create a second device with the feature enabled.
    vkt::QueueCreateInfoArray queue_info(m_device->Physical().queue_properties_);
    auto features = m_device->Physical().Features();

    VkDeviceCreateInfo device_create_info = vku::InitStructHelper(&host_query_reset_features);
    device_create_info.queueCreateInfoCount = queue_info.Size();
    device_create_info.pQueueCreateInfos = queue_info.Data();
    device_create_info.pEnabledFeatures = &features;
    device_create_info.enabledExtensionCount = m_device_extension_names.size();
    device_create_info.ppEnabledExtensionNames = m_device_extension_names.data();

    VkDevice second_device;
    ASSERT_EQ(VK_SUCCESS, vk::CreateDevice(Gpu(), &device_create_info, nullptr, &second_device));

    m_errorMonitor->SetDesiredError("VUID-vkResetQueryPool-queryPool-parent");
    // Run vk::ResetQueryPoolExt on the wrong device.
    vk::ResetQueryPool(second_device, query_pool, 0, 1);
    m_errorMonitor->VerifyFound();

    vk::DestroyDevice(second_device, nullptr);
}

TEST_F(NegativeQuery, CmdBufferQueryPoolDestroyed) {
    TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid due to a query pool dependency being destroyed.");
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    m_command_buffer.End();

    m_errorMonitor->SetDesiredError("VUID-vkQueueSubmit-pCommandBuffers-00070");
    // Destroy query pool dependency prior to submit to cause ERROR
    query_pool.Destroy();
    m_default_queue->Submit(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, BeginQueryOnTimestampPool) {
    TEST_DESCRIPTION("Call CmdBeginQuery on a TIMESTAMP query pool.");

    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-02804");
    VkCommandBufferBeginInfo begin_info = vku::InitStructHelper();

    vk::BeginCommandBuffer(m_command_buffer, &begin_info);
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    vk::EndCommandBuffer(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, InsideRenderPass) {
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);

    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-None-07007");
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_errorMonitor->VerifyFound();

    m_command_buffer.EndRenderPass();
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();
}

TEST_F(NegativeQuery, OutsideRenderPass) {
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);

    m_errorMonitor->SetDesiredError("VUID-vkCmdEndRenderPass-None-07004");
    m_command_buffer.EndRenderPass();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, InsideRenderPassDynamicRendering) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper();
    color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

    VkRenderingInfo begin_rendering_info = vku::InitStructHelper();
    begin_rendering_info.layerCount = 1;
    begin_rendering_info.renderArea = {{0, 0}, {64, 64}};
    begin_rendering_info.colorAttachmentCount = 1;
    begin_rendering_info.pColorAttachments = &color_attachment;

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    m_command_buffer.BeginRendering(begin_rendering_info);

    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-None-07007");
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_errorMonitor->VerifyFound();

    m_command_buffer.EndRendering();
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();
}

TEST_F(NegativeQuery, OutsideRenderPassDynamicRendering) {
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::dynamicRendering);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    VkRenderingAttachmentInfo color_attachment = vku::InitStructHelper();
    color_attachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

    VkRenderingInfo begin_rendering_info = vku::InitStructHelper();
    begin_rendering_info.layerCount = 1;
    begin_rendering_info.renderArea = {{0, 0}, {64, 64}};
    begin_rendering_info.colorAttachmentCount = 1;
    begin_rendering_info.pColorAttachments = &color_attachment;

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    m_command_buffer.BeginRendering(begin_rendering_info);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);

    m_errorMonitor->SetDesiredError("VUID-vkCmdEndRendering-None-06999");
    m_command_buffer.EndRendering();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, PoolCreate) {
    TEST_DESCRIPTION("Attempt to create a query pool for PIPELINE_STATISTICS without enabling pipeline stats for the device.");

    RETURN_IF_SKIP(Init());

    vkt::QueueCreateInfoArray queue_info(m_device->Physical().queue_properties_);

    VkDevice local_device;
    VkDeviceCreateInfo device_create_info = vku::InitStructHelper();
    auto features = m_device->Physical().Features();
    // Intentionally disable pipeline stats
    features.pipelineStatisticsQuery = VK_FALSE;
    device_create_info.queueCreateInfoCount = queue_info.Size();
    device_create_info.pQueueCreateInfos = queue_info.Data();
    device_create_info.enabledLayerCount = 0;
    device_create_info.ppEnabledLayerNames = NULL;
    device_create_info.pEnabledFeatures = &features;
    device_create_info.enabledExtensionCount = m_device_extension_names.size();
    device_create_info.ppEnabledExtensionNames = m_device_extension_names.data();
    VkResult err = vk::CreateDevice(Gpu(), &device_create_info, nullptr, &local_device);
    ASSERT_EQ(VK_SUCCESS, err);

    VkQueryPoolCreateInfo qpci = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 1);
    qpci.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT;
    VkQueryPool query_pool;

    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-00791");
    vk::CreateQueryPool(local_device, &qpci, nullptr, &query_pool);
    m_errorMonitor->VerifyFound();

    qpci.queryType = VK_QUERY_TYPE_OCCLUSION;
    qpci.queryCount = 0;
    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryCount-02763");
    vk::CreateQueryPool(local_device, &qpci, nullptr, &query_pool);
    m_errorMonitor->VerifyFound();

    vk::DestroyDevice(local_device, nullptr);
}

TEST_F(NegativeQuery, Sizes) {
    TEST_DESCRIPTION("Invalid size of using queries commands.");

    RETURN_IF_SKIP(Init());

    vkt::Buffer buffer(*m_device, 128, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
    VkMemoryRequirements mem_reqs = {};
    vk::GetBufferMemoryRequirements(device(), buffer, &mem_reqs);
    const VkDeviceSize buffer_size = mem_reqs.size;

    const uint32_t query_pool_size = 4;
    vkt::QueryPool occlusion_query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, query_pool_size);

    m_command_buffer.Begin();

    // FirstQuery is too large
    m_errorMonitor->SetDesiredError("VUID-vkCmdResetQueryPool-firstQuery-09436");
    m_errorMonitor->SetDesiredError("VUID-vkCmdResetQueryPool-firstQuery-09437");
    vk::CmdResetQueryPool(m_command_buffer, occlusion_query_pool, query_pool_size, 1);
    m_errorMonitor->VerifyFound();

    // Sum of firstQuery and queryCount is too large
    m_errorMonitor->SetDesiredError("VUID-vkCmdResetQueryPool-firstQuery-09437");
    vk::CmdResetQueryPool(m_command_buffer, occlusion_query_pool, 1, query_pool_size);
    m_errorMonitor->VerifyFound();

    // Actually reset all queries so they can be used
    vk::CmdResetQueryPool(m_command_buffer, occlusion_query_pool, 0, query_pool_size);

    vk::CmdBeginQuery(m_command_buffer, occlusion_query_pool, 0, 0);

    // Query index to large
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-query-00810");
    vk::CmdEndQuery(m_command_buffer, occlusion_query_pool, query_pool_size);
    m_errorMonitor->VerifyFound();

    vk::CmdEndQuery(m_command_buffer, occlusion_query_pool, 0);

    // FirstQuery is too large
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-firstQuery-09436");
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-firstQuery-09437");
    vk::CmdCopyQueryPoolResults(m_command_buffer, occlusion_query_pool, query_pool_size, 1, buffer, 0, 0, 0);
    m_errorMonitor->VerifyFound();

    // sum of firstQuery and queryCount is too large
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-firstQuery-09437");
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-queryCount-09438");
    vk::CmdCopyQueryPoolResults(m_command_buffer, occlusion_query_pool, 1, query_pool_size, buffer, 0, 0, 0);
    m_errorMonitor->VerifyFound();

    // Offset larger than buffer size
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-dstOffset-00819");
    vk::CmdCopyQueryPoolResults(m_command_buffer, occlusion_query_pool, 0, 1, buffer, buffer_size + 4, 0, 0);
    m_errorMonitor->VerifyFound();

    // Buffer does not have enough storage from offset to contain result of each query
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-dstBuffer-00824");
    vk::CmdCopyQueryPoolResults(m_command_buffer, occlusion_query_pool, 0, 2, buffer, buffer_size - 4, 4, 0);
    m_errorMonitor->VerifyFound();

    // Query is not a timestamp type
    if (HasZeroTimestampValidBits()) {
        m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-timestampValidBits-00829");
    }
    m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-queryPool-01416");
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, occlusion_query_pool, 0);
    m_errorMonitor->VerifyFound();

    m_command_buffer.End();

    const size_t out_data_size = 16;
    uint8_t data[out_data_size];

    // FirstQuery is too large
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-firstQuery-09436");
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-firstQuery-09437");
    vk::GetQueryPoolResults(device(), occlusion_query_pool, query_pool_size, 1, out_data_size, &data, 4, 0);
    m_errorMonitor->VerifyFound();

    // Sum of firstQuery and queryCount is too large
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-firstQuery-09437");
    vk::GetQueryPoolResults(device(), occlusion_query_pool, 1, query_pool_size, out_data_size, &data, 4, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, PreciseBit) {
    TEST_DESCRIPTION("Check for correct Query Precise Bit circumstances.");
    AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery);
    AddRequiredFeature(vkt::Feature::occlusionQueryPrecise);
    RETURN_IF_SKIP(Init());

    auto features = m_device->Physical().Features();

    // Test for precise bit when query type is not OCCLUSION
    if (features.occlusionQueryPrecise) {
        vkt::Event event(*m_device);

        VkQueryPoolCreateInfo query_pool_create_info = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 3);
        query_pool_create_info.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT |
                                                    VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT |
                                                    VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT;
        vkt::QueryPool query_pool(*m_device, query_pool_create_info);

        m_command_buffer.Begin();
        vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, query_pool_create_info.queryCount);
        m_command_buffer.End();

        m_default_queue->SubmitAndWait(m_command_buffer);

        m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-00800");

        m_command_buffer.Begin();
        vk::CmdBeginQuery(m_command_buffer, query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
        m_errorMonitor->VerifyFound();
        // vk::CmdBeginQuery(m_command_buffer, query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
        m_command_buffer.End();

        const size_t out_data_size = 64;
        uint8_t data[out_data_size];
        // The dataSize is too small to return the data
        m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-dataSize-00817");
        vk::GetQueryPoolResults(device(), query_pool, 0, 3, 8, &data, 12, 0);
        m_errorMonitor->VerifyFound();
    }

    // Test for precise bit when precise feature is not available
    features.occlusionQueryPrecise = false;
    vkt::Device test_device(Gpu(), m_device_extension_names, &features);

    VkCommandPoolCreateInfo pool_create_info = vku::InitStructHelper();
    pool_create_info.queueFamilyIndex = test_device.graphics_queue_node_index_;

    VkCommandPool command_pool;
    vk::CreateCommandPool(test_device, &pool_create_info, nullptr, &command_pool);

    VkCommandBufferAllocateInfo cmd = vku::InitStructHelper();
    cmd.commandPool = command_pool;
    cmd.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
    cmd.commandBufferCount = 1;

    VkCommandBuffer cmd_buffer;
    VkResult err = vk::AllocateCommandBuffers(test_device, &cmd, &cmd_buffer);
    ASSERT_EQ(VK_SUCCESS, err);

    VkCommandBuffer cmd_buffer2;
    err = vk::AllocateCommandBuffers(test_device, &cmd, &cmd_buffer2);
    ASSERT_EQ(VK_SUCCESS, err);

    VkEvent event;
    VkEventCreateInfo event_create_info = vku::InitStructHelper();
    vk::CreateEvent(test_device, &event_create_info, nullptr, &event);

    VkCommandBufferBeginInfo begin_info = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
                                           VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, nullptr};

    vkt::QueryPool query_pool(test_device, VK_QUERY_TYPE_OCCLUSION, 2);

    vk::BeginCommandBuffer(cmd_buffer2, &begin_info);
    vk::CmdResetQueryPool(cmd_buffer2, query_pool, 0, 2);
    vk::EndCommandBuffer(cmd_buffer2);

    VkSubmitInfo submit_info = vku::InitStructHelper();
    submit_info.commandBufferCount = 1;
    submit_info.pCommandBuffers = &cmd_buffer2;
    vk::QueueSubmit(test_device.QueuesWithGraphicsCapability().front()->handle(), 1, &submit_info, VK_NULL_HANDLE);
    vk::QueueWaitIdle(test_device.QueuesWithGraphicsCapability().front()->handle());

    vk::BeginCommandBuffer(cmd_buffer, &begin_info);
    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-00800");
    vk::CmdBeginQuery(cmd_buffer, query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
    m_errorMonitor->VerifyFound();
    vk::EndCommandBuffer(cmd_buffer);

    const size_t out_data_size = 16;
    uint8_t data[out_data_size];
    // The dataSize is too small to return the data
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-dataSize-00817");
    vk::GetQueryPoolResults(test_device, query_pool, 0, 2, 8, &data, out_data_size / 2, 0);
    m_errorMonitor->VerifyFound();

    vk::DestroyEvent(test_device, event, nullptr);
    vk::DestroyCommandPool(test_device, command_pool, nullptr);
}

TEST_F(NegativeQuery, PoolPartialTimestamp) {
    TEST_DESCRIPTION("Request partial result on timestamp query.");

    RETURN_IF_SKIP(Init());
    InitRenderTarget();
    if (HasZeroTimestampValidBits()) {
        GTEST_SKIP() << "Device graphic queue has timestampValidBits of 0, skipping.\n";
    }

    vkt::Buffer buffer(*m_device, 128, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    // Use setup as a positive test...
    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);

    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-queryType-09439");
    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 0, 8, VK_QUERY_RESULT_PARTIAL_BIT);
    m_errorMonitor->VerifyFound();

    m_command_buffer.End();

    // Submit cmd buffer and wait for it.
    VkSubmitInfo submit_info = vku::InitStructHelper();
    submit_info.commandBufferCount = 1;
    submit_info.pCommandBuffers = &m_command_buffer.handle();
    vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE);
    m_default_queue->Wait();

    // Attempt to obtain partial results.
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-09439");
    uint32_t data_space[16];
    m_errorMonitor->SetUnexpectedError("Cannot get query results on queryPool");
    vk::GetQueryPoolResults(*m_device, query_pool, 0, 1, sizeof(data_space), &data_space, sizeof(uint32_t),
                            VK_QUERY_RESULT_PARTIAL_BIT);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, PerformanceQueryIntel) {
    TEST_DESCRIPTION("Call CmdCopyQueryPoolResults for an Intel performance query.");

    AddRequiredExtensions(VK_INTEL_PERFORMANCE_QUERY_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkInitializePerformanceApiInfoINTEL performance_api_info_intel = vku::InitStructHelper();
    vk::InitializePerformanceApiINTEL(device(), &performance_api_info_intel);

    vkt::Buffer buffer(*m_device, 128, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL, 1);

    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-queryType-02734");
    m_command_buffer.Begin();
    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 0, 8, 0);
    m_command_buffer.End();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, PoolInUseDestroyed) {
    TEST_DESCRIPTION("Delete in-use query pool.");

    RETURN_IF_SKIP(Init());
    if (HasZeroTimestampValidBits()) {
        GTEST_SKIP() << "Device graphic queue has timestampValidBits of 0, skipping.";
    }
    InitRenderTarget();

    VkQueryPool query_pool;
    VkQueryPoolCreateInfo query_pool_ci = vku::InitStructHelper();
    query_pool_ci.queryType = VK_QUERY_TYPE_TIMESTAMP;
    query_pool_ci.queryCount = 1;
    vk::CreateQueryPool(device(), &query_pool_ci, nullptr, &query_pool);

    m_command_buffer.Begin();
    // Use query pool to create binding with cmd buffer
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);
    m_command_buffer.End();

    // Submit cmd buffer and then destroy query pool while in-flight
    m_default_queue->Submit(m_command_buffer);

    m_errorMonitor->SetDesiredError("VUID-vkDestroyQueryPool-queryPool-00793");
    vk::DestroyQueryPool(*m_device, query_pool, NULL);
    m_errorMonitor->VerifyFound();

    m_default_queue->Wait();
    // Now that cmd buffer done we can safely destroy query_pool
    m_errorMonitor->SetUnexpectedError("If queryPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle");
    m_errorMonitor->SetUnexpectedError("Unable to remove QueryPool obj");
    vk::DestroyQueryPool(*m_device, query_pool, NULL);
}

TEST_F(NegativeQuery, WriteTimeStamp) {
    TEST_DESCRIPTION("Test for invalid query slot in query pool.");

    AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::synchronization2);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();
    if (HasZeroTimestampValidBits()) {
        GTEST_SKIP() << "Device graphic queue has timestampValidBits of 0, skipping.\n";
    }

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-query-04904");
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 1);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, CmdEndQueryIndexedEXTIndex) {
    TEST_DESCRIPTION("Test InvalidCmdEndQueryIndexedEXT with invalid index");

    AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_properties = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(transform_feedback_properties);
    if (transform_feedback_properties.maxTransformFeedbackStreams < 1) {
        GTEST_SKIP() << "maxTransformFeedbackStreams < 1";
    }

    vkt::QueryPool tf_query_pool(*m_device, VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 1);
    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    m_command_buffer.Begin();
    vk::CmdBeginQueryIndexedEXT(m_command_buffer, tf_query_pool, 0, 0, 0);
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-queryType-06694");
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-queryType-06696");
    vk::CmdEndQueryIndexedEXT(m_command_buffer, tf_query_pool, 0, transform_feedback_properties.maxTransformFeedbackStreams);

    vk::CmdBeginQueryIndexedEXT(m_command_buffer, query_pool, 0, 0, 0);
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-queryType-06695");
    vk::CmdEndQueryIndexedEXT(m_command_buffer, query_pool, 0, 1);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-None-02342");
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-query-02343");
    vk::CmdEndQueryIndexedEXT(m_command_buffer, query_pool, 1, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, CmdEndQueryIndexedEXTPrimitiveGenerated) {
    TEST_DESCRIPTION("Test InvalidCmdEndQueryIndexedEXT with invalid index");

    SetTargetApiVersion(VK_API_VERSION_1_1);

    AddRequiredExtensions(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::primitivesGeneratedQueryWithNonZeroStreams);
    AddRequiredFeature(vkt::Feature::primitivesGeneratedQuery);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_properties = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(transform_feedback_properties);

    vkt::QueryPool tf_query_pool(*m_device, VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 1);
    vkt::QueryPool pg_query_pool(*m_device, VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT, 1);
    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    m_command_buffer.Begin();

    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQueryIndexedEXT-queryType-02339");
    vk::CmdBeginQueryIndexedEXT(m_command_buffer, tf_query_pool, 0, 0, transform_feedback_properties.maxTransformFeedbackStreams);
    m_errorMonitor->VerifyFound();

    vk::CmdBeginQueryIndexedEXT(m_command_buffer, tf_query_pool, 0, 0, 0);

    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-queryType-06696");
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-queryType-06694");
    vk::CmdEndQueryIndexedEXT(m_command_buffer, tf_query_pool, 0, transform_feedback_properties.maxTransformFeedbackStreams);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQueryIndexedEXT-queryType-06690");
    vk::CmdBeginQueryIndexedEXT(m_command_buffer, pg_query_pool, 0, 0, transform_feedback_properties.maxTransformFeedbackStreams);
    m_errorMonitor->VerifyFound();

    vk::CmdBeginQueryIndexedEXT(m_command_buffer, query_pool, 0, 0, 0);
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-queryType-06695");
    vk::CmdEndQueryIndexedEXT(m_command_buffer, query_pool, 0, 1);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, TransformFeedbackStream) {
    TEST_DESCRIPTION(
        "Call CmdBeginQuery with query type transform feedback stream when transformFeedbackQueries is not supported.");

    AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(transform_feedback_props);
    if (transform_feedback_props.transformFeedbackQueries) {
        GTEST_SKIP() << "Transform feedback queries are supported";
    }

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT, 1);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-02328");
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, GetResultsFlags) {
    TEST_DESCRIPTION("Test GetQueryPoolResults with invalid pData and stride");
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    const size_t out_data_size = 16;
    uint8_t data[out_data_size];

    VkQueryResultFlags flags = VK_QUERY_RESULT_WITH_STATUS_BIT_KHR | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT;

    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-flags-09443");
    vk::GetQueryPoolResults(device(), query_pool, 0, 1, out_data_size, data + 1, 4, flags);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, GetResultsStride) {
    TEST_DESCRIPTION("Test GetQueryPoolResults with invalid queryCount and stride");
    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 2);
    uint8_t data[8];

    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryCount-09438");
    vk::GetQueryPoolResults(device(), query_pool, 0, 2, 8, data, 0, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, ResultStatusOnly) {
    TEST_DESCRIPTION("Request result status only query result.");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_VIDEO_QUEUE_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    uint32_t qf_count;
    vk::GetPhysicalDeviceQueueFamilyProperties2(Gpu(), &qf_count, nullptr);

    std::vector<VkQueueFamilyProperties2> queueFamilyProps2(qf_count, vku::InitStruct<VkQueueFamilyProperties2>());
    std::vector<VkQueueFamilyQueryResultStatusPropertiesKHR> queueFamilyQueryResultStatusProps(
        qf_count, vku::InitStruct<VkQueueFamilyQueryResultStatusPropertiesKHR>());
    for (uint32_t i = 0; i < qf_count; ++i) {
        queueFamilyProps2[i].pNext = &queueFamilyQueryResultStatusProps[i];
    }
    vk::GetPhysicalDeviceQueueFamilyProperties2(Gpu(), &qf_count, queueFamilyProps2.data());

    bool has_queue_with_result_status_only_support = false;
    for (uint32_t qfi = 0; qfi < qf_count; ++qfi) {
        if (queueFamilyQueryResultStatusProps[qfi].queryResultStatusSupport) {
            has_queue_with_result_status_only_support = true;
            break;
        }
    }

    if (!has_queue_with_result_status_only_support) {
        GTEST_SKIP() << "Test requires queue to support result status queries";
    }

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR, 1);
    if (!query_pool.initialized()) {
        GTEST_SKIP() << "Required query not supported";
    }

    const size_t out_data_size = 16;
    uint8_t data[out_data_size];
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryType-09442");
    vk::GetQueryPoolResults(device(), query_pool, 0, 1, out_data_size, &data, sizeof(uint32_t), 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, DestroyActiveQueryPool) {
    TEST_DESCRIPTION("Destroy query pool after GetQueryPoolResults() without VK_QUERY_RESULT_PARTIAL_BIT returns VK_SUCCESS");

    RETURN_IF_SKIP(Init());
    if (HasZeroTimestampValidBits()) {
        GTEST_SKIP() << "Device graphic queue has timestampValidBits of 0, skipping.";
    }

    VkQueryPoolCreateInfo query_pool_create_info = vku::InitStructHelper();
    query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
    query_pool_create_info.queryCount = 1;

    VkQueryPool query_pool;
    vk::CreateQueryPool(device(), &query_pool_create_info, nullptr, &query_pool);

    VkCommandBufferBeginInfo cmd_begin = vku::InitStructHelper();
    cmd_begin.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
    m_command_buffer.Begin(&cmd_begin);
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
    m_command_buffer.End();

    m_default_queue->Submit(m_command_buffer);

    const size_t out_data_size = 16;
    uint8_t data[out_data_size];
    VkResult res;
    do {
        res = vk::GetQueryPoolResults(device(), query_pool, 0, 1, out_data_size, &data, 4, 0);
    } while (res != VK_SUCCESS);

    // Submit the command buffer again, making query pool in use and invalid to destroy
    m_default_queue->Submit(m_command_buffer);

    m_errorMonitor->SetDesiredError("VUID-vkDestroyQueryPool-queryPool-00793");
    vk::DestroyQueryPool(*m_device, query_pool, nullptr);
    m_errorMonitor->VerifyFound();

    m_default_queue->Wait();
    vk::DestroyQueryPool(*m_device, query_pool, nullptr);
}

TEST_F(NegativeQuery, MultiviewBeginQuery) {
    TEST_DESCRIPTION("Test CmdBeginQuery in subpass with multiview");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredFeature(vkt::Feature::multiview);
    RETURN_IF_SKIP(Init());

    VkAttachmentDescription attach = {};
    attach.format = VK_FORMAT_B8G8R8A8_UNORM;
    attach.samples = VK_SAMPLE_COUNT_1_BIT;
    attach.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
    attach.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
    attach.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
    attach.finalLayout = VK_IMAGE_LAYOUT_GENERAL;

    VkAttachmentReference color_att = {};
    color_att.layout = VK_IMAGE_LAYOUT_GENERAL;

    VkSubpassDescription subpass = {};
    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
    subpass.colorAttachmentCount = 1;
    subpass.pColorAttachments = &color_att;

    uint32_t view_masks[] = {0x3u};
    uint32_t correlation_masks[] = {0x1u};
    VkRenderPassMultiviewCreateInfo rpmv_ci = vku::InitStructHelper();
    rpmv_ci.subpassCount = 1;
    rpmv_ci.pViewMasks = view_masks;
    rpmv_ci.correlationMaskCount = 1;
    rpmv_ci.pCorrelationMasks = correlation_masks;

    VkRenderPassCreateInfo rp_ci = vku::InitStructHelper(&rpmv_ci);
    rp_ci.attachmentCount = 1;
    rp_ci.pAttachments = &attach;
    rp_ci.subpassCount = 1;
    rp_ci.pSubpasses = &subpass;

    vkt::RenderPass render_pass(*m_device, rp_ci);

    VkImageCreateInfo image_ci = vku::InitStructHelper();
    image_ci.imageType = VK_IMAGE_TYPE_2D;
    image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
    image_ci.extent = {64, 64, 1};
    image_ci.mipLevels = 1;
    image_ci.arrayLayers = 4;
    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
    image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
    vkt::Image image(*m_device, image_ci, vkt::set_layout);
    vkt::ImageView image_view = image.CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, 0, 1, 0, 4);
    VkImageView image_view_handle = image_view;

    vkt::Framebuffer framebuffer(*m_device, render_pass, 1, &image_view_handle, 64, 64);

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 2);

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderPass(render_pass, framebuffer, 64, 64);
    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-query-00808");
    vk::CmdBeginQuery(m_command_buffer, query_pool, 1, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.EndRenderPass();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, PipelineStatisticsQuery) {
    TEST_DESCRIPTION("Test unsupported pipeline statistics queries");

    AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery);

    RETURN_IF_SKIP(Init());

    const std::optional<uint32_t> decode_queue_family_index = m_device->QueueFamily(VK_QUEUE_VIDEO_DECODE_BIT_KHR);
    const std::optional<uint32_t> compute_queue_family_index = m_device->ComputeOnlyQueueFamily();
    if (!decode_queue_family_index && !compute_queue_family_index) {
        GTEST_SKIP() << "required queue families not found";
    }

    if (decode_queue_family_index) {
        vkt::CommandPool command_pool(*m_device, decode_queue_family_index.value());

        vkt::CommandBuffer command_buffer(*m_device, command_pool);
        command_buffer.Begin();

        VkQueryPoolCreateInfo qpci = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 1);
        qpci.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT;
        vkt::QueryPool query_pool(*m_device, qpci);

        m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-00805");
        vk::CmdBeginQuery(command_buffer, query_pool, 0, 0);
        m_errorMonitor->VerifyFound();

        command_buffer.End();
    }

    if (compute_queue_family_index) {
        vkt::CommandPool command_pool(*m_device, compute_queue_family_index.value());

        vkt::CommandBuffer command_buffer(*m_device, command_pool);
        command_buffer.Begin();

        VkQueryPoolCreateInfo qpci = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 1);
        qpci.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT;
        vkt::QueryPool query_pool(*m_device, qpci);

        m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-00804");
        vk::CmdBeginQuery(command_buffer, query_pool, 0, 0);
        m_errorMonitor->VerifyFound();

        command_buffer.End();
    }
}

TEST_F(NegativeQuery, GetQueryPoolResultsDataAndStride) {
    TEST_DESCRIPTION("Test pData and stride multiple in GetQueryPoolResults");

    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 2);

    const size_t out_data_size = 16;
    uint8_t data[out_data_size];
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryCount-12251");
    vk::GetQueryPoolResults(device(), query_pool, 0, 2, out_data_size, &data, 3, 0);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-flags-02828");
    vk::GetQueryPoolResults(device(), query_pool, 0, 1, out_data_size, &data[1], 4, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, PrimitivesGenerated) {
    TEST_DESCRIPTION("Test unsupported primitives generated queries");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::primitivesGeneratedQuery);

    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceTransformFeedbackPropertiesEXT transform_feedback_properties = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(transform_feedback_properties);

    const std::optional<uint32_t> compute_queue_family_index = m_device->ComputeOnlyQueueFamily();
    if (!compute_queue_family_index) {
        GTEST_SKIP() << "required queue family not found, skipping test";
    }
    vkt::CommandPool command_pool(*m_device, compute_queue_family_index.value());

    vkt::CommandBuffer command_buffer(*m_device, command_pool);
    command_buffer.Begin();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT, 1);

    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-06687");
    vk::CmdBeginQuery(command_buffer, query_pool, 0, 0);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQueryIndexedEXT-queryType-06689");
    vk::CmdBeginQueryIndexedEXT(command_buffer, query_pool, 0, 0, 0);
    m_errorMonitor->VerifyFound();

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQueryIndexedEXT-queryType-06690");
    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQueryIndexedEXT-queryType-06691");
    vk::CmdBeginQueryIndexedEXT(m_command_buffer, query_pool, 0, 0, transform_feedback_properties.maxTransformFeedbackStreams);
    m_errorMonitor->VerifyFound();

    vkt::QueryPool occlusion_query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);
    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQueryIndexedEXT-queryType-06692");
    vk::CmdBeginQueryIndexedEXT(m_command_buffer, occlusion_query_pool, 0, 0, 1);
    m_errorMonitor->VerifyFound();

    vk::CmdBeginQueryIndexedEXT(m_command_buffer, query_pool, 0, 0, 0);
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQueryIndexedEXT-queryType-06696");
    vk::CmdEndQueryIndexedEXT(m_command_buffer, query_pool, 0, 1);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, PrimitivesGeneratedFeature) {
    TEST_DESCRIPTION("Test missing primitives generated query feature");

    AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME);

    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT, 1);
    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryType-06688");
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQueryIndexedEXT-queryType-06693");
    vk::CmdBeginQueryIndexedEXT(m_command_buffer, query_pool, 0, 0, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, PrimitivesGeneratedDiscardEnabled) {
    TEST_DESCRIPTION("Test missing primitivesGeneratedQueryWithRasterizerDiscard feature.");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::primitivesGeneratedQuery);

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkPipelineRasterizationStateCreateInfo rs_ci = vku::InitStructHelper();
    rs_ci.lineWidth = 1.0f;
    rs_ci.rasterizerDiscardEnable = VK_TRUE;

    CreatePipelineHelper pipe(*this);
    pipe.rs_state_ci_ = rs_ci;
    // Rasterization discard enable prohibits fragment shader.
    pipe.VertexShaderOnly();
    pipe.CreateGraphicsPipeline();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT, 1);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-primitivesGeneratedQueryWithRasterizerDiscard-06708");

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);

    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);

    m_command_buffer.EndRenderPass();
    m_command_buffer.End();

    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, PrimitivesGeneratedStreams) {
    TEST_DESCRIPTION("Test missing primitivesGeneratedQueryWithNonZeroStreams feature.");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::transformFeedback);
    AddRequiredFeature(vkt::Feature::geometryStreams);
    AddRequiredFeature(vkt::Feature::primitivesGeneratedQuery);

    RETURN_IF_SKIP(Init());

    VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_props = vku::InitStructHelper();
    GetPhysicalDeviceProperties2(xfb_props);
    if (!xfb_props.transformFeedbackRasterizationStreamSelect) {
        GTEST_SKIP() << "VkPhysicalDeviceTransformFeedbackFeaturesEXT::transformFeedbackRasterizationStreamSelect is VK_FALSE";
    }
    InitRenderTarget();

    VkPipelineRasterizationStateStreamCreateInfoEXT rasterization_streams = vku::InitStructHelper();
    rasterization_streams.rasterizationStream = 1;

    CreatePipelineHelper pipe(*this);
    pipe.rs_state_ci_.pNext = &rasterization_streams;
    pipe.CreateGraphicsPipeline();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT, 1);

    m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-primitivesGeneratedQueryWithNonZeroStreams-06709");

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);

    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    vk::CmdDraw(m_command_buffer, 3, 1, 0, 0);
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);

    m_command_buffer.EndRenderPass();
    m_command_buffer.End();

    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, CommandBufferMissingOcclusion) {
    TEST_DESCRIPTION(
        "Test executing secondary command buffer without VkCommandBufferInheritanceInfo::occlusionQueryEnable enabled while "
        "occlusion query is active.");
    AddRequiredFeature(vkt::Feature::inheritedQueries);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

    VkCommandBufferInheritanceInfo cbii = vku::InitStructHelper();
    cbii.renderPass = m_renderPass;
    cbii.framebuffer = Framebuffer();
    cbii.occlusionQueryEnable = VK_FALSE;  // Invalid

    VkCommandBufferBeginInfo cbbi = vku::InitStructHelper();
    cbbi.pInheritanceInfo = &cbii;

    VkCommandBuffer secondary_handle = secondary;
    vk::BeginCommandBuffer(secondary_handle, &cbbi);
    vk::EndCommandBuffer(secondary_handle);

    m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBuffer-00102");
    m_command_buffer.Begin();
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    vk::CmdExecuteCommands(m_command_buffer, 1, &secondary_handle);
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, CommandBufferInheritanceFlags) {
    TEST_DESCRIPTION("Test executing secondary command buffer with bad VkCommandBufferInheritanceInfo::queryFlags.");
    AddRequiredFeature(vkt::Feature::occlusionQueryPrecise);
    AddRequiredFeature(vkt::Feature::inheritedQueries);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

    VkCommandBufferInheritanceInfo cbii = vku::InitStructHelper();
    cbii.renderPass = m_renderPass;
    cbii.framebuffer = Framebuffer();
    cbii.occlusionQueryEnable = VK_TRUE;
    cbii.queryFlags = 0;

    VkCommandBufferBeginInfo cbbi = vku::InitStructHelper();
    cbbi.pInheritanceInfo = &cbii;

    VkCommandBuffer secondary_handle = secondary;
    vk::BeginCommandBuffer(secondary_handle, &cbbi);
    vk::EndCommandBuffer(secondary_handle);

    m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBuffer-00103");
    m_command_buffer.Begin();
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
    vk::CmdExecuteCommands(m_command_buffer, 1, &secondary_handle);
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, MeshShaderQueries) {
    TEST_DESCRIPTION("Invalid usage without meshShaderQueries enabled");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_MESH_SHADER_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery);
    RETURN_IF_SKIP(Init());

    VkQueryPool pool = VK_NULL_HANDLE;

    VkQueryPoolCreateInfo query_pool_info = vku::InitStructHelper();
    query_pool_info.queryType = VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT;
    query_pool_info.flags = 0;
    query_pool_info.queryCount = 1;
    query_pool_info.pipelineStatistics = 0;
    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-meshShaderQueries-07068");
    vk::CreateQueryPool(*m_device, &query_pool_info, nullptr, &pool);
    m_errorMonitor->VerifyFound();

    query_pool_info.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS;
    query_pool_info.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_TASK_SHADER_INVOCATIONS_BIT_EXT;
    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-meshShaderQueries-07069");
    vk::CreateQueryPool(*m_device, &query_pool_info, nullptr, &pool);
    m_errorMonitor->VerifyFound();

    query_pool_info.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_MESH_SHADER_INVOCATIONS_BIT_EXT;
    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-meshShaderQueries-07069");
    vk::CreateQueryPool(*m_device, &query_pool_info, nullptr, &pool);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, WriteTimestampWithoutQueryPool) {
    TEST_DESCRIPTION("call vkCmdWriteTimestamp(2) with queryPool being invalid.");

    AddRequiredExtensions(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::synchronization2);
    RETURN_IF_SKIP(Init());

    if (HasZeroTimestampValidBits()) {
        GTEST_SKIP() << "Device graphic queue has timestampValidBits of 0, skipping.\n";
    }

    VkQueryPool bad_query_pool = CastFromUint64<VkQueryPool>(0xFFFFEEEE);

    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-queryPool-parameter");
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, bad_query_pool, 0);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp2-queryPool-parameter");
    vk::CmdWriteTimestamp2KHR(m_command_buffer, VK_PIPELINE_STAGE_2_NONE, bad_query_pool, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, DestroyWithoutQueryPool) {
    TEST_DESCRIPTION("call vkDestryQueryPool with queryPool being invalid.");
    RETURN_IF_SKIP(Init());
    VkQueryPool bad_query_pool = CastFromUint64<VkQueryPool>(0xFFFFEEEE);
    m_errorMonitor->SetDesiredError("VUID-vkDestroyQueryPool-queryPool-parameter");
    vk::DestroyQueryPool(device(), bad_query_pool, nullptr);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, GetQueryPoolResultsWithoutQueryPool) {
    TEST_DESCRIPTION("call vkGetQueryPoolResults with queryPool being invalid.");
    RETURN_IF_SKIP(Init());
    VkQueryPool bad_query_pool = CastFromUint64<VkQueryPool>(0xFFFFEEEE);
    const size_t out_data_size = 16;
    uint8_t data[out_data_size];
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-queryPool-parameter");
    vk::GetQueryPoolResults(device(), bad_query_pool, 0, 1, out_data_size, &data, 4, 0);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, CmdEndQueryWithoutQueryPool) {
    TEST_DESCRIPTION("call vkCmdEndQuery with queryPool being invalid.");
    RETURN_IF_SKIP(Init());

    VkQueryPool bad_query_pool = CastFromUint64<VkQueryPool>(0xFFFFEEEE);
    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    m_command_buffer.Begin();
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);

    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-queryPool-parameter");
    vk::CmdEndQuery(m_command_buffer, bad_query_pool, 0);
    m_errorMonitor->VerifyFound();

    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();
}

TEST_F(NegativeQuery, CmdCopyQueryPoolResultsWithoutQueryPool) {
    TEST_DESCRIPTION("call vkCmdCopyQueryPoolResults with queryPool being invalid.");
    RETURN_IF_SKIP(Init());

    VkQueryPool bad_query_pool = CastFromUint64<VkQueryPool>(0xFFFFEEEE);
    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    m_command_buffer.Begin();
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);

    vkt::Buffer buffer(*m_device, 1024, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-queryPool-parameter");
    vk::CmdCopyQueryPoolResults(m_command_buffer, bad_query_pool, 0, 1, buffer, 0, 0, VK_QUERY_RESULT_WAIT_BIT);
    m_errorMonitor->VerifyFound();

    m_command_buffer.End();
}

TEST_F(NegativeQuery, CmdResetQueryPoolWithoutQueryPool) {
    TEST_DESCRIPTION("call vkCmdResetQueryPool with queryPool being invalid.");
    RETURN_IF_SKIP(Init());
    VkQueryPool bad_query_pool = CastFromUint64<VkQueryPool>(0xFFFFEEEE);
    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdResetQueryPool-queryPool-parameter");
    vk::CmdResetQueryPool(m_command_buffer, bad_query_pool, 0, 1);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, ResetQueryPoolWithoutQueryPool) {
    TEST_DESCRIPTION("call vkResetQueryPool with queryPool being invalid.");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    RETURN_IF_SKIP(Init());
    VkQueryPool bad_query_pool = CastFromUint64<VkQueryPool>(0xFFFFEEEE);
    m_errorMonitor->SetDesiredError("VUID-vkResetQueryPool-queryPool-parameter");
    vk::ResetQueryPool(device(), bad_query_pool, 0, 1);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, ActiveEndQuery) {
    TEST_DESCRIPTION("Check all queries for vkCmdEndQuery are active");
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    m_errorMonitor->SetDesiredError("VUID-vkCmdEndQuery-None-01923");
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, ActiveCmdResetQueryPool) {
    TEST_DESCRIPTION("Check all queries for vkCmdResetQueryPool are not active");
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    m_errorMonitor->SetDesiredError("VUID-vkCmdResetQueryPool-None-02841");
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    m_errorMonitor->VerifyFound();
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();
}

TEST_F(NegativeQuery, ActiveCmdCopyQueryPoolResults) {
    TEST_DESCRIPTION("Check all queries for vkCmdCopyQueryPoolResults are not active");
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    vkt::Buffer buffer(*m_device, 128, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-None-07429");
    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 0, 0, VK_QUERY_RESULT_WAIT_BIT);
    m_errorMonitor->VerifyFound();
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();
}

TEST_F(NegativeQuery, CmdExecuteCommandsActiveQueries) {
    TEST_DESCRIPTION("Check query types when calling vkCmdExecuteCommands");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::inheritedQueries);
    AddRequiredFeature(vkt::Feature::primitivesGeneratedQuery);
    RETURN_IF_SKIP(Init());

    vkt::CommandPool pool(*m_device, m_device->graphics_queue_node_index_, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
    vkt::CommandBuffer secondary(*m_device, pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT, 1);

    VkCommandBufferInheritanceInfo cmd_buf_hinfo = vku::InitStructHelper();
    VkCommandBufferBeginInfo cmd_buf_info = vku::InitStructHelper();
    cmd_buf_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
    cmd_buf_info.pInheritanceInfo = &cmd_buf_hinfo;

    vk::BeginCommandBuffer(secondary, &cmd_buf_info);
    vk::EndCommandBuffer(secondary);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBuffer-07594");
    vk::CmdExecuteCommands(m_command_buffer, 1u, &secondary.handle());
    m_errorMonitor->VerifyFound();
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();
}

TEST_F(NegativeQuery, CmdExecuteBeginActiveQuery) {
    TEST_DESCRIPTION("Begin a query in secondary command buffer that is already active in primary command buffer");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredFeature(vkt::Feature::inheritedQueries);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 2);

    VkCommandBufferInheritanceInfo cbii = vku::InitStructHelper();
    cbii.renderPass = m_renderPass;
    cbii.occlusionQueryEnable = VK_TRUE;

    VkCommandBufferBeginInfo cbbi = vku::InitStructHelper();
    cbbi.pInheritanceInfo = &cbii;

    vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
    secondary.Begin(&cbbi);
    vk::CmdBeginQuery(secondary, query_pool, 1u, 0u);
    vk::CmdEndQuery(secondary, query_pool, 1u);
    secondary.End();

    m_command_buffer.Begin();
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0u, 0u);
    m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-pCommandBuffers-00105");
    vk::CmdExecuteCommands(m_command_buffer, 1u, &secondary.handle());
    m_errorMonitor->VerifyFound();
    vk::CmdEndQuery(m_command_buffer, query_pool, 0u);
    m_command_buffer.End();
}

TEST_F(NegativeQuery, PerformanceQueryReset) {
    TEST_DESCRIPTION("Invalid performance query pool reset");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::performanceCounterQueryPools);
    RETURN_IF_SKIP(Init());

    uint32_t counterCount = 0u;
    vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(m_device->Physical(), m_device->graphics_queue_node_index_,
                                                                      &counterCount, nullptr, nullptr);
    std::vector<VkPerformanceCounterKHR> counters(counterCount, vku::InitStruct<VkPerformanceCounterKHR>());
    std::vector<VkPerformanceCounterDescriptionKHR> counterDescriptions(counterCount,
                                                                        vku::InitStruct<VkPerformanceCounterDescriptionKHR>());
    vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(m_device->Physical(), m_device->graphics_queue_node_index_,
                                                                      &counterCount, counters.data(), counterDescriptions.data());

    uint32_t enabledCounter = counterCount;
    for (uint32_t i = 0; i < counterCount; ++i) {
        if (counters[i].scope == VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR) {
            enabledCounter = i;
            break;
        }
    }
    if (enabledCounter == counterCount) {
        GTEST_SKIP() << "No counter with scope VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR found";
    }

    auto query_pool_performance_ci = vku::InitStruct<VkQueryPoolPerformanceCreateInfoKHR>();
    query_pool_performance_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
    query_pool_performance_ci.counterIndexCount = 1u;
    query_pool_performance_ci.pCounterIndices = &enabledCounter;

    uint32_t num_passes = 0u;
    vk::GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(m_device->Physical(), &query_pool_performance_ci, &num_passes);

    auto query_pool_ci = vku::InitStruct<VkQueryPoolCreateInfo>(&query_pool_performance_ci);
    query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
    query_pool_ci.queryCount = 1u;

    vkt::QueryPool query_pool(*m_device, query_pool_ci);

    auto acquire_profiling_lock_info = vku::InitStruct<VkAcquireProfilingLockInfoKHR>();
    acquire_profiling_lock_info.timeout = vvl::kU64Max;
    vk::AcquireProfilingLockKHR(*m_device, &acquire_profiling_lock_info);

    {
        m_command_buffer.Begin();
        vk::CmdResetQueryPool(m_command_buffer, query_pool, 0u, 1u);
        m_command_buffer.End();

        m_default_queue->Submit(m_command_buffer);
        m_device->Wait();
    }

    vkt::CommandBuffer command_buffer(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
    command_buffer.Begin();
    vk::CmdBeginQuery(command_buffer, query_pool, 0u, 0u);
    vk::CmdEndQuery(command_buffer, query_pool, 0u);
    command_buffer.End();

    for (uint32_t i = 0; i < 2; ++i) {
        m_command_buffer.Begin();
        if (i == 0) {
            vk::CmdBeginQuery(m_command_buffer, query_pool, 0u, 0u);
            vk::CmdEndQuery(m_command_buffer, query_pool, 0u);
        } else {
            vk::CmdExecuteCommands(m_command_buffer, 1u, &command_buffer.handle());
        }
        vk::CmdResetQueryPool(m_command_buffer, query_pool, 0u, 1u);
        m_command_buffer.End();

        auto performance_query_submit_info = vku::InitStruct<VkPerformanceQuerySubmitInfoKHR>();
        performance_query_submit_info.counterPassIndex = 0u;

        auto submit_info = vku::InitStruct<VkSubmitInfo>(&performance_query_submit_info);
        submit_info.commandBufferCount = 1u;
        submit_info.pCommandBuffers = &m_command_buffer.handle();
        m_errorMonitor->SetDesiredError("VUID-vkCmdResetQueryPool-firstQuery-02862");
        vk::QueueSubmit(m_default_queue->handle(), 1u, &submit_info, VK_NULL_HANDLE);
        m_errorMonitor->VerifyFound();
        m_device->Wait();
    }

    vk::ReleaseProfilingLockKHR(*m_device);
}

TEST_F(NegativeQuery, GetQueryPoolResultsWithoutReset) {
    TEST_DESCRIPTION("Get query pool results without ever resetting the query");
    SetTargetApiVersion(VK_API_VERSION_1_2);
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_OCCLUSION, 1);

    vkt::Buffer buffer(*m_device, 128, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

    uint32_t data = 0u;
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-None-09401");
    vk::GetQueryPoolResults(*m_device, query_pool, 0u, 1u, sizeof(uint32_t), &data, sizeof(uint32_t), 0u);
    m_errorMonitor->VerifyFound();

    m_command_buffer.Begin();
    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0u, 1u, buffer, 0u, sizeof(uint32_t), 0u);
    m_command_buffer.End();

    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-None-09402");
    m_default_queue->Submit(m_command_buffer);
    m_errorMonitor->VerifyFound();
    m_default_queue->Wait();
}

TEST_F(NegativeQuery, InvalidMeshQueryAtDraw) {
    TEST_DESCRIPTION("Draw with vertex shader with mesh query active");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_MESH_SHADER_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::meshShader);
    AddRequiredFeature(vkt::Feature::meshShaderQueries);

    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    CreatePipelineHelper pipe(*this);
    pipe.CreateGraphicsPipeline();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT, 1);

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderPass(m_renderPassBeginInfo);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0u, 0u);
    vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
    m_errorMonitor->SetDesiredError("VUID-vkCmdDraw-stage-07073");
    vk::CmdDraw(m_command_buffer, 3u, 1u, 0u, 0u);
    m_errorMonitor->VerifyFound();
    vk::CmdEndQuery(m_command_buffer, query_pool, 0u);
    m_command_buffer.EndRenderPass();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, PipelineStatisticsQueryWithSecondaryCmdBuffer) {
    TEST_DESCRIPTION("Use a pipeline statistics query in secondary command buffer");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredFeature(vkt::Feature::inheritedQueries);
    AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkQueryPoolCreateInfo qpci = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 1);
    qpci.pipelineStatistics =
        VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT | VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT;
    vkt::QueryPool query_pool(*m_device, qpci);

    VkCommandBufferInheritanceInfo cbii = vku::InitStructHelper();
    cbii.renderPass = m_renderPass;
    cbii.framebuffer = Framebuffer();
    cbii.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT;

    VkCommandBufferBeginInfo cbbi = vku::InitStructHelper();
    cbbi.pInheritanceInfo = &cbii;

    vkt::CommandBuffer secondary(*m_device, m_command_pool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
    secondary.Begin(&cbbi);
    secondary.End();

    m_command_buffer.Begin();
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0u, 0u);
    m_errorMonitor->SetDesiredError("VUID-vkCmdExecuteCommands-commandBuffer-00104");
    vk::CmdExecuteCommands(m_command_buffer, 1u, &secondary.handle());
    m_errorMonitor->VerifyFound();
    vk::CmdEndQuery(m_command_buffer, query_pool, 0u);
    m_command_buffer.End();
}

TEST_F(NegativeQuery, PipelineStatisticsZero) {
    TEST_DESCRIPTION("Use a pipeline statistics query in secondary command buffer");
    AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery);
    RETURN_IF_SKIP(Init());

    VkQueryPoolCreateInfo qpci = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 1);
    qpci.pipelineStatistics = 0;
    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-09534");
    vkt::QueryPool query_pool(*m_device, qpci);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, WriteTimestampInsideRenderPass) {
    TEST_DESCRIPTION("Call vkCmdWriteTimestamp() inside an active render pass instance");

    AddRequiredExtensions(VK_KHR_MULTIVIEW_EXTENSION_NAME);
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredFeature(vkt::Feature::multiview);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    if (!(m_device->Physical().limits_.timestampComputeAndGraphics & VK_QUEUE_GRAPHICS_BIT)) {
        GTEST_SKIP() << "Timestamps not supported in the graphics queue";
    }

    VkQueryPoolCreateInfo query_pool_create_info = vku::InitStructHelper();
    query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
    query_pool_create_info.queryCount = 2;
    vkt::QueryPool query_pool(*m_device, query_pool_create_info);

    VkSubpassDescription subpass = {};
    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;

    uint32_t viewMasks[] = {0x3u};
    uint32_t correlationMasks[] = {0x1u};
    VkRenderPassMultiviewCreateInfo rpmv_ci = vku::InitStructHelper();
    rpmv_ci.subpassCount = 1;
    rpmv_ci.pViewMasks = viewMasks;
    rpmv_ci.correlationMaskCount = 1;
    rpmv_ci.pCorrelationMasks = correlationMasks;

    VkRenderPassCreateInfo render_pass_ci = vku::InitStructHelper(&rpmv_ci);
    render_pass_ci.subpassCount = 1u;
    render_pass_ci.pSubpasses = &subpass;

    vkt::RenderPass render_pass(*m_device, render_pass_ci);

    VkFramebufferCreateInfo framebuffer_ci = vku::InitStructHelper();
    framebuffer_ci.renderPass = render_pass;
    framebuffer_ci.width = 32u;
    framebuffer_ci.height = 32u;
    framebuffer_ci.layers = 1u;

    vkt::Framebuffer framebuffer(*m_device, framebuffer_ci);

    VkRenderPassBeginInfo render_pass_bi = vku::InitStructHelper();
    render_pass_bi.renderPass = render_pass;
    render_pass_bi.framebuffer = framebuffer;
    render_pass_bi.renderArea = {{0, 0}, {32u, 32u}};
    render_pass_bi.clearValueCount = 1u;
    render_pass_bi.pClearValues = m_renderPassClearValues.data();

    m_command_buffer.Begin();
    m_command_buffer.BeginRenderPass(render_pass_bi);

    m_errorMonitor->SetDesiredError("VUID-vkCmdWriteTimestamp-query-00831");
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, query_pool, 1);
    m_errorMonitor->VerifyFound();

    m_command_buffer.EndRenderPass();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, Stride) {
    TEST_DESCRIPTION("Validate Stride parameter.");
    RETURN_IF_SKIP(Init());

    uint32_t queue_count;
    vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &queue_count, nullptr);
    std::vector<VkQueueFamilyProperties> queue_props(queue_count);
    vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &queue_count, queue_props.data());
    if (queue_props[m_device->graphics_queue_node_index_].timestampValidBits == 0) {
        GTEST_SKIP() << " Device graphic queue has timestampValidBits of 0, skipping.";
    }

    InitRenderTarget();

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0, 1);
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0);
    m_command_buffer.End();

    m_default_queue->SubmitAndWait(m_command_buffer);

    uint8_t data_space[16];
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-flags-02828");
    vk::GetQueryPoolResults(*m_device, query_pool, 0, 1, 4, &data_space[1], 1, VK_QUERY_RESULT_WAIT_BIT);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-flags-00815");
    vk::GetQueryPoolResults(*m_device, query_pool, 0, 1, 8, &data_space[1], 1, (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT));
    m_errorMonitor->VerifyFound();

    char data_space4[4] = "";
    vk::GetQueryPoolResults(*m_device, query_pool, 0, 1, sizeof(data_space4), &data_space4, 4, VK_QUERY_RESULT_WAIT_BIT);

    // alignas() for 32-bit machines
    alignas(8) char data_space8[8] = "";
    vk::GetQueryPoolResults(*m_device, query_pool, 0, 1, sizeof(data_space8), &data_space8, 8,
                            (VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT));

    vkt::Buffer buffer(*m_device, 128, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

    m_command_buffer.Reset();
    m_command_buffer.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-flags-00822");
    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 1, 1, 0);
    m_errorMonitor->VerifyFound();

    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-flags-00823");
    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 1, 1, VK_QUERY_RESULT_64_BIT);
    m_errorMonitor->VerifyFound();

    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 4, 4, 0);

    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0, 1, buffer, 8, 8, VK_QUERY_RESULT_64_BIT);
}

TEST_F(NegativeQuery, PerfQueryQueueFamilyIndex) {
    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::performanceCounterQueryPools);
    RETURN_IF_SKIP(Init());

    vkt::Queue* queue0 = m_default_queue;
    auto queue1_family = m_device->ComputeOnlyQueueFamily();
    if (!queue1_family.has_value()) {
        GTEST_SKIP() << "Can't find two different queue families";
    }
    assert(queue0->family_index != queue1_family.value());

    uint32_t counterCount = 0u;
    vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(m_device->Physical(), 0, &counterCount, nullptr, nullptr);
    std::vector<VkPerformanceCounterKHR> counters(counterCount, vku::InitStruct<VkPerformanceCounterKHR>());
    std::vector<VkPerformanceCounterDescriptionKHR> counterDescriptions(counterCount,
                                                                        vku::InitStruct<VkPerformanceCounterDescriptionKHR>());
    vk::EnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR(m_device->Physical(), 0, &counterCount, counters.data(),
                                                                      counterDescriptions.data());

    std::vector<uint32_t> enabledCounters(128);
    const uint32_t enabledCounterCount = std::min(counterCount, static_cast<uint32_t>(enabledCounters.size()));
    for (uint32_t i = 0; i < enabledCounterCount; ++i) {
        enabledCounters[i] = i;
    }

    auto query_pool_performance_ci = vku::InitStruct<VkQueryPoolPerformanceCreateInfoKHR>();
    query_pool_performance_ci.queueFamilyIndex = queue0->family_index;
    query_pool_performance_ci.counterIndexCount = enabledCounterCount;
    query_pool_performance_ci.pCounterIndices = enabledCounters.data();

    uint32_t num_passes = 0;
    vk::GetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR(m_device->Physical(), &query_pool_performance_ci, &num_passes);

    auto query_pool_ci = vku::InitStruct<VkQueryPoolCreateInfo>(&query_pool_performance_ci);
    query_pool_ci.queryType = VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR;
    query_pool_ci.queryCount = 1;
    vkt::QueryPool query_pool(*m_device, query_pool_ci);

    VkCommandPoolCreateInfo pool_create_info = vku::InitStructHelper();
    pool_create_info.queueFamilyIndex = queue1_family.value();
    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
    vkt::CommandPool command_pool(*m_device, pool_create_info);

    vkt::CommandBuffer cb(*m_device, command_pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

    auto acquire_profiling_lock_info = vku::InitStruct<VkAcquireProfilingLockInfoKHR>();
    acquire_profiling_lock_info.timeout = vvl::kU64Max;
    vk::AcquireProfilingLockKHR(*m_device, &acquire_profiling_lock_info);

    cb.Begin();
    vk::CmdResetQueryPool(cb, query_pool, 0u, 1u);
    cb.End();

    cb.Begin();
    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-queryPool-07289");
    vk::CmdBeginQuery(cb, query_pool, 0, 0);
    m_errorMonitor->VerifyFound();
    cb.End();
    vk::ReleaseProfilingLockKHR(*m_device);
}

TEST_F(NegativeQuery, NoInitReset) {
    AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkQueryPoolCreateInfo qpci = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 1);
    qpci.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT;
    vkt::QueryPool query_pool(*m_device, qpci);

    m_command_buffer.Begin();
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0, 0);
    vk::CmdEndQuery(m_command_buffer, query_pool, 0);
    m_command_buffer.End();

    m_errorMonitor->SetDesiredError("VUID-vkCmdBeginQuery-None-00807");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, CopyUnavailableQueries) {
    TEST_DESCRIPTION("Copy query results when they are not available");
    RETURN_IF_SKIP(Init());

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1u);
    vkt::Buffer buffer(*m_device, 16u, VK_BUFFER_USAGE_TRANSFER_DST_BIT);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0u, 1u);
    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0u, 1u, buffer, 0u, 0u, 0u);
    m_command_buffer.End();

    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-None-08752");
    m_default_queue->SubmitAndWait(m_command_buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeQuery, QueryResultCopyBufferInvalidFlags) {
    TEST_DESCRIPTION("Copy query results to a buffer without transfer dst flag");
    RETURN_IF_SKIP(Init());

    if (!m_device->Physical().limits_.timestampComputeAndGraphics) {
        GTEST_SKIP() << "Timestamps not supported";
    }

    vkt::QueryPool query_pool(*m_device, VK_QUERY_TYPE_TIMESTAMP, 1u);
    vkt::Buffer buffer(*m_device, 16u, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0u, 1u);
    vk::CmdWriteTimestamp(m_command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, query_pool, 0u);
    m_errorMonitor->SetDesiredError("VUID-vkCmdCopyQueryPoolResults-dstBuffer-00825");
    vk::CmdCopyQueryPoolResults(m_command_buffer, query_pool, 0u, 1u, buffer, 0u, 0u, 0u);
    m_errorMonitor->VerifyFound();
    m_command_buffer.End();
}

TEST_F(NegativeQuery, QueryPoolResultsStride) {
    AddRequiredFeature(vkt::Feature::pipelineStatisticsQuery);
    RETURN_IF_SKIP(Init());
    InitRenderTarget();

    VkQueryPoolCreateInfo qpci = vkt::QueryPool::CreateInfo(VK_QUERY_TYPE_PIPELINE_STATISTICS, 2u);
    qpci.pipelineStatistics = VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT;
    vkt::QueryPool query_pool(*m_device, qpci);

    m_command_buffer.Begin();
    vk::CmdResetQueryPool(m_command_buffer, query_pool, 0u, 2u);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 0u, 0u);
    vk::CmdEndQuery(m_command_buffer, query_pool, 0u);
    vk::CmdBeginQuery(m_command_buffer, query_pool, 1u, 0u);
    vk::CmdEndQuery(m_command_buffer, query_pool, 1u);
    m_command_buffer.End();

    m_default_queue->SubmitAndWait(m_command_buffer);

    uint32_t data_space[4];
    m_errorMonitor->SetDesiredError("VUID-vkGetQueryPoolResults-stride-08993");
    vk::GetQueryPoolResults(*m_device, query_pool, 0u, 2u, sizeof(uint32_t) * 4, data_space, sizeof(uint32_t),
                            VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
    m_errorMonitor->VerifyFound();
}
