blob: 483193230fd8d373a6fb7007ebbe485a1c09f412 [file]
/*
* Copyright (c) 2023-2026 Valve Corporation
* Copyright (c) 2023-2026 LunarG, Inc.
*
* 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 "../framework/layer_validation_tests.h"
#include "../framework/shader_helper.h"
class PositiveDeviceQueue : public VkLayerTest {};
TEST_F(PositiveDeviceQueue, NoQueues) {
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_MAINTENANCE_9_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::maintenance9);
RETURN_IF_SKIP(InitFramework());
VkDeviceCreateInfo device_ci = vku::InitStructHelper();
device_ci.pNext = requested_features_.GetEnabledFeatures2();
device_ci.enabledExtensionCount = static_cast<uint32_t>(m_device_extension_names.size());
device_ci.ppEnabledExtensionNames = m_device_extension_names.data();
vkt::Device device(gpu_, device_ci);
VkShaderObj cs(device, kMinimalShaderGlsl, VK_SHADER_STAGE_COMPUTE_BIT);
std::vector<VkDescriptorSetLayoutBinding> bindings(0);
const vkt::DescriptorSetLayout pipeline_dsl(device, bindings);
const vkt::PipelineLayout pipeline_layout(device, {&pipeline_dsl});
VkComputePipelineCreateInfo compute_create_info = vku::InitStructHelper();
compute_create_info.stage = cs.GetStageCreateInfo();
compute_create_info.layout = pipeline_layout;
VkPipeline pipeline;
vk::CreateComputePipelines(device, VK_NULL_HANDLE, 1, &compute_create_info, nullptr, &pipeline);
vk::DestroyPipeline(device, pipeline, nullptr);
}
TEST_F(PositiveDeviceQueue, QueueFamilyIndexDifferentCreateFlags) {
SetTargetApiVersion(VK_API_VERSION_1_1);
AddRequiredExtensions(VK_KHR_INTERNALLY_SYNCHRONIZED_QUEUES_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::internallySynchronizedQueues);
RETURN_IF_SKIP(InitFramework());
bool found_queue = false;
VkQueueFamilyProperties queue_properties;
uint32_t queue_family_index = 0u;
uint32_t queue_family_count = 0u;
vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &queue_family_count, nullptr);
std::vector<VkQueueFamilyProperties> queue_families(queue_family_count);
vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &queue_family_count, queue_families.data());
for (size_t i = 0; i < queue_families.size(); i++) {
if (queue_families[i].queueCount > 1) {
found_queue = true;
queue_family_index = i;
queue_properties = queue_families[i];
break;
}
}
if (found_queue == false) {
GTEST_SKIP() << "test requires queue family with 2 queues, not available";
}
float queue_priority = 1.0f;
VkDeviceQueueCreateInfo device_queue_ci[2];
device_queue_ci[0] = vku::InitStructHelper();
device_queue_ci[0].flags = 0u;
device_queue_ci[0].queueFamilyIndex = queue_family_index;
device_queue_ci[0].queueCount = 1u;
device_queue_ci[0].pQueuePriorities = &queue_priority;
device_queue_ci[1] = vku::InitStructHelper();
device_queue_ci[1].flags = VK_DEVICE_QUEUE_CREATE_INTERNALLY_SYNCHRONIZED_BIT_KHR;
device_queue_ci[1].queueFamilyIndex = queue_family_index;
device_queue_ci[1].queueCount = 1u;
device_queue_ci[1].pQueuePriorities = &queue_priority;
VkDevice test_device = VK_NULL_HANDLE;
VkDeviceCreateInfo device_ci = vku::InitStructHelper();
device_ci.pNext = requested_features_.GetEnabledFeatures2();
device_ci.queueCreateInfoCount = 2u;
device_ci.pQueueCreateInfos = device_queue_ci;
device_ci.enabledExtensionCount = static_cast<uint32_t>(m_device_extension_names.size());
device_ci.ppEnabledExtensionNames = m_device_extension_names.data();
vk::CreateDevice(Gpu(), &device_ci, nullptr, &test_device);
vk::DestroyDevice(test_device, nullptr);
}
TEST_F(PositiveDeviceQueue, MultipleQueuePerfHint) {
TEST_DESCRIPTION("Test vkQueueSetPerfHintQCOM on all supported queues.");
SetTargetApiVersion(VK_API_VERSION_1_3);
AddRequiredExtensions(VK_QCOM_QUEUE_PERF_HINT_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::queuePerfHint);
RETURN_IF_SKIP(InitFramework());
VkPhysicalDeviceQueuePerfHintPropertiesQCOM perf_hint_props = vku::InitStructHelper();
GetPhysicalDeviceProperties2(perf_hint_props);
const VkQueueFlags supported_queues = perf_hint_props.supportedQueues;
uint32_t queue_family_count = 0;
vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &queue_family_count, nullptr);
std::vector<VkQueueFamilyProperties> queue_family_props(queue_family_count);
vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &queue_family_count, queue_family_props.data());
std::vector<uint32_t> supported_queue_ids{};
for (uint32_t index = 0; index < queue_family_count; ++index) {
if ((queue_family_props[index].queueFlags & supported_queues) != 0) {
supported_queue_ids.push_back(index);
}
}
if (supported_queue_ids.empty()) {
GTEST_SKIP() << "Failed to find the queue family that supports queue perf-hint property, skipping test.";
}
RETURN_IF_SKIP(InitState());
constexpr std::array<VkPerfHintTypeQCOM, 3> hint_types{
VK_PERF_HINT_TYPE_FREQUENCY_SCALED_QCOM,
VK_PERF_HINT_TYPE_DEFAULT_QCOM,
VK_PERF_HINT_TYPE_FREQUENCY_MIN_QCOM,
};
uint32_t index = 0;
for (const uint32_t family_id : supported_queue_ids) {
VkQueue queue = VK_NULL_HANDLE;
vk::GetDeviceQueue(device(), family_id, 0, &queue);
VkPerfHintInfoQCOM perf_hint_info = vku::InitStructHelper();
perf_hint_info.type = hint_types[index];
perf_hint_info.scale = 0;
if (hint_types[index] == VK_PERF_HINT_TYPE_FREQUENCY_SCALED_QCOM) {
perf_hint_info.scale = 65;
}
vk::QueueSetPerfHintQCOM(queue, &perf_hint_info);
++index;
index = index % hint_types.size();
}
}