Git Product home page Git Product logo

volk's Introduction

🐺 volk Build Status

Purpose

volk is a meta-loader for Vulkan. It allows you to dynamically load entrypoints required to use Vulkan without linking to vulkan-1.dll or statically linking Vulkan loader. Additionally, volk simplifies the use of Vulkan extensions by automatically loading all associated entrypoints. Finally, volk enables loading Vulkan entrypoints directly from the driver which can increase performance by skipping loader dispatch overhead.

volk is written in C89 and supports Windows, Linux, Android and macOS (via MoltenVK).

Building

There are multiple ways to use volk in your project:

  1. You can add volk.c to your build system. Note that the usual preprocessor defines that enable Vulkan's platform-specific functions (VK_USE_PLATFORM_WIN32_KHR, VK_USE_PLATFORM_XLIB_KHR, VK_USE_PLATFORM_MACOS_MVK, etc) must be passed as desired to the compiler when building volk.c.
  2. You can use provided CMake files, with the usage detailed below.
  3. You can use volk in header-only fashion. Include volk.h wherever you want to use Vulkan functions. In exactly one source file, define VOLK_IMPLEMENTATION before including volk.h. Do not build volk.c at all in this case - however, volk.c must still be in the same directory as volk.h. This method of integrating volk makes it possible to set the platform defines mentioned above with arbitrary (preprocessor) logic in your code.

Basic usage

To use volk, you have to include volk.h instead of vulkan/vulkan.h; this is necessary to use function definitions from volk.

If some files in your application include vulkan/vulkan.h and don't include volk.h, this can result in symbol conflicts; consider defining VK_NO_PROTOTYPES when compiling code that uses Vulkan to make sure this doesn't happen. It's also important to make sure that vulkan-1 is not linked into the application, as this results in symbol name conflicts as well.

To initialize volk, call this function first:

VkResult volkInitialize();

This will attempt to load Vulkan loader from the system; if this function returns VK_SUCCESS you can proceed to create Vulkan instance. If this function fails, this means Vulkan loader isn't installed on your system.

After creating the Vulkan instance using Vulkan API, call this function:

void volkLoadInstance(VkInstance instance);

This function will load all required Vulkan entrypoints, including all extensions; you can use Vulkan from here on as usual.

Optimizing device calls

If you use volk as described in the previous section, all device-related function calls, such as vkCmdDraw, will go through Vulkan loader dispatch code. This allows you to transparently support multiple VkDevice objects in the same application, but comes at a price of dispatch overhead which can be as high as 7% depending on the driver and application.

To avoid this, you have two options:

  1. For applications that use just one VkDevice object, load device-related Vulkan entrypoints directly from the driver with this function:
void volkLoadDevice(VkDevice device);
  1. For applications that use multiple VkDevice objects, load device-related Vulkan entrypoints into a table:
void volkLoadDeviceTable(struct VolkDeviceTable* table, VkDevice device);

The second option requires you to change the application code to store one VolkDeviceTable per VkDevice and call functions from this table instead.

Device entrypoints are loaded using vkGetDeviceProcAddr; when no layers are present, this commonly results in most function pointers pointing directly at the driver functions, minimizing the call overhead. When layers are loaded, the entrypoints will point at the implementations in the first applicable layer, so this is compatible with any layers including validation layers.

Since volkLoadDevice overwrites some function pointers with device-specific versions, you can choose to use volkLoadInstanceOnly instead of volkLoadInstance; when using table-based interface this can also help enforce the usage of the function tables as volkLoadInstanceOnly will leave device-specific functions as NULL.

CMake support

If your project uses CMake, volk provides you with targets corresponding to the different use cases:

  1. Target volk is a static library. Any platform defines can be passed to the compiler by setting VOLK_STATIC_DEFINES. Example:
if (WIN32)
   set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_WIN32_KHR)
elseif()
   ...
endif()
add_subdirectory(volk)
target_link_library(my_application PRIVATE volk)
  1. Target volk_headers is an interface target for the header-only style. Example:
add_subdirectory(volk)
target_link_library(my_application PRIVATE volk_headers)

and in the code:

/* ...any logic setting VK_USE_PLATFORM_WIN32_KHR and friends... */
#define VOLK_IMPLEMENTATION
#include "volk.h"

The above example use add_subdirectory to include volk into CMake's build tree. This is a good choice if you copy the volk files into your project tree or as a git submodule.

Volk also supports installation and config-file packages. Installation is disabled by default (so as to not pollute user projects with install rules), and can be enabled by passing -DVOLK_INSTALL=ON to CMake. Once installed, do something like find_package(volk CONFIG REQUIRED) in your project's CMakeLists.txt. The imported volk targets are called volk::volk and volk::volk_headers.

License

This library is available to anybody free of charge, under the terms of MIT License (see LICENSE.md).

volk's People

Contributors

alanjian85 avatar amerkoleci avatar apg360 avatar bionicles avatar brad0 avatar cxong avatar ellarbooher avatar github-actions[bot] avatar gmodarelli avatar ibriano avatar jeweg avatar jkunstwald avatar lephar avatar loicmouton avatar lostgoat avatar lunarpapillo avatar philip-trettner avatar radgerayden avatar richard-lunarg avatar scribam avatar siliace avatar spanzeri avatar spnda avatar thelavablock avatar themaister avatar themostdiligent avatar tobine avatar valakor avatar web-flow avatar zeux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

volk's Issues

Expose volkGenLoadLoader

I have a use-case where I'd like to load my own vulkan.so, and provide my own vkGetInstanceProcAddr to volk. It seems like just making volkGenLoadLoader public would enable that.

cast between incompatible function types

when I use MinGW gcc 8.2.0 to compile the library, there was a error.
error: cast between incompatible function types from 'FARPROC' {aka 'long long int ()()'} to 'void ( (*)(struct VkInstance_T *, const char *))(void)' [-Werror=cast-function-type]
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetProcAddress(module, "vkGetInstanceProcAddr");

Compile error with MinGW cross-compiler

Platform: Ubuntu 22.04
Compiler: MinGW-w64 GCC 10 cross-compiler

When windows.h is included before volk.h (e.g. when glad is used), compilation fails with the following error:

deps/volk/volk.c:10:31: error: redefinition of typedef ‘FARPROC’ with different type
   10 |   typedef __int64 (__stdcall* FARPROC)(void);
      |                               ^~~~~~~
In file included from /usr/share/mingw-w64/include/windef.h:9,
                 from /usr/share/mingw-w64/include/windows.h:69,
                 from deps/glad/include/glad/vulkan.h:342,
<snip...>
/usr/share/mingw-w64/include/minwindef.h:196:28: note: previous declaration of ‘FARPROC’ was here
  196 |   typedef INT_PTR (WINAPI *FARPROC) ();
      |                            ^~~~~~~

The minwindef.h Windows header also contains the latter declaration, so I assume the non-void parameter declaration is the correct one.

Device Table Overflow

Somehow this seems to overflow into the next fields of my struct
Here is where that happens:
image
any idea why that could be the case?
image
volkLoadDeviceTable(&app->vk, app->device);

Loading of `vkDestroyInstance` failed: Access violation writing location

Capture

However, if I try to load it into a temporary variable (vkDestroyInstance_another) on the line https://github.com/zeux/volk/blob/master/volk.c#L153, like:

// vkDestroyInstance = (PFN_vkDestroyInstance)load(context, "vkDestroyInstance");
PFN_vkDestroyInstance vkDestroyInstance_another = (PFN_vkDestroyInstance)load(context, "vkDestroyInstance");

it seems to work and consequently vkDestroyInstance_another seems to be a pointer into vulkan-1.dll

Call stack:

helloworld_d.exe!volkGenLoadInstance(void * context, void(*)()(*)(void *, const char *) load) Line 153	C
helloworld_d.exe!volkLoadInstance(VkInstance_T * instance) Line 104	C
helloworld_d.exe!nbl::video::CVulkanConnection::CVulkanConnection(unsigned int appVer, const char * appName, const nbl::video::SDebugCallback & dbgCb) Line 33	C++
helloworld_d.exe!nbl::core::make_smart_refctd_ptr<nbl::video::CVulkanConnection,unsigned int &,char const * &,nbl::video::SDebugCallback const &>(unsigned int & <args_0>, const char * & <args_1>, const nbl::video::SDebugCallback & <args_2>) Line 333	C++
helloworld_d.exe!nbl::video::createVulkanConnection(unsigned int appVer, const char * appName, const nbl::video::SDebugCallback & dbgCb) Line 10	C++
helloworld_d.exe!nbl::video::IAPIConnection::create(nbl::video::E_API_TYPE apiType, unsigned int appVer, const char * appName, const nbl::video::SDebugCallback & dbgCb) Line 27	C++
helloworld_d.exe!main() Line 177	C++
[External Code]	

volkLoadDeviceTable table functions unset to NULL after return

volkLoadDeviceTable

void volkLoadDeviceTable(struct VolkDeviceTable* table, VkDevice device)
{
    volkGenLoadDeviceTable(table, device, vkGetDeviceProcAddrStub);
    printf("%p // table->vkCreateFence after returning from volkGenLoadDeviceTable\n", table->vkCreateFence);
    printf("%p // table->vkAcquireNextImageKHR after returning from volkGenLoadDeviceTable\n", table->vkAcquireNextImageKHR);
}

I added some prints to the volkLoadDeviceTable function.

volkLoadDeviceTable calling code

    // vkCreateDevice etc. abstracted
    struct VolkDeviceTable *Table_p = malloc(sizeof(struct VolkDeviceTable));              
    if (Table_p == NULL) {exit(0);}                                                                                                                                                  
    volkLoadDeviceTable(Table_p, Device);                                                                                                                                
    printf("%p // table->vkCreateFence after returning from volkLoadDeviceTable\n", Table_p->vkCreateFence);
    printf("%p // table->vkAcquireNextImageKHR after returning from volkLoadDeviceTable\n", Table_p->vkAcquireNextImageKHR);                                                                                         
    exit(0);   

Output and Problem Description

0x7fcec0f10450 // table->vkCreateFence after returning from volkGenLoadDeviceTable
0x7fcec0f127c0 // table->vkAcquireNextImageKHR after returning from volkGenLoadDeviceTable
0x7fcec0f10450 // table->vkCreateFence after returning from volkLoadDeviceTable
(nil) // table->vkAcquireNextImageKHR after returning from volkLoadDeviceTable

As you notice, somehow table->vkAcquireNextImageKHR is NULL after the execution returns from volkLoadDeviceTable. But the actual loading completed successfully, otherwise vkAcquireNextImageKHR would be NULL directly after volkGenLoadDeviceTable.

The code worked fine a few days ago. All functions were being loaded correctly. I'm really not sure what is causing this.

I noticed that this at least affects functions loaded by the definition of VK_KHR_swapchain (such as vkAcquireNextImageKHR). Functions loaded when defining VK_VERSION_1_0 (such as vkCreateFence) are not affected. I think this is not really a volk issue, but I'm not sure whom else to ask for help.. Any help would be greatly appreciated!

System:

Arch Linux 5.4.69-1-lts
Vulkan Instance Version: 1.2.153
VkPhysicalDeviceDriverProperties:
---------------------------------
	driverID           = DRIVER_ID_INTEL_OPEN_SOURCE_MESA
	driverName     = Intel open-source Mesa driver
	driverInfo         = Mesa 20.2.0
	conformanceVersion = 1.2.0.0

volk + GLFW = (identifier glfwCreateWindowSurface not found)

First time volk user here. I have been trying to use volk as a header-only library and have followed the steps given to use volk.h instead of vulkan.h wherever required. I have also made sure to have just one file with

#define VOLK_IMPLEMENTATION
#include "Volk/volk.h"

I have also not linking against vulkan-1.lib anymore as mentioned.

However, due to this, I get this "identifier glfwCreateWindowSurface not found" error.

If I include GLFW with #define GLFW_INCLUDE_VULKAN then obviously this function becomes available since vulkan.h from the glfw3.h gets included which prompts "fatal error C1189: #error: To use volk, you need to define VK_NO_PROTOTYPES before including vulkan.h"

Has anyone faced this before, clearly, I am missing out on something obvious!

Should I be calling `volkFinalize()`?

This is interesting... you expose several functions such as volkInitialize() and volkLoadInstance() and a few other functions. The ones I explicitly mentioned have a place on the README where a brief usage example utilizes them. Usually libraries and APIs would expose functions like init_xyz() or create_xyz(), and they will have their own termination functions like deinit_xyz() and destroy_xyz(). The README has no mention such, but upon looking into the volk header file I found volkFinalize() - which thanks to the comment above it - allows me to draw the conclusion that this is the termination function of volkInitialize().

It's exposed in the header file, so I'd assume it is for users of Volk to call (and volk.c doesn't seem to call it), but sometimes this isn't always the case. The tests that reside in test/ don't call the volkFinalize() and neither do the projects that I found that use Volk. My question is: Should I be calling volkFinalize()? and when?

It would be appreciated if the comments on each function can reflect its usage. Say, the comment can add:

/**
 * <original comment here>
 * 
 * if initializing volk fails, volk will internally do teardown operations,
 * but if it is successful, then the caller needs to call `volkFinalize()`
 * when the renderer is being deconstructed (or something like that).
*/
VkResult volkInitialize(void);

You know?

PFN_vkGetImageViewAddressNVX undefined

Hi!

Cloning the most recent version, PFN_vkGetImageViewAddressNVX appears to be undefined for me. I have Vulkan SDK 1.2.1350 on windows. To work around this, I have commented out all references to PFN_vkGetImageViewAddressNVX and it runs. Maybe i have done something wrong, but incase it's not, thought I'd post this here.

Many thanks

Harri

add InstanceTable?

is it possible to add an instance table instead of loading the functions in global scope?

Support MoltenVK without ICD

Right now volk always loads libvulkan.dylib on macOS which uses the ICD flow - it's compatible with validation layers, but requires the corrent JSON files etc.

For shipping many applications would want to link directly to MoltenVK dylib to bypass that, so we should support this automatically by falling back to MoltenVK dylib during initialization.

type name changes with vulkan SDK 1.2.182.0

Using the latest vulkan SDK (1.2.182.0) I get a bunch of errors of the following kind when building volk:

[  5%] Building C object lava/extern/volk/CMakeFiles/volk.dir/volk.c.o
In file included from /local/pschmitz/development/lava-samples/lava/extern/volk/volk.c:3:
/local/pschmitz/development/lava-samples/lava/extern/volk/volk.h:415:2: error: unknown type name ‘PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI’
  415 |  PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /local/pschmitz/development/lava-samples/lava/extern/volk/volk.c:3:
/local/pschmitz/development/lava-samples/lava/extern/volk/volk.h:1050:8: error: unknown type name ‘PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI’
 1050 | extern PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI;
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/local/pschmitz/development/lava-samples/lava/extern/volk/volk.c: In function ‘volkGenLoadDevice’:
/local/pschmitz/development/lava-samples/lava/extern/volk/volk.c:636:53: error: ‘PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI’ undeclared (first use in this function); did you mean ‘vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI’?
  636 |  vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI = (PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)load(context, "vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI");
      |                                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The errors don't appear with vulkan SDK version 1.2.176.1. It looks like these HUAWEI specific calls got renamed.

Symbol `vkDeviceWaitIdle' causes overflow in R_X86_64_PC32 relocation

I'm having these output, but the app still runs.
Is this important?

./ShadowMapping: Symbol `vkDeviceWaitIdle' causes overflow in R_X86_64_PC32 relocation
./ShadowMapping: Symbol `vkDeviceWaitIdle' causes overflow in R_X86_64_PC32 relocation
./ShadowMapping: Symbol `vkDestroySurfaceKHR' causes overflow in R_X86_64_PC32 relocation
./ShadowMapping: Symbol `vkDestroySurfaceKHR' causes overflow in R_X86_64_PC32 relocation

Linking against `dl` on linux

Out of the box one might encounter error: undefined reference to dlopen on linux.

Maybe add target_link_libraries(volk PRIVATE dl) on linux?

Use of X macro for function prototype list

volk/volk.c

Line 98 in 0c836e6

/* VOLK_GENERATE_LOAD_INSTANCE */

A modest suggestion to make the code simpler: generate.py could create separate header file for each category of Vulkan functions (volk_instance.h, volk_device.h, volk_loader.h...), these files could then be included though X macros for function loading, prototype definitions, device table setup...

VK_KHR_ray_tracing not usable on Windows

I can't get the new functions from VK_KHR_ray_tracing to work via volk. While they are actually included in the volk headers, the function pointers are defined in a new and separate vulkan_beta.h header file, which doesn't seem to be included by volk at all on Windows.

The main Vulkan header includes that new beta header via a new define:

#ifdef VK_ENABLE_BETA_EXTENSIONS
#include "vulkan_beta.h"
#endif

But as on Windows, only the Vulkan core headers is explicitly included the beta one isn't included at all.

Declaring vk*() symbols at global scope is illegal

Had a look and saw that volkGenLoadDevice() is loading global symbols with vk*() namespace. As far as I've understood it, this is not allowed, and needs to be namespaced accordingly.

From spec:

On platforms where Vulkan is provided as a shared library, library symbols beginning with “vk”
and followed by a digit or uppercase letter are reserved for use by the implementation.
Applications which use Vulkan must not provide definitions of these symbols. This allows the
Vulkan shared library to be updated with additional symbols for new API versions or extensions
without causing symbol conflicts with existing applications.

There is some discussion around extension loading here, which might be relevant: KhronosGroup/Vulkan-Ecosystem#21

Add Macro in volk.h for custom vulkan.h (etc.) location

Hi there,

first of all thanks a lot for your work!

Just a quick thought: How about we add a macro in volk.h which allows devs to define paths to vulkan.h, vulkan_core.h, etc.? This would mean that the target system wouldn't have to supply header files and we wouldn't need to install header files to a place which is visible via environment variable. Which is good because we wouldn't clutter the target system with unnecessary header files if it turns out at runtime that vulkan won't be used.

I have something like this in mind:

#ifdef CUSTOM_VULKAN_H_PATH
#include CUSTOM_VULKAN_H_PATH
#endif
#ifndef CUSTOM_VULKAN_H_PATH
#include <vulkan/vulkan.h>
#endif

Best regards!

Change include of vulkan.h on windows platforms.

In order to avoid including windows.h with vulkan.h and subsequently with volk.h one thing to be done (as pointer by Jérémie) is to include vk_platform.h and vulkan_core.h on the header:
#ifndef VULKAN_H_
#if defined(_WIN32)
#include <vulkan/vk_platform.h>
#include <vulkan/vulkan_core.h>
#else
#include <vulkan/vulkan.h>
#endif
#endif

Then, at the .c file use the following instead of #include <windows.h>:
#ifdef _WIN32

typedef void* HANDLER;
typedef void* HINSTANCE;
typedef void* HWND;
typedef void* HMONITOR;
typedef void* HMODULE;
typedef const wchar_t* LPCWSTR;
typedef unsigned long DWORD;

typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
void* lpSecurityDescriptor;
int bInheritHandle;
} SECURITY_ATTRIBUTES;

typedef int64_t (__stdcall* FARPROC)(void);

void* __stdcall LoadLibraryA(const char* lpFileName);
FARPROC* __stdcall GetProcAddress(void* hModule, const char* lProcName);
void* __stdcall GetModuleHandleA(const char* lpModuleName);
void* __stdcall GetActiveWindow();

static void volkGenLoadLoader(void* context, PFN_vkVoidFunction (load)(void, const char*));
static void volkGenLoadInstance(void* context, PFN_vkVoidFunction (load)(void, const char*));
static void volkGenLoadDevice(void* context, PFN_vkVoidFunction (load)(void, const char*));
static void volkGenLoadDeviceTable(struct VolkDeviceTable* table, void* context, PFN_vkVoidFunction (load)(void, const char*));

static PFN_vkVoidFunction vkGetInstanceProcAddrStub(void* context, const char* name)
{
return vkGetInstanceProcAddr((VkInstance)context, name);
}

static PFN_vkVoidFunction vkGetDeviceProcAddrStub(void* context, const char* name)
{
return vkGetDeviceProcAddr((VkDevice)context, name);
}
#else
#include <dlfcn.h>
#endif

mold linker symbol mismatch warning

Hi,

When linking volk using mold linker, I get a ton of warnings (one for each definition) like:

mold: warning: symbol type mismatch: vkGetDeviceQueue2
>>> defined in Submodules/volk/libvolk.a(volk.c.o) as STT_OBJECT
>>> defined in /home/moka/vulkan/1.3.250.1/x86_64/lib/libvulkan.so as STT_FUNC

I am on arch linux using mold linker 2.0. The warning seems to be added in the 2.0 version of the linker so I am not entirely sure if this issue is with mold or volk at this point.

I am linking volk with cmake via the volk target. Mold is enabled like this: cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-fuse-ld=mold" .. . For what it's worth, the same happens if I compile volk into my own c/cpp file.

Any ideas welcome,
Thanks!

`visibility (hidden)` is problematic in certain circumstances

I use volk through an FFI interface, so my only option is to build it as a shared library. At least on linux this doesn't work because of the pragma at https://github.com/zeux/volk/blob/master/volk.c#L1262, which makes all vk* functions hidden such that they can't be dynamically linked.
I understand there's probably some advantage to this if you're statically linking, but perhaps it could be configurable via a preprocessor option? Locally I just patched it so that it says "default" instead and it works for me.

question on unloading the dll

Thank you for sharing this simple loader.

I'd like to know why there is no a corresponding function to the volkInitialize to unload the loaded dll.
I know it's just simple to add that function and unload the dll by myself. But I just wanted to know your opinion about not adding it.

Thanks!

vkCreateWin32SurfaceKHR initialized to nullptr

(PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr( vk.Instance, "vkCreateWin32SurfaceKHR" ); always returns nullptr.

Extensions functions like vkCreateWin32SurfaceKHR etc can be obtained only by static linking or using dlsym / GetProcAddress.

vkDestroyDevice & vkDestroyInstance fail at dll unloading

Not sure if this is something that can be fixed in volk.

What I'm trying to do is something like:

MyContext::~MyContext()
{
	vkDestroyDevice(m_device, nullptr);
	vkDestroyInstance(m_instance, nullptr);
}
static MyContext s_context;

I expected that the destructor of s_context would be called at process exit time, so that I can do some clean up there. This works fine when the code is built into an exe file.
However, when I use the code above in a dll module, sometimes the vkDestroyxx commands will fail, which I guess is because vulkan-1.dll is unloaded earlier than my dll.
Is there anything I can do to fix this?

Thanks.

Add option to disable the volk target

At the moment, the volk target is always created by CMake. However, when VOLK_PULL_IN_VULKAN is OFF, the target is not complete and will not build unless path to Vulkan headers is explicitly added. When VOLK_PULL_IN_VULKAN is OFF, the application most likely only needs the volk_headers target and has to explicitly remove volk from build.
It would be very helpful if there was an option to only define the volk_headers target, e.g. VOLK_HEADERS_ONLY

vkSetDebugUtilsObjectNameEXT retrieval problem

Hi,

Thanks for this amazing tool, it eases the pain of managing vulkan extensions greatly. A slight issue for me is that the vkSetDebugUtilsObjectNameEXT is always null, but if I load it manually like this it works fine:

VkDevice device;
//...

vkSetDebugUtilsObjectNameEXT = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetDeviceProcAddr(device, "vkSetDebugUtilsObjectNameEXT");

(I think it should be in the volkGenLoadDevice function instead of volkGenLoadInstance but I might be mistaken)

This is also true for the following functions:

  • vkSetDebugUtilsObjectNameEXT
  • vkCmdBeginDebugUtilsLabelEXT
  • vkCmdEndDebugUtilsLabelEXT
  • vkCmdInsertDebugUtilsLabelEXT

At the same time, all other extensions that I use work fine without doing anything like this manually (raytracing, mesh shader, vrs... )

Is this intended? Am I not using this library correctly?

Thanks

Access violation in volkInitialize

I am running into a similar issue to #58 and am getting a write access violation in the same location. Weirdly, however, the violation only occurs when I remove code from a virtual method. The code being removed is not executed prior to the access violation. (Example commit of what I mean: benreid24/BLIB@3046839).

volk mem

It appears that somehow the vkGetInstanceProcAddr variable is getting placed in readonly (or otherwise protected) memory. In the screenshot you can see that it has a non-null value prior to the assignment, and it's the assignment itself that is failing. I don't know how that could be corrupted at runtime because it's a direct access to a global variable. I am running Windows 10 with an Nvidia 1080 and using Visual Studio (MSVC) to build and run. Verified that the same issue also happens on a different machine (similar specs but different Nvidia GPU).

I unfortunately do not have a minimal reproducible example, but the error should be reproducible by running this example: https://github.com/benreid24/BLIB/blob/volk-working/examples/Graphics/main.cpp. The volk-broken and volk-working branches illustrate the error. To build after cloning:

  • git submodule update --init --recursive
  • cmake -S . -B ./build (use your generator of choice)
  • cmake --build ./build --target graphics

platform macros and pre-built volk

To get the platform-specific function pointers, one of the macros (e.g. VK_USE_PLATFORM_WIN32_KHR) must be set before including vulkan.h. However, those macros need to be defined at volk build time as well. I totally didn't think of that when I made the cmake package config and the vcpkg port. Doesn't this mean that volk will in practice always have to be built as part of a user's project? Automatically setting the right define doesn't seem to be an option: it'd work for win32, but it couldn't make the choice between xcb, xlib, wayland, etc.
Am I missing something here? How did that work with the earlier simple CMakeLists? It didn't set any defines either.

volkInitialize return 0 even if vulkan is available on the system

I added volk to my project so I can make a build that dynamically loads vulkan.

I did as the documentation asked, and included volk.h

#pragma once

#define VK_USE_PLATFORM_WIN32_KHR
#include "volk.h"

#define VMA_STATIC_VULKAN_FUNCTIONS 0
#include "vk_mem_alloc.h"

and in a .cpp included the implementation

#include "vulkan.hpp"

#define VOLK_IMPLEMENTATION
#include "volk.h"

#define VMA_IMPLEMENTATION
#include "vk_mem_alloc.h"

then finally volkInitialize() gets called but it returns 0, this means that the vulkan loader wasn't found.

I am missing something? I know for sure my laptop has a vulkan driver. It works fine if I dynamicaly link vulkan-1

Warnings from Volk with higher warnings enabled

The same problem regarding other functions was previously addressed in #11. I'm new to Vulkan, Volk, and the whole graphics and rendering thing, so I'm not sure if this was intensional or not. Anyways, here is the relevant part from compiling Volk with -std=c11 -O2 -Wall -Wextra -pedantic. Oh, and this is using the sdk-1.3.250 branch.

# ...
vendor/volk/volk.c:113:33: warning: a function declaration without a prototype is deprecated in all versions of C [-Wstrict-prototypes]
VkInstance volkGetLoadedInstance()
                                ^
                                 void
vendor/volk/volk.c:124:29: warning: a function declaration without a prototype is deprecated in all versions of C [-Wstrict-prototypes]
VkDevice volkGetLoadedDevice()
                            ^
                             void
2 warnings generated.

Does device-optimized volk prevent using layers?

Just a point of clarification after reading README. If using volk in the device-optimized manner to bypass loader dispatch table, does that mean that layer cannot be loaded?
So one usage model for volk would be to use it at the instance-level for development where platform loader and layers are still in use, then when ready to ship use the device-optimized setup?

FYI - we will be making use of 'api' attribute in Vulkan XML, you will need a small change

This has been part of the schema for a while, but we will start using it soon to allow combining the Vulkan and Vulkan SC XML in a single file. You will need to adapt your loading code to this new use.

The simplest way is to globally pre-filter the XML to remove all tags with explicit 'api' elements not matching the API being generated, as the Vulkan-Docs scripts already do. For this you can either use the scripts/stripAPI.py script that's provided, or do the equivalent

import reg
keepAPI = 'vulkan'
reg.stripNonmatchingAPIs(tree.getroot(), keepAPI, actuallyDelete=True)

after loading your ElementTree from the XML, where 'reg' is scripts/reg.py from the Vulkan-Docs repository.

Let me know if there are any questions. There isn't a specific timescale for this, but probably will appear starting sometime in February.

Warnings from C code

It would be nice if volk could fix some warnings emitted from the volk.h/volk.c when enabling really high warning levels, both on Windows and Linux. The offending code is declarations and definitions which uses the form:

VkResult foo();
VkResult foo() {
...
}

instead of

VkResult foo(void);
VkResult foo(void) {
...
}

On VS2017 the warning emitted is C4255 (https://msdn.microsoft.com/en-us/library/0k9z2ey4.aspx) and on Linux -Wstrict-prototypes (which complains about the missing void) and -Wmissing-prototypes (which follows since the prototypes aren't defined). All in all, not a big issue, but also a simple fix?

VK_EXT_debug_utils initialization

VK_EXT_debug_utils pointers are retreived in volkGenLoadDevice. Would it be more appropriate to move that code to volkGenLoadInstance?

Right now I have valid vkCmdBeginDebugUtilsLabelEXT pointer after volkLoadInstance call. But subsequent volkLoadDevice call sets it to null.

Hi from the other VOLK project

Hi!

I'm one of the maintainers for the Vector Optimized Library of Kernels (VOLK).
I was just made aware of your project and I guess you didn't know about ours.

I can imagine that users who try to install both projects might run into issues. We haven't received any issues though. Feel free to get in touch in case this happens.

Feature request: Only enable user chosen Vulkan subset

Currently, volk creates function pointers for all Vulkan API and extensions that are defined in the vulkan header. If instead the user could define (I suppose via macro defines) which core version + extension are being used, it would have the following advantages:

  • Only functions that the user plans to use are actually resolved, speeding up initialization
  • It prevents the user from accidentally using functions from extensions or core versions that were not declared

Missing extension name definitions?

For instance, if I try to use VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME there is an error. It seems like volk.h includes vulkan.h already, so I am not sure why these symbols are not included.

Segmentation Fault when loading instance

Hello,
I have encountered an issue in which the debugger gives me this error :

Thread 1 received signal SIGSEGV, Segmentation fault.
0x00007ffb892d1877 in vulkan-1!vkResetFences () from C:\WINDOWS\SYSTEM32\vulkan-1.dll

after using any functions after using volkLoadInstance. Enabling validation layers or not does not fix the issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.