Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Surface related vk calls fail with an SDL-created Vulkan Surface (Vulkan 1.3) #451

Open
TheMagehawk opened this issue Jan 13, 2024 · 1 comment

Comments

@TheMagehawk
Copy link

TheMagehawk commented Jan 13, 2024

API: Vulkan 1.3
Windowing Library: SDL2
Build System Generator: CMake

During the Vulkan Setup Process, I encounter an issue with Surface related vk functions.

This particular function causes a Segmentation Fault:

VkBool32 supportsPresentation = 0;
vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, familyIndex, surface, &supportsPresentation);

I generate the glad library with CMake:

glad_add_library(glad STATIC EXCLUDE_FROM_ALL REPRODUCIBLE API vulkan=1.3)
target_link_libraries(${PROJECT_NAME} PUBLIC glad)

It works, if I use the system-wide Vulkan package instead without applying the glad load functions, so it's probably related to missing symbols:

find_package(Vulkan)
target_link_libraries(${PROJECT_NAME} PUBLIC Vulkan::Vulkan)

Here is a summarized overview of the Vulkan Setup Process:

window = SDL_CreateWindow(name, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_VULKAN);

...

gladLoadVulkanUserPtr(nullptr, (GLADuserptrloadfunc) SDL_Vulkan_GetVkGetInstanceProcAddr(), nullptr);

...

uint32_t sdlExtensionCount = 0;
SDL_bool result = SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, nullptr);
CC_ENGINE_ASSERT_ARGS(result == SDL_TRUE, "Failed to retrieve SDL required Vulkan Extensions! SDL_Error: {}", SDL_GetError());
std::vector<const char*> requiredExtensions(sdlExtensionCount);
result = SDL_Vulkan_GetInstanceExtensions(window, &sdlExtensionCount, requiredExtensions.data());

...

VkApplicationInfo appInfo{};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pNext = nullptr;
appInfo.pApplicationName = name;
appInfo.applicationVersion = VK_MAKE_VERSION(0, 1, 0);
appInfo.pEngineName = "";
appInfo.engineVersion = VK_MAKE_VERSION(0, 1, 0);
appInfo.apiVersion = VK_API_VERSION_1_3;

VkInstanceCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.pApplicationInfo = &appInfo;
createInfo.enabledLayerCount = static_cast<uint32_t>(enabledLayers.size());  // This mainly contains VK_LAYER_KHRONOS_validation
createInfo.ppEnabledLayerNames = enabledLayers.data();
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionNames.size());  // This contains the SDL required extensions
createInfo.ppEnabledExtensionNames = extensionNames.data();

VkResult createResult = vkCreateInstance(&createInfo, nullptr, &instance);
gladLoadVulkanUserPtr(nullptr, (GLADuserptrloadfunc) SDL_Vulkan_GetVkGetInstanceProcAddr(), instance);

...

// Find the first physical device GPU
...
physicalDevice = physicalDevices.at(0);

gladLoadVulkanUserPtr(physicalDevice, (GLADuserptrloadfunc) SDL_Vulkan_GetVkGetInstanceProcAddr(), instance);

...

// Find first Graphics Queue Family and create a VkDevice and receive the first Graphics Queue
...

SDL_Vulkan_CreateSurface(window, instance, &surface);

I also notice that, if I create a VkInstance with the Application API Version set to Vulkan 1.2 or lower (even if I generate for Vulkan 1.3 on glad), the problem suddenly disappears.

Following code change fixes the issue, but restricts usage to Vulkan <=1.2:

appInfo.apiVersion = VK_API_VERSION_1_2;

I couldn't figure out what specifically made it work on Vulkan 1.2, but I applied no other changes.

EDIT:
On Android (Android 14) it fails on exactly the same function call on any selected VK_API_VERSION_1_*

@vs49688
Copy link

vs49688 commented Oct 12, 2024

Bit of a necropost, but I hit this same issue using Vulkan 1.3/SDL on RADV.

Special-casing vkEnumerateInstanceVersion and vkEnumerateInstanceExtensionProperties fixes it, similar to #329 (comment)

e.g.

    if(strcmp("vkEnumerateInstanceVersion", name) == 0 || strcmp("vkEnumerateInstanceExtensionProperties", name) == 0)
        return self->getInstanceProcAddr(NULL, name);

    return self->getInstanceProcAddr(self->vulkan, name);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants