Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Surface format is B8G8R8A8_UNORM, but vkCmdClearColorImage takes float?

Tags:

vulkan

I use vkGetPhysicalDeviceSurfaceFormatsKHR to get supported image formats for the swapchain, and (on Linux+Nvidia, using SDL) I get VK_FORMAT_B8G8R8A8_UNORM as the first option and I go ahead and create the swapchain with that format:

VkSwapchainCreateInfoKHR swapchain_info = {
    ...
    .imageFormat = format, /* taken from vkGetPhysicalDeviceSurfaceFormatsKHR */
    ...
};

So far, it all makes sense. The image format used to draw on the screen is the usual 8-bits-per-channel BGRA.

As part of my learning process, I have so far arrived at setting up a lot of stuff but not yet the graphics pipeline1. So I am trying the only command I can use that doesn't need a pipeline: vkCmdClearColorImage2.

The VkClearColorValue used to define the clear color can take the color as float, uint32_t or int32_t, depending on the format of the image. I would have expected, based on the image format given to the swapchain, that I should give it uint32_t values, but that doesn't seem to be correct. I know because the screen color didn't change. I tried giving it floats and it works.

My question is, why does the clear color need to be specified in floats when the image format is VK_FORMAT_B8G8R8A8_UNORM?


1Actually I have, but thought I would try out the simpler case of no pipeline first. I'm trying to incrementally use Vulkan (given its verbosity) particularly because I'm also writing tutorials on it as I learn.

2Actually, it technically doesn't need a render pass, but I figured hey, I'm not using any pipeline stuff here, so let's try it without a pipeline and it worked.


My rendering loop is essentially the following:

  • acquire image from swapchain
  • create a command buffer with the following:
    • transition from VK_IMAGE_LAYOUT_UNDEFINED to VK_IMAGE_LAYOUT_GENERAL (because I'm clearing the image outside a render pass)
    • clear the image
    • transition from VK_IMAGE_LAYOUT_GENERAL to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
  • submit command buffer to queue (taking care of synchronization with swapchain with semaphores)
  • submit for presentation
like image 411
Shahbaz Avatar asked May 06 '16 02:05

Shahbaz


1 Answers

My question is, why does the clear color need to be specified in floats when the image format is VK_FORMAT_B8G8R8A8_UNORM?

Because the normalized, scaled, or sRGB image formats are really just various forms of floating-point compression. A normalized integer is a way of storing floating-point values on the range [0, 1] or [-1, 1], but using a much smaller amount of data than even a 16-bit float. A scaled integer is a way of storing floating point values on the range [0, MAX] or [-MIN, MAX]. And sRGB is just a compressed way of storing linear color values on the range [0, 1], but in a gamma-corrected color space that puts precision in different places than the linear color values would suggest.

You see the same things with inputs to the vertex shader. A vec4 input type can be fed by normalized formats just as well as by floating-point formats.

like image 183
Nicol Bolas Avatar answered Oct 02 '22 23:10

Nicol Bolas