vulkan.gpuinfo.org icon indicating copy to clipboard operation
vulkan.gpuinfo.org copied to clipboard

Memory types and heaps appear confused.

Open DEF7 opened this issue 1 year ago • 2 comments

The database displays memory types as being a subset of heaps, when in Vulkan there are heaps and then a single list of memory types where each is each backed by one of the available heaps. There are only VkPhysicalDeviceMemoryProperties.memoryTypeCount number of memory types total, not one set of memory types per heap, which is how the database displays it - as though there's a memory type 0 for each heap. Memory type 0 is backed only by one heap, per the Vulkan API:

https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceMemoryProperties.html shows one list of memoryTypes[] for a physical device, and one memoryTypeCount - not individual per-heap memoryTypes[] or memoryTypeCounts.

https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkMemoryType.html shows a single heapIndex for a memoryType, not multiple heap indices.

Each memory type for a given physical device is supported by only one heap, and therefore should only be listed under that heap - not under multiple heaps, because each memory type only exists once, there is only one memory type with that index for the physical device, not multiple memory types with the same type index.

For instance: https://vulkan.gpuinfo.org/displayreport.php?id=32537#memory

This shows memory types 0-3 under Heap 0, and types 0-7 under Heap 1 even though types 0-3 have already been shown to include DEVICE_LOCAL, which Heap 1 doesn't, and then types 0-3 under Heap 2. It doesn't make any sense because there are not multiple lists of memory types on a per-heap basis. There are just the single list of memory types and the heaps that they are backed by (which is one heap per memory type).

i.e. a system with 5 memory types and 2 memory heaps could be something like this:

Heap 0: DEVICE_LOCAL
 Type 0: DEVICE_LOCAL
 Type 2: DEVICE_LOCAL | DEVICE_COHERENT | DEVICE_CACHED

Heap 1: none
 Type 1: HOST_VISIBLE | HOST_COHERENT
 Type 3: HOST_VISIBLE | HOST_COHERENT | HOST_CACHED
 Type 4: HOST_VISIBLE | HOST_COHERENT | DEVICE_COHERENT | DEVICE_CACHED

Or perhaps a system has the ~256MB heap for fast RAM access from the GPU, and has 3 heaps:

Heap 0: DEVICE_LOCAL
 Type 0: DEVICE_LOCAL
 Type 1: DEVICE_LOCAL | DEVICE_COHERENT | DEVICE_CACHED

Heap 1: none
 Type 2: HOST_VISIBLE | HOST_COHERENT
 Type 3: HOST_VISIBLE | HOST_COHERENT | HOST_CACHED

Heap 2: DEVICE_LOCAL
 Type 4: DEVICE_LOCAL | HOST_VISIBLE | HOST_COHERENT
 Type 5: DEVICE_LOCAL | HOST_VISIBLE | HOST_COHERENT | DEVICE_COHERENT | DEVICE_UNCACHED

Etcetera. Notice how each type index only exists once, under the heap that is backing it (i.e. VkPhysicalDeviceMemoryProperties.memoryTypes[].heapIndex) - not the same type listed multiple types with different combinations of VkMemoryPropertyFlags for the same type index.

This can't be a Vulkan implementation thing, because the API doesn't provide a way to access memory type flags in terms of a heap, you just have one list of heaps and then one list of memory types where each references a memory heap once, which means each memory type can only be classified under one heap, not multiple heaps.

I hope that this makes sense. Hopefully the actual database itself isn't bungled and this is just a front-end issue that has confused the heap/type convention. I can't imagine this is multiple reports with the same GPU/OS/driver/etc all merging together - these are being shown as a single "report" on the site.

I do notice that while the Vulkan Hardware Capability Viewer is showing each heap's memory types' property flags properly, for whatever reason it has changed the memory type indices on them to always start at zero. That's not a good sign! When you vkAllocateMemory() the VkMemoryAllocateInfo's .memoryTypeIndex field is specifically in terms of the memoryTypes[] array in VkPhysicalDeviceMemoryProperties, and it should show the memory indices as such, not starting at zero for each heap.

This is what my current Vulkan project outputs:

8 physical device memory types found:
 type[0] = heap[0] flags: DEVICE_LOCAL
 type[1] = heap[1] flags: HOST_VISIBLE HOST_COHERENT
 type[2] = heap[2] flags: DEVICE_LOCAL HOST_VISIBLE HOST_COHERENT
 type[3] = heap[1] flags: HOST_VISIBLE HOST_COHERENT HOST_CACHED
 type[4] = heap[0] flags: DEVICE_LOCAL DEVICE_COHERENT DEVICE_UNCACHED
 type[5] = heap[1] flags: HOST_VISIBLE HOST_COHERENT DEVICE_COHERENT DEVICE_UNCACHED
 type[6] = heap[2] flags: DEVICE_LOCAL HOST_VISIBLE HOST_COHERENT DEVICE_COHERENT DEVICE_UNCACHED
 type[7] = heap[1] flags: HOST_VISIBLE HOST_COHERENT HOST_CACHED DEVICE_COHERENT DEVICE_UNCACHED

If re-arranged by heap, and formatted a little differently, it would look like (and should in VCHV and on gpuinfo) this:

 heap[0]: type[0] flags = DEVICE_LOCAL
 heap[0]: type[4] flags = DEVICE_LOCAL DEVICE_COHERENT DEVICE_UNCACHED
 heap[1]: type[1] flags = HOST_VISIBLE HOST_COHERENT
 heap[1]: type[3] flags = HOST_VISIBLE HOST_COHERENT HOST_CACHED
 heap[1]: type[5] flags = HOST_VISIBLE HOST_COHERENT DEVICE_COHERENT DEVICE_UNCACHED
 heap[1]: type[7] flags = HOST_VISIBLE HOST_COHERENT HOST_CACHED DEVICE_COHERENT DEVICE_UNCACHED
 heap[2]: type[2] flags = DEVICE_LOCAL HOST_VISIBLE HOST_COHERENT
 heap[2]: type[6] flags = DEVICE_LOCAL HOST_VISIBLE HOST_COHERENT DEVICE_COHERENT DEVICE_UNCACHED

Where the memory types backed by a heap are only shown with that heap. No re-numbering of the memory types! I am thinking that this oversight in VHCV is why gpuinfo is showing reports for memory support the way that it is, and it's a database issue now :(

Doh!

DEF7 avatar Oct 27 '24 08:10 DEF7

It's simply the way that they're visually grouped at front-end level. Will take a look at how to improve this (if required) at some point, but I'm deep into reworking a different part of the database. I'll get back to you after that rework is finished.

SaschaWillems avatar Oct 28 '24 20:10 SaschaWillems

I realize it's probably not as big of an issue as I was originally thinking in my head. The memory types are not actually really becoming "confused", they're just re-numbered. It's still the same total memory types that a system exposes, but I was thinking that it was somehow getting the wrong total number of memory types as a result of re-numbering the types, which isn't the case.

Thanks Sascha :]

DEF7 avatar Oct 28 '24 22:10 DEF7