11

So, I'm gathering some info about my device in Vulkan during initialization and find a unique (or rather, quite similar) set of memory types returned by vkGetPhysicalDeviceMemoryProperties:

Device Name: GeForce GTX 1060 3GB
Device ID: 7170
Device Type: 2
Device Vendor ID: 4318
Device API Version: 4194369 (1.0.65)
Device Driver Version: 1636843520 (390.65)
Device Heaps:
    0 -> Size: 3133145088 Flags: 1
    1 -> Size: 8523874304 Flags: 0
Device Memory:
    0 -> Index: 1 Flags: 0
    1 -> Index: 1 Flags: 0
    2 -> Index: 1 Flags: 0
    3 -> Index: 1 Flags: 0
    4 -> Index: 1 Flags: 0
    5 -> Index: 1 Flags: 0
    6 -> Index: 1 Flags: 0
    7 -> Index: 0 Flags: 1
    8 -> Index: 0 Flags: 1
    9 -> Index: 1 Flags: 6
    10 -> Index: 1 Flags: 14

I sit down and contemplate... which one should I chose? Excluding the seven identical host local memory types, we still have two identical device memory types. There must be some reason for this, so I head out on my adventure through the depths of the internet!

StackOverflow doesn't seem to have anything similar, and Google returns some official documents from Nvidia that don't seem to touch on memory types extensively, so maybe the Vulkan documentation has something juicy? vkGetPhysicalDeviceMemoryProperties, VkPhysicalDeviceMemoryProperties and VkMemoryType don't seem to offer any insightful information on the topic of multiple identical memory types. Maybe the official Vulkan programming guide (whose source code still hasn't been published by the way) can touch on this topic? Unfortunately, it seems my quick glance has lead me to page 10 and beyond which doesn't seem to mention anything about identical memory types (but the queue section right after it does mention about identical queue families).

Why am I getting multiple memory types, and more importantly which one should I chose? Should I alternate the different types if I want to allocate multiple buffers like you would do with queues?

Frzn Flms
  • 468
  • 1
  • 7
  • 18
  • A comment I made recently: "Vulkan: for those who really wanted to program against the CAD database for the hardware but will settle for endless series of property enumeration APIs instead." As the answer below indicates, the operative property is you choose the *first* one that meets your requirements. There are likely also cases where one knows what the different heaps (at least) are and makes a hardware specific decision as to which to use. – Zalman Stern Jan 13 '18 at 19:57

1 Answers1

8

As far as the Vulkan specification is concerned:

  • VkMemoryRequirements::memoryTypeBits tells you which types you can use
  • in case of same memory type flags, they should be ordered by performance

So, the best/expected practice is:

1) Decide which flags you want/need.
2) Further filter the list with those types allowed by VkMemoryRequirements::memoryTypeBits
3) If there are any types left pick the first one. (Or start from step 1 with even less flags.)

The Vulkan does not necessarily know (and report) everything. But as long as you stick to the above you should be fine.

The What’s your Vulkan Memory Type? NVIDIA article seems to describe what is happening for the host-local types:

In OpenGL or DirectX 11, the driver traditionally has been supporting the application’s resource allocation by moving resources between device local and system memory in case of oversubscription of device memory, which can happen if the user might select image quality settings that exceed the amount of available device local memory.

[...]

To enable this, we are exposing additional host-local memory types:

  • A memory type for buffers
  • A memory type for color images of any format
  • Separate memory types for depth/stencil images for each depth/stencil format in system memory

The math seems to check out: 1(for buffers) + 1(for images) + 5(which seems to match supported depth formats on this GPU) = 7.

I would expect similar rationale for the device local types. SPECULATION: Possibly one for depth resources and one for images and buffers.

krOoze
  • 12,301
  • 1
  • 20
  • 34
  • 2
    I assume (and hope) that they use `memoryTypeBits` to restrict each image or buffer to just the relevant memory types. That way apps which are written correctly should do the right thing. – Jesse Hall Jan 14 '18 at 03:08
  • 1
    It would be nice to know what's going on with the device memory types... Should I email Nvidia? – Frzn Flms Jan 16 '18 at 13:03
  • 1
    @FrznFlms Can't hurt. They also have a Dev forum, which is more likely to be frequented by NV employees. Instead of hunting through blogs it would be nice if they made some semi-formal document of their implementation design choices. – krOoze Jan 16 '18 at 13:14
  • 1
    @FrznFlms Though in this case for host-memory I already included it in the answer. And the device-side will be likely similar (i.e. one kind of resource can use only one of the memory type, and different kinds the other type). This could be tested to find out exactly. Then again (especially assuming you are trying to program platform agnostic) I believe this does not really change anything about how you use Vulkan... it is more about curiosity than anything. – krOoze Jan 16 '18 at 13:19