Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't the Vulkan spec define VkDeviceSize?

Tags:

vulkan

The Vulkan specification (1.0.12) introduces VkDeviceSize in section 2.4:

With few exceptions, Vulkan uses the standard C types for parameters (int types from stdint.h, etc). Exceptions to this are using VkResult for return values, using VkBool32 for boolean values, VkDeviceSize for sizes and offsets pertaining to device address space, and VkFlags for passing bits or sets of bits of predefined values.

However, it never tells us what the underlying type of VkDeviceSize actually is. How are we supposed to know whether it is safe to convert between a VkDeviceSize and a size_t?

From the headers provided with the SDK, I see that it is typedef'ed to uint64_t. How likely is it that this would change, at any point in the future?

like image 563
Andrew Williamson Avatar asked Apr 30 '16 01:04

Andrew Williamson


2 Answers

Why doesn't the Vulkan spec define VkDeviceSize?

Notice that the Vulkan specification does not specify, for example, the value of any of its enumerators. Why? Because they're specified in vk.xml, which is used to generate vulkan.h.

Same goes for VkDeviceSize. Just as it does for all of the other types that Vulkan defines.

Yes, the OpenGL specification specified particular sizes for its various types. But Vulkan doesn't, and it does not have to.

How are we supposed to know whether it is safe to convert between a VkDeviceSize and a size_t?

The only ways it would be unsafe is if one of the following is true:

  1. The value of type size_t you want to convert is too big for VkDeviceSize.

  2. The value of VkDeviceSize you want to convert is too big for size_t.

Well, the vast majority of places where you specify VkDeviceSize ultimately derive from a call to vkAllocateMemory (mapping offsets, buffer/image creation, etc, all are based on a block of memory you allocate). So if you're going to provide a size_t that can't fit into VkDeviceSize, then... what does that mean?

Well clearly, it means that the amount of memory you intend to allocate must be greater than the amount of memory that the implementation provides. After all, the memory limits are themselves specified by VkDeviceSize. So if your size_t is too big to fit into that type, then you must be trying to allocate more memory than exists.

I'd say that this is a much bigger problem than an integer conversion not working.

And #2 primarily matters for vkGetPhysicalDeviceMemoryProperties. If size_t is too small to store the values you get back from that... wait, why would you be using size_t to store those values to begin with? Is there some reason you couldn't use the actual type of the value, VkDeviceSize?

How likely is it that this would change, at any point in the future?

That's more or less irrelevant. Why? Because of the compatibility guarantees Vulkan already has.

By the specification, minor versions of Vulkan cannot make backwards-incompatible changes. If you write code that works against Vulkan 1.0, it must also function against Vulkan 1.1. And 1.2. And so forth.

If VkDeviceSize changed between versions, one would have to (at a minimum) recompile one's code to fix it. And Vulkan seems to define backwards compatibility to be binary compatibility, not source compatibility:

A given version of the API is backwards compatible with an earlier version if an application, relying only on valid behavior and functionality defined by the earlier specification, is able to correctly run against each version without any modification.

That would suggest that the application should work without recompilation.

So the only time VkDeviceSize would change would be with major version changes. And if that happens, all bets are off as far as compatibility is concerned. So minor things like changing that size would probably be irrelevant.

like image 174
Nicol Bolas Avatar answered Dec 06 '22 13:12

Nicol Bolas


It is defined in the vk.xml (as uint64_t). Spec quote of it's official status:

The canonical definition of the Vulkan APIs is kept in an XML file known as the Vulkan registry. The registry is kept in src/spec/vk.xml[...]

It is rather rooted now and you can't expect it to change in 1.0.X patch versions (though some minor (arguably) breaking changes have occured so far, while it's new)

You can query it using sizeof() operator. You don't know the size of size_t neither for that matter.

like image 42
krOoze Avatar answered Dec 06 '22 13:12

krOoze