| /* |
| * 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); |
| } |