kohi
kohi copied to clipboard
[BUG] Validation Error: VkDeviceCreateInfo-queueFamilyIndex-02802
Bug:
In certain graphics cards, the current queue selection process will pick the same queueFamilyIndex more than once if there are not enough individual queueFamilyIndex's for each (graphics, transfer and present) queue. This triggers a validation error within vulkan that goes as follows:
Output:
Validation Error: [ VUID-VkDeviceCreateInfo-queueFamilyIndex-02802 ] Object 0: handle = 0x1088d50, type = VK_OBJECT_TYPE_PHYSICAL_DEVICE; | MessageID = 0x29498778 | CreateDevice(): pCreateInfo->pQueueCreateInfos[2].queueFamilyIndex (=1) is not unique and was also used in pCreateInfo->pQueueCreateInfos[1]. The Vulkan spec states: The queueFamilyIndex member of each element of pQueueCreateInfos must be unique within pQueueCreateInfos, except that two members can share the same queueFamilyIndex if one describes protected-capable queues and one describes queues that are not protected-capable (https://vulkan.lunarg.com/doc/view/1.3.224.0/linux/1.3-extensions/vkspec.html#VUID-VkDeviceCreateInfo-queueFamilyIndex-02802)
neofetch --stdout
shadoww@xddz
------------
OS: Debian GNU/Linux 11 (bullseye) x86_64
Host: Aspire A315-21G V1.12
Kernel: 5.10.0-18-amd64
Uptime: 1 day, 13 hours, 37 mins
Packages: 2926 (dpkg)
Shell: zsh 5.8
Resolution: 1366x768
WM: bspwm
Theme: Adwaita-One-Dark [GTK2/3]
Icons: hicolor [GTK2/3]
Terminal: alacritty
Terminal Font: Iosevka
CPU: AMD A9-9420 RADEON R5 2C+3G (2) @ 3.000GHz
GPU: AMD ATI Radeon R5 M230 / R7 M260DX / Radeon 520 Mobile
GPU: AMD ATI Radeon R2/R3/R4/R5 Graphics
Memory: 5397MiB / 7410MiB
VkQueueFamilyProperties (vulkaninfo
):
VkQueueFamilyProperties:
========================
queueProperties[0]:
-------------------
minImageTransferGranularity = (1,1,1)
queueCount = 1
queueFlags = QUEUE_GRAPHICS | QUEUE_COMPUTE | QUEUE_TRANSFER | QUEUE_SPARSE_BINDING
timestampValidBits = 64
present support = true
queueProperties[1]:
-------------------
minImageTransferGranularity = (1,1,1)
queueCount = 4
queueFlags = QUEUE_COMPUTE | QUEUE_TRANSFER | QUEUE_SPARSE_BINDING
timestampValidBits = 64
present support = true
./engine/src/renderer/vulkan/vulkan_device.c
if (!transfer_shares_graphics_queue) {
indices[index++] = context->device.transfer_queue_index;
}
VkDeviceQueueCreateInfo queue_create_infos[index_count];
for (u32 i = 0; i < index_count; ++i) {
queue_create_infos[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queue_create_infos[i].queueFamilyIndex = indices[i];
queue_create_infos[i].queueCount = 1;
// TODO: Enable this for a future enhancement.
// if (indices[i] == context->device.graphics_queue_index) {
// queue_create_infos[i].queueCount = 2;
// }
queue_create_infos[i].flags = 0;
queue_create_infos[i].pNext = 0;
f32 queue_priority = 1.0f;
queue_create_infos[i].pQueuePriorities = &queue_priority;
}
// Request device features.
// TODO: should be config driven
VkPhysicalDeviceFeatures device_features = {};
As you can see above, I've only got 2 "queue families", yet, the current code requires at least one queue family for each mode (graphics, present, transfer).
i think this answer might be too late but this will probably help somebody else im pretty sure the issue has something to do with queueCreateInfoCount because when using index_count it crashes but when i just set it to 1 it works
const b8 present_shares_graphics_queue = context->device.graphics_queue_index == context->device.present_queue_index;
const b8 transfer_shares_graphics_queue = context->device.graphics_queue_index == context->device.transfer_queue_index;
uint32_t index_count = 1;
if (!present_shares_graphics_queue) index_count++;
if (!transfer_shares_graphics_queue) index_count++;
int32_t indices[index_count];
uint8_t index = 0;
indices[index++] = context->device.graphics_queue_index;
if (!present_shares_graphics_queue)
indices[index++] = context->device.present_queue_index;
if (!transfer_shares_graphics_queue)
indices[index++] = context->device.transfer_queue_index;
VkDeviceQueueCreateInfo pQueueInfo[index_count];
for (uint32_t i = 0; i < index_count; i++) {
pQueueInfo[i].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
pQueueInfo[i].queueFamilyIndex = indices[i];
pQueueInfo[i].queueCount = 1;
if (indices[i] == context->device.graphics_queue_index)
pQueueInfo[i].queueCount = 1;
pQueueInfo[i].flags = 0;
pQueueInfo[i].pNext = NULL;
float queue_priority = 1.0f;
pQueueInfo[i].pQueuePriorities = &queue_priority;
}
VkPhysicalDeviceFeatures deviceFeatures;
s_zerofill(&deviceFeatures, sizeof(deviceFeatures));
deviceFeatures.samplerAnisotropy = VK_TRUE;
VkDeviceCreateInfo deviceInfo;
s_zerofill(&deviceInfo, sizeof(deviceInfo));
deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
deviceInfo.queueCreateInfoCount = 1;
deviceInfo.pQueueCreateInfos = pQueueInfo;
deviceInfo.pEnabledFeatures = &deviceFeatures;
deviceInfo.enabledExtensionCount = 1;
const char *extension_names = VK_KHR_SWAPCHAIN_EXTENSION_NAME;
deviceInfo.ppEnabledExtensionNames = &extension_names;
deviceInfo.enabledLayerCount = 0;
deviceInfo.ppEnabledLayerNames = NULL;