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: vkCmdClearColorImage
2.
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 float
s and it works.
My question is, why does the clear color need to be specified in float
s 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:
VK_IMAGE_LAYOUT_UNDEFINED
to VK_IMAGE_LAYOUT_GENERAL
(because I'm clearing the image outside a render pass)VK_IMAGE_LAYOUT_GENERAL
to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With