4

When specifying a VkAllocationCallbacks struct to vkCreate* functions, I would like to use only the vulkan notification without overwriting the real allocators, but I can't find how.

From https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkAllocationCallbacks.html

  • pfnAllocation must be a valid pointer to a valid user-defined PFN_vkAllocationFunction

  • pfnReallocation must be a valid pointer to a valid user-defined PFN_vkReallocationFunction

  • pfnFree must be a valid pointer to a valid user-defined PFN_vkFreeFunction

  • if either of pfnInternalAllocation or pfnInternalFree is not NULL, both must be valid callbacks

It seems weird to me that I can't just pass a nullptr to use the default allocations, is there any rationals for this ?

Maybe that it is possible to query the default allocators at runtime, but I haven't found any way to do it, I'd be glad to know if it is possible in a portable way.

Nowine
  • 166
  • 8

2 Answers2

4

You may not be fully understanding the difference between these sets of functions.

The first set of functions, the allocation functions, are used by Vulkan to allocate CPU memory... most of the time. The other two functions, the internal notification functions, are for the other times.

See, there are times when the Vulkan implementation needs to make OS-specific system calls to allocate memory. The Vulkan specification recognizes such a case: to allocate "executable memory": memory containing opcodes for the CPU's instruction set. For security reasons, OS's don't let you just execute random memory addresses; modern OS's require most apps to allocate memory in a special way in order for it to be executable. Therefore:

The application is not expected to handle allocating memory that is intended for execution by the host due to the complexities of differing security implementations across multiple platforms. The implementation will allocate such memory internally and invoke an application provided informational callback when these internal allocations are allocated and freed.

Normal memory allocation functions like ::operator new or malloc can't do that. And the Vulkan specification does not expect the client code to be able to make those system calls either.

However, the client code may need to be able to track such allocations, so that it can know how much memory the Vulkan implementation is keeping around. Therefore, when "internal allocations" are made/freed, the internal notification functions are called.

This is the only time such functions are called.

So if your goal is just to track when implementation allocations are being made/freed, the internal notification functions alone are not going to get the job done. You have to override them all, which means you'll need to actually do the allocation/reallocation/freeing.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • From what I understand, the non-internal allocations callbacks are triggered when allocating on host visible memory, whereas the internal callbacks are triggered when allocating on device visible memory. I was only interested by tracking the device allocated memory at the moment (for learning purposes, like what happen if I do this or that...), but of course I will need to track both in the future. The problem is that even if I wanted to track both, it would not be possible without rewriting the allocator which is something I want to avoid. – Nowine Jun 17 '19 at 17:26
  • @Nowine: "*From what I understand, the non-internal allocations callbacks are triggered when allocating on host visible memory, whereas the internal callbacks are triggered when allocating on device visible memory.*" Neither of these statements are true. These callbacks have nothing to do with device memory. – Nicol Bolas Jun 17 '19 at 17:27
  • The only kind of "device memory" you get to track is what you allocate directly, such as that used by `vkAllocateMemory`. If the Vulkan implementation of, for example, a command buffer needs to do some GPU memory allocations, you don't get to track those. – Nicol Bolas Jun 17 '19 at 17:30
  • Ok some things are more clear this way, but the original problem is still here. If I want to keep track of memory allocated by vulkan on host side, I have to rewrite the allocators. I can't simply get a callback with the amount of memory allocated. From what I red, the default allocators are likely to be more performant than hand written ones, this is why I don't want to overwrite it. – Nowine Jun 17 '19 at 17:45
  • @Nowine: "*I have to rewrite the allocators*" Which consists of simply calling `malloc`/et. al. It would have taken you less time to do that than it took to write the question. "*From what I red, the default allocators are likely to be more performant than hand written ones*" From where have you read this? – Nicol Bolas Jun 17 '19 at 17:56
  • From the Vulkan Programming Guide : - "It is very tempting to simply hook this function up to a naïve allocator such as malloc. If you do this, you will find that it works for a while but that certain functions might mysteriously crash later. If you provide your own allocator, it must honor the alignment parameter." - "It maps the Vulkan allocation functions to the POSIX aligned_malloc functions. Note that this allocator is almost certainly not better than what most Vulkan implementations use internally and serves only as an example of how to hook the callback functions up to your own code" – Nowine Jun 17 '19 at 18:03
0

As it seems that it's not possible, I would simply use a hand written allocator fulfilling the required alignement (with for exemple ::operator new in C++17). This allocator is very likely to be less performant than the Vulkan default one, but if it is only needed for debugging purposes it should do the trick.

Nowine
  • 166
  • 8