Tag: vulkan

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

Pages: 1

Jul 2017

Vulkan Memory Allocator - a library on GPUOpen & GitHub

Vulkan is hard. One of the difficulties is the responsibility of a developer to manually manage GPU memory. Various GPU vendors expose various set of memory heaps and types and you need to choose right ones. It is also recommended to allocate larger memory blocks and assign parts of them to individual buffers and images. Now there is a library that simplifies these tasks - a one that I developed as part of my job duties. It has just been announced on GPUOpen blog and published on GitHub:

It is a single-header C++ library with a simple C Vulkan-style interface documented using Doxygen-style comments. It is available on MIT license.

Comments (0) | Tags: graphics vulkan | Author: Adam Sawicki | Share

May 2017

Vulkan Bits and Pieces: Synchronization in a Frame

One of the things that you must implement when using Vulkan is basic structure of a rendering frame, which consists of filling a command buffer, submitting it to a command queue, acquiring image from swap chain and finally presenting it (order not preserved here). Things happen in parallel, as GPU works asynchronously to the CPU, so you must explicitly synchronize all these things. In this post I’d like to present basic structure of the rendering frame, with all necessary synchronization.

There are actually two objects that we must take care of simultaneously. First is command buffer. One time it is being filled on the CPU by using vkBeginCommandBuffer, vkEndCommandBuffer and everything in between (like starting render passes and posting all the vkCmd* commands). Another time (after being submitted to a queue using vkQueueSubmit) it waits for execution or it is being executed on the GPU. These things cannot happen at the same time, so we need synchronization. Because it’s a GPU-to-CPU synchronization, we use fence for that. It’s better to have multiple command buffers and all these synchronization objects, stored in array and used in a round-robin fashion (with help of index variable) because this way one can be filled while the other one is consumed at the same time.

Second object is an image acquired from the swapchain. One time it is being rendered to during command buffer execution. Another time it is presented on the screen. Again, we need to synchronize it so these states happen in a sequence. Because it’s a GPU-to-GPU synchronization, we use semaphores for that. There are multiple images as well because swapchain consists of several of them (not necessarily used in round-robin fashion, we need to obtain index of a new image using vkAcquireNextImageKHR function, so there is separate imageIndex).

Having following objects already initialized:

VkDevice g_Device;
VkQueue g_GraphicsQueue;
VkSwapchainKHR g_Swapchain;
VkImageView g_SwapchainImageViews[MAX_SWAPCHAIN_IMAGES];

const uint32_t COUNT = 2;
uint32_t g_NextIndex = 0;
VkCommandBuffer g_CmdBuf[COUNT];
VkFence g_CmdBufExecutedFences[COUNT]; // Create with VK_FENCE_CREATE_SIGNALED_BIT.
VkSemaphore g_ImageAvailableSemaphores[COUNT];
VkSemaphore g_RenderFinishedSemaphores[COUNT];

Structure of a frame may look like this:

uint32_t index = (g_NextIndex++) % COUNT;
VkCommandBuffer cmdBuf = g_CmdBuf[index];

vkWaitForFences(g_Device, 1, &g_CmdBufExecutedFences[index], VK_TRUE, UINT64_MAX);

VkCommandBufferBeginInfo cmdBufBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
vkBeginCommandBuffer(cmdBuf, &cmdBufBeginInfo);

// Post some rendering commands to cmdBuf.

uint32_t imageIndex;
vkAcquireNextImageKHR(g_Device, g_Swapchain, UINT64_MAX, g_ImageAvailableSemaphores[index], VK_NULL_HANDLE, &imageIndex);

// Post those rendering commands that render to final backbuffer:
// g_SwapchainImageViews[imageIndex]


vkResetFences(g_Device, 1, &g_CmdBufExecutedFences[index]);

VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = &g_ImageAvailableSemaphores[index];
submitInfo.pWaitDstStageMask = &submitWaitStage;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &cmdBuf;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &g_RenderFinishedSemaphores[index];
vkQueueSubmit(g_GraphicsQueue, 1, &submitInfo, g_CmdBufExecutedFences[index]);

presentInfo.waitSemaphoreCount = 1;
presentInfo.pWaitSemaphores = &g_RenderFinishedSemaphores[index];
presentInfo.swapChainCount = 1;
presentInfo.pSwapchains = &g_Swapchain;
presentInfo.pImageIndices = &imageIndex;
vkQueuePresentKHR(g_GraphicsQueue, &presentInfo);

At least that’s what I currently believe is the correct and efficient way. If you think I’m wrong, please leave a comment or write me an e-mail.

That’s just one aspect of using Vulkan. There are still more things to do before you can even render your first triangle, like transitioning swapchain image layout between VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL and VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.

Comments (0) | Tags: vulkan graphics | Author: Adam Sawicki | Share

Apr 2017

Vulkan Bits and Pieces: Writing to an Attachment

One of the reasons why new generation graphics APIs (DirectX 12 and Vulkan) are so complicated, is that they have so many levels of indirection in referring to anything. For example, when you render pixels to a color attachment (also known as “render target” in other APIs), the path is as follows:

  1. GLSL fragment shader writes to a variable with some NAME, e.g. “outColor”:
    outColor = vec4(1.0, 0.0, 0.0, 1.0);
  2. The variable is defined earlier in this shader as output and bound to a specific LOCATION, e.g. number 0:
    layout(location = 0) out vec4 outColor;
  3. Switching to C/C++ code, this location is actually index to array pointed by VkSubpassDescription::​pColorAttachments - member of the structure that describes rendering subpass.
  4. Each element of this array in its member VkAttachmentReference::​attachment provides another INDEX, this time to an array pointed by VkRenderPassCreateInfo::​pAttachments - member of the structure that describes rendering pass.
  5. Elements of this array of type VkAttachmentDescription provide just few parameters, like format.
  6. But this index also refers to elements of array pointed by VkFramebufferCreateInfo::​pAttachments - member of a structure filled when creating a framebuffer that is going to be pointed by VkRenderPassBeginInfo::​framebuffer when starting actual execution of the render pass.
  7. Rest is business as usual. Elements of this array are of type VkImageView, so each of them is a VIEW to an image, pointed by VkImageViewCreateInfo::​image - member of a structure used when creating the view.
  8. The IMAGE (type VkImage) is either obtained from swap chain using function vkGetSwapchainImagesKHR, or created manually using function vkCreateImage.
  9. In the latter case, you must also allocate MEMORY (type VkDeviceMemory) with function vkAllocateMemory and bind its fragment to the image using function vkBindImageMemory. This is the memory that will be actually written.

Yeah, Vuklan is hard…

Comments (0) | Tags: vulkan graphics | Author: Adam Sawicki | Share

Feb 2016

Vulkan 1.0 Released!

Yesterday (2016-02-16) was a big day - Vulkan 1.0 has finally been released. The new 3D graphics and compute API from Khronos Group has a chance to be the solution long awaited in the PC world that will:

Time will tell whether Vulkan becomes popular, common standard. It's not so certain. Microsoft promotes its own Direct3D 12, Apple has its Metal API, NVIDIA develops CUDA, old OpenGL and OpenCL are here to stay. What hardware versions and software platforms will eventually support the new API? What will be the quality and performance of those drivers? Will some good debugging and performance probiling tools become available? Will game developers and game engine developers port their code any time soon? What the reception will be among video/media, CAD/CAM, HPC professionals? I'm very enthusiastic, seeing so many learning materials and code samples available since day one! Just look at #Vulkan and #VulkanAPI hashtags on Twitter.

Some useful links to start with:

Comments (1) | Tags: gpu vulkan | Author: Adam Sawicki | Share

Pages: 1

STAT NO AD [Stat] [Admin] [STAT NO AD] [pub] [Mirror] Copyright © 2004-2017 Adam Sawicki
Copyright © 2004-2017 Adam Sawicki