When creating my swapchain, using vkCreateSwapchainKHR
(actually I am using the C++ interface, but it seems that all communication is done using the C API) I pass a pointer to a VkSwapchainCreateInfoKHR
that has a member imageFormat
described by the specs as “imageFormat is a VkFormat value specifying the format the swapchain image(s) will be created with.”
There are over 100 formats to choose from.
Looking at tutorials and examples.
“Because of that we should also use an SRGB color format, of which one of the most common ones is VK_FORMAT_B8G8R8A8_SRGB.”
with code
for (const auto& availableFormat : availableFormats) {
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
return availableFormat;
}
}
In other words, they prefer VK_FORMAT_B8G8R8A8_SRGB
.
This page does not talk about swapchain formats, but their code can be found here:
with code:
vk::SurfaceFormatKHR VulkanCommon::GetSwapChainFormat( std::vector<vk::SurfaceFormatKHR> const & surface_formats ) const {
// If the list contains only one entry with undefined format
// it means that there are no preferred surface formats and any can be chosen
if( (surface_formats.size() == 1) &&
(surface_formats[0].format == vk::Format::eUndefined) ) {
return { vk::Format::eR8G8B8A8Unorm, vk::ColorSpaceKHR::eSrgbNonlinear };
}
// Check if list contains most widely used R8 G8 B8 A8 format
// with nonlinear color space
for( auto & surface_format : surface_formats ) {
if( surface_format.format == vk::Format::eR8G8B8A8Unorm ) {
return surface_format;
}
}
// Return the first format from the list
return surface_formats[0];
}
So clearly they prefer vk::Format::eR8G8B8A8Unorm
, aka VK_FORMAT_R8G8B8A8_UNORM
.
- vkguidedev which uses vkBootstrap (http://github.com/charles-lunarg/vk-bootstrap/blob/master/README.md)
Uses the code
void SwapchainBuilder::add_desired_formats(std::vector<VkSurfaceFormatKHR>& formats) const {
formats.push_back({ VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
formats.push_back({ VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
}
So, they prefer VK_FORMAT_R8G8B8A8_SRGB
(assuming that doesn’t swap Red and Blue ;).
Has a C++ example,
with the code:
// There is no preferred format, so pick a default one|
format = formats[0];|
format.format = VK_FORMAT_B8G8R8A8_UNORM;|
[...]
for (auto &candidate : formats)
{
switch (candidate.format)
{
case VK_FORMAT_R8G8B8A8_UNORM:
case VK_FORMAT_B8G8R8A8_UNORM:
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
format = candidate;
break;
default:
break;
In other words, they prefer VK_FORMAT_R8G8B8A8_UNORM
.
I know what the difference is between SRGB and UNORM, and I read
but the answer wasn’t very clear to me.
Even ignoring that there are close to 200 formats to choose from, apparently even tutorials and examples have a hard time to choose between srgb and unorm for the swapchain they create.
I am willing to assume that my images are encoded using srgb and that my surface (I am using XCB) uses srgb, but I don’t want a conversion, ever, between R8G8B8A8_SRGB
and R8G8B8A8_UNORM
for obvious reasons (that would throw away information and you’d get the worst of both worlds). Nevertheless, I am assuming that an image has to be converted to something linear at some point in order to do math, like blending.
I also discussed this on discord and it was said that the linear form in this case uses 32bit floats per channel; is this correct? That would be 128bits per texel, four times the size of an image as handled in the host as far as I can see. Are images processed at that size internally on hardware?
I am totally confused on what is ACTUALLY going on, how to get both speed and no loss of data; and why there is a difference in what examples/tutorials use even.
If I add to this the general case - what code should I write to pick the correct format for my swapchain from the 100+ existing ones? Of course, most will not even be supported by my hardware; but as soon as SOME are I need a strategy to make a good pick.
Hopefully someone can explain in detail what is going on and therefore how to pick the right format.
PS I spent 1.5 hours typing in this question, then hit Enter and get: “Sorry you can’t use links in your post.” I now removed all h…p / / prefixes. Hopefully at least it will let me post this.
PS Still not allowed… so I removed all links. THIS SUCKS.