Tag: vulkan

Entries for tag "vulkan", ordered from most recent. Entry count: 27.

Pages: > 1 2 3 4 >

# Vulkan with DXGI - experiment results

Mon
19
Nov 2018

In my previous post, I’ve described a way to get GPU memory usage in Windows Vulkan app by using DXGI. This API, designed for Direct3D, seems to work with Vulkan as well. In this post I would like to share detailed results of my experiment on two different platforms with two graphics cards from different vendors. But before that, a disclaimer:

Read full entry > | Comments | #windows #graphics #directx #vulkan Share

# There is a way to query GPU memory usage in Vulkan - use DXGI

Thu
15
Nov 2018

In my GDC 2018 talk “Memory management in Vulkan and DX12” (slides freely available, video behind GDC Vault paywall) I said that in Direct3D 12 you can query for the exact amount of GPU memory used and available, while in Vulkan there is no way to do that, so I recommend to just query for memory capacity (VkMemoryHeap::​size) and limit your usage to around 80% of it. It turns out that I wasn’t quite right. If you code for Windows, there is a way to do this. I assumed that the mentioned function IDXGIAdapter3::​QueryVideoMemoryInfo is part of Direct3D 12 interface, while it is actually part of DirectX Graphics Infrastructure (DXGI). This is a more generic, higher level Windows API that allows you to enumerate adapters (graphics cards) installed in the system, query for their parameters and outputs (monitors) connected to them. Direct3D refers to this API, but it’s not the same.

Key question is: Can you use DXGI to query for GPU memory usage while doing graphics using Vulkan, not D3D11 or D3D12? Would it return some reasonable data and not all zeros? Short answer is: YES! I’ve made an experiment - I wrote a simple app that creates various Vulkan objects and queries DXGI for memory usage. Results look very promising. But before I move on to the details, here is a short primer of how to use this DXGI interface, for all non-DirectX developers:

1. Use C++ in Visual Studio. You may also use some other compiler for Windows or other programming language, but it will be probably harder to setup.

2. Install relatively new Windows SDK.

3. #include <dxgi1_4.h> and <atlbase.h>

4. Link with “dxgi.lib”.

5. Create Factory object:

IDXGIFactory4* dxgiFactory = nullptr;
CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));

Don’t forget to release it at the end:

dxgiFactory->Release();

6. Write a loop to enumerate available adapters. Choose and remember suitable one.

IDXGIAdapter3* dxgiAdapter = nullptr;
IDXGIAdapter1* tmpDxgiAdapter = nullptr;
UINT adapterIndex = 0;
while(m_DxgiFactory->EnumAdapters1(adapterIndex, &tmpDxgiAdapter) != DXGI_ERROR_NOT_FOUND)
{
    DXGI_ADAPTER_DESC1 desc;
    tmpDxgiAdapter>GetDesc1(&desc);
    if(!dxgiAdapter && desc.Flags == 0)
    {
        tmpDxgiAdapter->QueryInterface(IID_PPV_ARGS(&dxgiAdapter));
    }
    tmpDxgiAdapter->Release();
    ++adapterIndex;
}

At the end, don’t forget to release it:

dxgiAdapter->Release();

Please note that using new version of DXGI interfaces like DXGIFactory4 and DXGIAdapter3 requires some relatively new version (I’m not sure which one) of both Windows SDK on developer’s side (otherwise it won’t compile) and updated Windows system on user’s side (otherwise function calls with fail with appropriate returned HRESULT).

7. To query for GPU memory usage at the moment, use this code:

DXGI_QUERY_VIDEO_MEMORY_INFO info = {};
dxgiAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_LOCAL, &info);

There are two possible options:

Among members of the returned structure, the most interesting is CurrentUsage. It seems to precisely reflect the use of GPU memory - it increases when I allocate a new VkDeviceMemory object, as well as when I use some implicit memory by creating other Vulkan resources, like a swap chain, descriptor pools and descriptor sets, command pools and command buffers, query pools etc.

Other DXGI features for video memory - callback for budget change notification (IDXGIAdapter3::​RegisterVideoMemoryBudgetChangeNotificationEvent) and reservation (IDXGIAdapter3::​SetVideoMemoryReservation) may also work with Vulkan, but I didn’t check them.

As an example, on my system with GPU = AMD Radeon RX 580 8 GB and 16 GB of system RAM, on program startup and before any Vulkan or D3D initialization, DXGI reports following data:

Local:
 Budget=7252479180 CurrentUsage=0
 AvailableForReservation=3839547801 CurrentReservation=0
Nonlocal:
 Budget=7699177267 CurrentUsage=0
 AvailableForReservation=4063454668 CurrentReservation=0

8. You may want to choose correct DXGI adapter to match the physical device used in Vulkan. Even on the system with just one discrete GPU there are two adapters reported, one of them being software renderer. I exclude it by comparing desc.Flags == 0, which means this is a real, hardware-accelerated GPU, not DXGI_ADAPTER_FLAG_REMOTE or DXGI_ADAPTER_FLAG_SOFTWARE.

Good news is that even when there are more such adapters in the system, there is a way to match them between DXGI and Vulkan. Both APIs return something called Locally Unique Identifier (LUID). In DXGI it’s in DXGI_ADAPTER_DESC1::​AdapterLuid. In Vulkan it’s in VkPhysicalDeviceIDProperties::​deviceLUID. They are of different types - two 32-bit numbers versus array of bytes, but it seems that simple, raw memory compare works correctly. So the way to find DXGI adapter matching Vulkan physical device is:

// After obtaining VkPhysicalDevice of your choice:
VkPhysicalDeviceIDProperties physDeviceIDProps = {
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES };
VkPhysicalDeviceProperties2 physDeviceProps = {
    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 };
physDeviceProps.pNext = &physDeviceIDProps;
vkGetPhysicalDeviceProperties2(physicalDevice, &physDeviceProps);

// While enumerating DXGI adapters, replace condition:
// if(!dxgiAdapter && desc.Flags == 0)
// With this:
if(memcmp(&desc.AdapterLuid, physDeviceIDProps.deviceLUID, VK_LUID_SIZE) == 0)

Please note that function vkGetPhysicalDeviceProperties2 requires Vulkan 1.1, so set VkApplicationInfo::​apiVersion = VK_API_VERSION_1_1. Otherwise the call results in “Access Violation” error.

In my next blog post, I present detailed results of my experiment with DXGI used with Vulkan application, tested on 2 different GPUs.

Update 2019-03-15: Khronos released Vulkan extension equivalent to this DXGI functionality: VK_EXT_memory_budget.

Comments | #directx #vulkan #graphics #windows Share

# Vulkan Memory Allocator 2.1.0

Tue
28
Aug 2018

Yesterday I merged changes in the code of Vulkan Memory Allocator that I've been working on for past few months to "master" branch, which I consider a major milestone, so I marked it as version 2.1.0-beta.1. There are many new features, including:

The release also includes many smaller bug fixes, improvements and additions. Everything is tested and documented. Yet I call it "beta" version, to encourage you to test it in your project and send me your feedback.

Comments | #vulkan #libraries #productions #graphics Share

# Porting your engine to Vulkan or DX12 - video from my talk

Fri
06
Jul 2018

Organizers of Digital Dragons conference published video recording of my talk "Porting your engine to Vulkan or DX12":

PowerPoint slides are also available for download here: Porting your engine to Vulkan or DX12 - GPUOpen.

Comments | #vulkan #directx #teaching #events #video Share

# Vulkan layers don't work? Look at registry.

Fri
06
Jul 2018

If you program using Vulkan on Windows and you see that Vulkan layers stopped working (especially after updating graphics driver or Vulkan SDK), first thing to try is to uninstall Vulkan SDK and install it again. Also restart your computer, to be sure that environmental variables are updated. But sometimes it doesn't help or it even makes things worse.

If you are still not able to successfully find and enable VK_LAYER_LUNARG_standard_validation in your code, or you try to enable VK_LAYER_LUNARG_api_dump using environmental variable but can't see it working, or have problem with any other layer, first thing you can try is to issue vulkaninfo console command. If you see some errors about "JSON", it clearly indicates that there is a problem with configuration of Vulkan in your system, regarding paths to layer DLLs and their JSON descriptions.

Either way, the thing I recommend is to launch regedit (Registry Editor) and check values in following keys:

HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\ExplicitLayers
HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\Vulkan\ImplicitLayers

They should contain paths to valid JSON files that describe installed Vulkan layer DLLs. "ExplicitLayers" is the list of layers that can be manually enabled either programatically via VkInstanceCreateInfo::​ppEnabledLayerNames, or via environmental variable VK_INSTANCE_LAYERS. "ImplicitLayers" is the list of layers loaded automatically by each Vulkan app (e.g. one added by Steam or RenderDoc). For further details see article: "Vulkan Validation and Debugging Layers".

It looks that the installer of Vulkan SDK can mess up these registry entries. Yesterday, after uninstalling old SDK and installing new one, I found there entries from both versions. Today, my colleague found these registry keys completely empty. So whenever you have problems with Vulkan layers on Windows, take a look at the registry.

Update 2018-08-27: There is Issue #38 on GitHub - Vulkan-Ecosystem about this.

Comments | #vulkan Share

# Human-friendly classification of Vulkan resources

Wed
06
Jun 2018

In graphics programming we deal with different kinds of resources. Their specific types and names depend on graphics API. For example, in Direct3D 9 we have vertex buffers, index buffers, constant buffers, textures etc. OpenGL equivalent of constant buffer is uniform buffer object (UBO).

Vulkan has only two types of resources: buffers and images. This may be the only thing that is simpler in Vulkan than in other APIs :) When creating such resource, we specify usage flags that define how do we intend to use it. For example, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT means that a buffer may be used as vertex buffer. VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT means that an image may be used as color attachment (which is Vulkan name for “render target”).

Such flags may be combined together, so a single buffer can contain data to be used as vertex buffer, index buffer, and uniform buffer. I’m not 100% sure if this is guaranteed by the specification (theoretically some drivers could return disjoint sets of VkMemoryRequirements::memoryTypeBits for different usage flags), but I think that every real implementation allows that. It means we cannot clearly classify buffers and images into categories. Despite that, I decided to develop a human-friendly classification of Vulkan resources into several categories, starting from most “special”, and ending with most “common/generic” ones. I propose following algorithm:

For buffers:
  // Buffer is used as source of data for fixed-function stage of graphics pipeline.
  // It’s indirect, vertex, or index buffer.
  if ((usage & (VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT |
    VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
    VK_BUFFER_USAGE_INDEX_BUFFER_BIT)) != 0)
    return class0;
  // Buffer is accessed by shaders for load/store/atomic.
  // Aka “UAV”
  else if ((usage & (VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
    VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) != 0)
    return class1;
  // Buffer is accessed by shaders for reading uniform data.
  // Aka “constant buffer”
  else if ((usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT |
    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) != 0)
    return class2;
  // Any other type of buffer.
  // Notice that VK_BUFFER_USAGE_TRANSFER_SRC_BIT and VK_BUFFER_USAGE_TRANSFER_DST_BIT
  // flags are intentionally ignored.
  else
    return class3;

For images:
  // Image is used as depth/stencil “texture/surface”.
  if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
    return class0;
  // Image is used as other type of attachment.
  // Aka “render target”
  else if ((usage & (VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)) != 0)
    return class1;
  // Image is accessed by shaders for sampling.
  // Aka “texture”
  else if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0)
    return class2;
  // Any other type of image.
  // Notice that VK_IMAGE_USAGE_TRANSFER_SRC_BIT and VK_IMAGE_USAGE_TRANSFER_DST_BIT
  // flags are intentionally ignored.
  else
    return class3;

I needed this because I wanted to introduce better coloring to VMA Dump Vis. Vulkan Memory Allocator (VMA) is a C++ library that simplifies GPU memory management in Vulkan applications. VMA Dump Vis is a Python script that can visualize JSON dump from this library on a picture. As I updated the library to remember usage flags of created resources, I wanted to use them to show more information on the picture. To do this, I defined following color scheme:

Example visualization of Vulkan memory in some game:

This color scheme is carefully designed. I based it on following principles:

  1. Brightness: Details too small to be shown as filled rectangles are black. Borders of rectangles representing allocations are dark gray. Fill colors of all allocations must be visually brighter than this.
  2. Saturation: Memory of unknown purpose (small details, free space, allocation of unknown type) is black/gray. Allocations of known type have specific color. Additionally, buffers and images with no special usage flags use more desaturated (brighter) color.
  3. Warm/cool colors: Buffers use warm colors: red, orange, yellow. Images use cool colors: purple, blue etc.
  4. Hue (1): Classes of buffers, from most special to most generic, use colors from red, through orange, to yellow. Classes of images, from most special to most generic, use colors from purple, through violet, to cyan.
  5. Hue (2): Vulkan images with VK_IMAGE_TILING_OPTIMAL should be used wherever possible, so those with VK_IMAGE_TILING_LINEAR are just marked with green. Images of unknown tiling have color between cyan and green.

You can already visualize your Vulkan memory with all these colors if you grab Vulkan Memory Allocator from development branch. I think that this classification of GPU resources and accompanying color scheme could also be useful for other graphics APIs.

Comments | #productions #libraries #vulkan Share

# Vulkan API - my talk at Warsaw University of Technology

Mon
16
Apr 2018

On Wednesday 16 April, around 8 PM, at Warsaw University of Technology, during weekly meeting of KNTG Polygon, I will give a talk about "Vulkan API" (in Polish). Come if you want to hear about new generation of graphics APIs, see how Vulkan API looks like, what tools are there to support it, what are advantages and disadvantages of using such API and finally decide whethere learning Vulkan is a good idea for you.

Event on Facebook: https://www.facebook.com/events/185314825611839/

Slides:
Vulkan API.pdf
Vulkan API.pptx

Comments | #graphics #gpu #vulkan #teaching Share

# Memory management in Vulkan and DX12: slides are online

Tue
03
Apr 2018

Slides from my talk at Game Developers Conference (GDC) 2018: "Memory management in Vulkan and DX12" are now available online, as part of materials from Advanced Graphics Techniques Tutorial. Access to this PDF is open to anyone, not behind GDC Vault paywall. I've put some additional information in "backup" slides at the end that I didn't show during my presentation. The slides are designed the way that you can learn from them even without seeing the talk.

Update 2018-05-04: Slides from my talk in PPTX format with additional notes are now available (together with many other GDC 2018 presentations) on page: GDC 2018 Presentations - GPUOpen.

Comments | #events #teaching #gdc #directx #vulkan Share

Pages: > 1 2 3 4 >

[Download] [Dropbox] [pub] [Mirror] [Privacy policy]
Copyright © 2004-2020