blob: 5dea9975730a59f20b5fd618ff7e66c33a980628 [file] [log] [blame]
/*
* Copyright (c) 2015-2025 The Khronos Group Inc.
* Copyright (c) 2015-2025 Valve Corporation
* Copyright (c) 2015-2025 LunarG, Inc.
* Copyright (c) 2015-2025 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();
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());
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();
}