Available Memory Types in Vulkan

The type of memory which should be used in Vulkan is dependent on the use case

Vulkan provides several memory types. The specification orders them based on their performance. An application should attempt to use the fastest memory types wherever possible.

The list below contains the memory types and common use cases:

  • The memory type VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT is recommended when allocating static device buffers (created once at initialisation) used to store data that is exclusively used by the device. This type of memory should be preferred as it will offer the best performance for the application, as it provides the fastest type of memory available.
  • The memory type VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT is recommended when allocating buffers used to upload data to the graphics device. This memory type should always be preferred when implementing staging buffers, which is the optimal method for passing data to the graphics device. The memory allocation should avoid the flags DEVICE_LOCAL, HOST_COHERENT and HOST_CACHED when using this memory type for staging buffers.
  • The memory type VK_MEMORY_PROPERTY_HOST_COHERENT_BIT is recommended when allocating buffers used to update per frame data, such as uniform buffers. This will provide the optimal memory type available for performing coherent data transfers between the CPU and graphics hardware.
Note: The PowerVR driver does not currently support host cached coherent memory types, but this is subject to change in future driver releases.
Note: All current PowerVR based platforms use Unified Memory Architecture (UMA), meaning that memory types are less critical than on a system employing a Discrete Memory Architecture (DMA). Buffers may be left mapped without negatively impacting performance.

Recommended frequency of allocation

Vulkan provides the function vkAllocateMemory to allocate memory objects. On PowerVR hardware, the function vkAllocateMemory should be called as infrequently as possible. Memory allocations should be in the tens of megabytes at a time, and ideally called during initialisation. If the application requires finer-grained allocations, then it should implement its own memory sub-allocation.