Skip to content

Introduce proper vulkan initialization#570

Merged
MarkCallow merged 2 commits intoKhronosGroup:masterfrom
rHermes:proper-vulkan-init
May 23, 2022
Merged

Introduce proper vulkan initialization#570
MarkCallow merged 2 commits intoKhronosGroup:masterfrom
rHermes:proper-vulkan-init

Conversation

@rHermes
Copy link
Copy Markdown
Contributor

@rHermes rHermes commented May 7, 2022

This is a first attempt to address Issue #568, and introduce a more flexible approach to initializing KTX with the vulkan functions it need.

The bulk of the PR is to add a struct named ktxVulkanFunctions, which contains all functions that KTX might need during it's vulkan operations. An expanded version of txVulkanDeviceInfo_Construct is created, which now takes in both an instance and a pointer to a ktxVulkanFunctions struct.

The minimum a user should pass in to the new function is an instance and a ktxVulkanFunctions with the vkGetInstanceProcAddr field filled out. The function will then take care of loading the rest of the functions and the user is good to go. A user can optionally provide more of the functions explicitly, if they wish. This enables either mocking, or custom implementations.

To enable backward compatibility with previous versions, the old loader code is still in place, and will be triggered if the user does not supply an explicit vkGetInstanceProcAddr or instance.

The code is still quite rough, and will need to be improved before being merged in. Documentation, examples and tests will need to be provided as well. I'm creating this PR now, as to get some early feedback, before going over and polishing it up.

I've tested this on Linux, with my own application which does not directly link to Vulkan, and it works.

@MarkCallow
Copy link
Copy Markdown
Collaborator

MarkCallow commented May 7, 2022

Have you considered mocking the ICD (there's a generator to help) or creating a layer to intercept the Vulkan API calls using the Vulkan Layer Factory?

The advantage of these approaches are that you only need to mock exactly what is of interest and there is no need to modify libraries that you need.

@rHermes
Copy link
Copy Markdown
Contributor Author

rHermes commented May 8, 2022

I have not looked at that, but I'm not sure how it would solve the problem here?

In the case where vulkan is dynamically loaded, and not directly linked, your code would still error out, as in issue #568.

Furthermore, it seems a very poor way of handling the issue of improper initialization of vulkan functions here. The correct way to do this, as seen in other Khronos software, is to provide some sort of dispatcher mechanism to the user, so they are free to load vulkan as they want.

The way Vulkan-Hpp solves this is by having a default global dispatcher, which uses the same method I show above, though more robust of course. I could do that here, but I think a more sensible approach for an util library like this, is to follow what VulkanMemoryAllocator does, and take the desired functions in as a struct. This also enables the library to be used in a multi device setting, which mocking the layers would not.

Mocking the ICD is primarly use for testing, but I haven't looked at Vulkan Layer Factory before. It seems to me to be the wrong way to go about this though. It would force every user of this library that doesn't explicitly link with vulkan, those using volk or SDL being an example, to do the same work over again. For me, the solution here would rather be to just modify the code of the library, which is what I've done.

@MarkCallow
Copy link
Copy Markdown
Collaborator

You are conflating what look to me to be two separate issues: getting libktx to work for applications that are loading libvulkan themselves, instead of linking to it, and mocking parts or the entirety of the Vulkan API. To solve the first only requires the handle to the instance and a pointer to VkLoadInstanceProcAddr. The latter is really what layers are all about. I see no fundamental difference between mocking and the validation functions layers were designed to support.

Once you have a layer you can use it with any library you like without having to modify said library or even the program using it as it is possible to activate layers by external means. This is all handled within libvulkan so will work even if you load libvulkan your self. I use the validation layers all the time with libktx. In that case I have vkloadtests activate the layers via VkCreateInstance rather than use the external means.

@rHermes
Copy link
Copy Markdown
Contributor Author

rHermes commented May 9, 2022

Ah ok, I see what you are getting at. For sure the user facing API could only have the possiblity of taking in an instance and a VkLoadInstanceProcAddr, but we will need a place to store the function pointers we pass in once that done, so I don't see what we would gain from not allowing the user to directly set the functions if they want.

Setting global functions on init would remove the ability to both use vkLoadDeviceProcAddr and remove the ability to use multiple instances. The latter is quite rare, but we get it for free with my method above.

@MarkCallow
Copy link
Copy Markdown
Collaborator

Thank you for the helpful discussion. I agree with your approach here.

@rHermes rHermes force-pushed the proper-vulkan-init branch from 5aa21bf to b9fb010 Compare May 14, 2022 08:57
@MarkCallow
Copy link
Copy Markdown
Collaborator

Apart from the question I just asked, I think this is ready to go. I suggest you drop the draft status.

@MarkCallow
Copy link
Copy Markdown
Collaborator

@rHermes, Ping! Please answer my question and drop the draft status.

@rHermes rHermes marked this pull request as ready for review May 23, 2022 07:28
@MarkCallow MarkCallow merged commit bb9babc into KhronosGroup:master May 23, 2022
@MarkCallow
Copy link
Copy Markdown
Collaborator

I am getting this warning when compiling with Visual Studio 2019:

C:\projects\ktx\lib\vk_funcs.c(121,1): warning C4113: 'FARPROC' differs in parameter lists from 'PFN_vkVoidFunction' [C:\projects\ktx\build\ktx.vcxproj]

Please take a look. Sorry I didn't notice before merging the PR.

@MarkCallow
Copy link
Copy Markdown
Collaborator

Another problem I've just noticed is

C:/projects/ktx/include/ktxvulkan.h(56): warning : Compound ktxVulkanFunctions is not documented. [C:\projects\ktx\build\libktx.doc.vcxproj]
C:/projects/ktx/lib/vkloader.c(181): warning : The following parameter of ktxVulkanDeviceInfo::ktxVulkanDeviceInfo_ConstructEx(ktxVulkanDeviceInfo *This, VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, VkQueue queue, VkCommandPool cmdPool, const VkAllocationCallbacks *pAllocator, const ktxVulkanFunctions *pFunctions) is not documented: [C:\projects\ktx\build\libktx.doc.vcxproj]
    parameter 'instance'

Please provide a PR to fix this and the FARPROC warning>

@rHermes
Copy link
Copy Markdown
Contributor Author

rHermes commented Jun 2, 2022

Hey! I'll look into this in the weekend. I normally develop on linux, but I'll try to set this up on windows :)

@MarkCallow
Copy link
Copy Markdown
Collaborator

Thanks. There are 2 more warnings from VS2017 C4204 non-standard extension used: non-constant aggregate initializer on lines 587 and 630 of vkloader.c.

KaperD pushed a commit to KaperD/KTX-Software that referenced this pull request Feb 21, 2024
Applications can now provide an instance pointer when creating a `VulkanDeviceInfo` object.
Optionally they can also provide pointers to the Vulkan functions to use.

Fixes KhronosGroup#567. Fixes KhronosGroup#568.
KaperD pushed a commit to KaperD/KTX-Software that referenced this pull request Feb 22, 2024
Applications can now provide an instance pointer when creating a `VulkanDeviceInfo` object.
Optionally they can also provide pointers to the Vulkan functions to use.

Fixes KhronosGroup#567. Fixes KhronosGroup#568.
KaperD pushed a commit to KaperD/KTX-Software that referenced this pull request Feb 22, 2024
Applications can now provide an instance pointer when creating a `VulkanDeviceInfo` object.
Optionally they can also provide pointers to the Vulkan functions to use.

Fixes KhronosGroup#567. Fixes KhronosGroup#568.
KaperD pushed a commit to KaperD/KTX-Software that referenced this pull request Feb 22, 2024
Applications can now provide an instance pointer when creating a `VulkanDeviceInfo` object.
Optionally they can also provide pointers to the Vulkan functions to use.

Fixes KhronosGroup#567. Fixes KhronosGroup#568.
KaperD pushed a commit to KaperD/KTX-Software that referenced this pull request Feb 22, 2024
Applications can now provide an instance pointer when creating a `VulkanDeviceInfo` object.
Optionally they can also provide pointers to the Vulkan functions to use.

Fixes KhronosGroup#567. Fixes KhronosGroup#568.
richgel999 pushed a commit to BinomialLLC/KTX-Software-Binomial-Fork that referenced this pull request Mar 9, 2026
Applications can now provide an instance pointer when creating a `VulkanDeviceInfo` object.
Optionally they can also provide pointers to the Vulkan functions to use.

Fixes KhronosGroup#567. Fixes KhronosGroup#568.
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

Successfully merging this pull request may close these issues.

2 participants