Describe the bug
Vulkan initizlization in bgfx::init() fails. Tldr: The code chooses the GPU which is not able to render to a surface.
I wanted to circumvent the issue by specifying the GPU to be used, however, that is not directly possible.
The GPU ID and vendor ID are the same for both NVIDIA RTX 2080 GPUs.
Here is the log output of the found devices after querying the Vulkan API (with my own code):
[2.67033s][Info]: Rendering::Device::findDevices(): Found 3 devices:
Device(NVIDIA GeForce RTX 2080, ID: 7810, vendorID: 4318, physicalType: discrete GPU, canRender: 1)
Device(llvmpipe (LLVM 20.1.2, 256 bits), ID: 0, vendorID: 65541, physicalType: CPU, canRender: 1)
Device(NVIDIA GeForce RTX 2080, ID: 7810, vendorID: 4318, physicalType: discrete GPU, canRender: 0)
Unfortunately, vendorID is the same for both GPUs (from props.vendorID with VkPhysicalDeviceProperties props). Though, the devices are actually different from each other, the VkPhysicalDevice * values are:
0x555555c3ab80 and 0x555555c3abb0.
Since these pointers are from my own temporary Vulkan instance for listing available GPUs,
I cannot reuse them in the bgfx::init() function directly.
The canRender value is from:
const auto supportsRendering = vkGetPhysicalDeviceXlibPresentationSupportKHR(
physicalDevice, qfIdx, display, visualID);
The output from bgfx reflects the issue from above:
../../../src/renderer_vk.cpp (1501): BGFX Physical device 0:
../../../src/renderer_vk.cpp (1502): BGFX Name: NVIDIA GeForce RTX 2080
../../../src/renderer_vk.cpp (1503): BGFX API version: 1.4.325
../../../src/renderer_vk.cpp (1508): BGFX API variant: 0
../../../src/renderer_vk.cpp (1509): BGFX Driver version: 938c0040
../../../src/renderer_vk.cpp (1510): BGFX VendorId: 10de
../../../src/renderer_vk.cpp (1511): BGFX DeviceId: 1e82
../../../src/renderer_vk.cpp (1512): BGFX Type: 2
...
../../../src/renderer_vk.cpp (1501): BGFX Physical device 1:
../../../src/renderer_vk.cpp (1502): BGFX Name: NVIDIA GeForce RTX 2080
../../../src/renderer_vk.cpp (1503): BGFX API version: 1.4.325
../../../src/renderer_vk.cpp (1508): BGFX API variant: 0
../../../src/renderer_vk.cpp (1509): BGFX Driver version: 938c0040
../../../src/renderer_vk.cpp (1510): BGFX VendorId: 10de
../../../src/renderer_vk.cpp (1511): BGFX DeviceId: 1e82
../../../src/renderer_vk.cpp (1512): BGFX Type: 2
...
../../../src/renderer_vk.cpp (1606): BGFX Using physical device 1: NVIDIA GeForce RTX 2080
The code chooses the last of the two RTX2080 GPUs as they look identical given the queries up to this point:
The chosen GPU then fails the can present test here:
|
result = vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, queueFamily, m_surface, &surfaceSupported); |
Is it possible to check the GPU connection to a screen before chosing the final GPU?
For example, some bgfx function that is a platform independent version of this?
const auto supportsRendering = vkGetPhysicalDeviceXlibPresentationSupportKHR(
physicalDevice, qfIdx, display, visualID);
To Reproduce
That's probably a bit annoying as you need two GPUs with the same VendorId and DeviceId.
Then both of the GPUs need to be connected in a way that the second one which is listed by Vulkan cannot present to a surface/render, but only the first GPU. Both of the GPUs are connected to a one of two screens, but somehow only one supports rendering to a surface from the OS/Vulkan point of view.
Expected behavior
bgfx::init() with renderer type set to Vulkan should fail with:
../../../src/renderer_vk.cpp (7523): BGFX Attempting Xlib surface creation.
../../../src/renderer_vk.cpp (7634): BGFX Create surface error: Presentation to the given surface not
supported.
Then OpenGL is chosen instead.
If you change the number of listed devices to 1 using a debugger in order to make the code only consider the first GPU,
then the surface creation works and Vulkan is successfully initialized as renderer.
Additional context
OS: Ubuntu 24.04
Window creation using X11/Xlib
Describe the bug
Vulkan initizlization in bgfx::init() fails. Tldr: The code chooses the GPU which is not able to render to a surface.
I wanted to circumvent the issue by specifying the GPU to be used, however, that is not directly possible.
The GPU ID and vendor ID are the same for both NVIDIA RTX 2080 GPUs.
Here is the log output of the found devices after querying the Vulkan API (with my own code):
Unfortunately, vendorID is the same for both GPUs (from props.vendorID with VkPhysicalDeviceProperties props). Though, the devices are actually different from each other, the VkPhysicalDevice * values are:
0x555555c3ab80 and 0x555555c3abb0.
Since these pointers are from my own temporary Vulkan instance for listing available GPUs,
I cannot reuse them in the bgfx::init() function directly.
The canRender value is from:
const auto supportsRendering = vkGetPhysicalDeviceXlibPresentationSupportKHR(
physicalDevice, qfIdx, display, visualID);
The output from bgfx reflects the issue from above:
The code chooses the last of the two RTX2080 GPUs as they look identical given the queries up to this point:
bgfx/src/renderer_vk.cpp
Line 1545 in a73c12d
The chosen GPU then fails the can present test here:
bgfx/src/renderer_vk.cpp
Line 7641 in a73c12d
Is it possible to check the GPU connection to a screen before chosing the final GPU?
For example, some bgfx function that is a platform independent version of this?
const auto supportsRendering = vkGetPhysicalDeviceXlibPresentationSupportKHR(
physicalDevice, qfIdx, display, visualID);
To Reproduce
That's probably a bit annoying as you need two GPUs with the same VendorId and DeviceId.
Then both of the GPUs need to be connected in a way that the second one which is listed by Vulkan cannot present to a surface/render, but only the first GPU. Both of the GPUs are connected to a one of two screens, but somehow only one supports rendering to a surface from the OS/Vulkan point of view.
Expected behavior
bgfx::init() with renderer type set to Vulkan should fail with:
Then OpenGL is chosen instead.
If you change the number of listed devices to 1 using a debugger in order to make the code only consider the first GPU,
then the surface creation works and Vulkan is successfully initialized as renderer.
Additional context
OS: Ubuntu 24.04
Window creation using X11/Xlib