Skip to content

Commit 92fc80e

Browse files
committed
Add more color spaces.
1 parent b4228b6 commit 92fc80e

File tree

2 files changed

+59
-13
lines changed

2 files changed

+59
-13
lines changed

vulkan/wsi.cpp

+56-12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define NOMINMAX
2424
#include "wsi.hpp"
2525
#include "environment.hpp"
26+
#include <algorithm>
2627

2728
#if defined(ANDROID) && defined(HAVE_SWAPPY)
2829
#include "swappy/swappyVk.h"
@@ -65,8 +66,11 @@ WSI::WSI()
6566
void WSI::set_hdr_metadata(const VkHdrMetadataEXT &hdr)
6667
{
6768
hdr_metadata = hdr;
68-
if (swapchain && swapchain_surface_format.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT)
69+
if (swapchain && swapchain_surface_format.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT &&
70+
device->get_device_features().supports_hdr_metadata)
71+
{
6972
table->vkSetHdrMetadataEXT(device->get_device(), 1, &swapchain, &hdr_metadata);
73+
}
7074
}
7175

7276
void WSIPlatform::set_window_title(const std::string &)
@@ -1101,12 +1105,6 @@ VkSurfaceFormatKHR WSI::find_suitable_present_format(const std::vector<VkSurface
11011105
size_t format_count = formats.size();
11021106
VkSurfaceFormatKHR format = { VK_FORMAT_UNDEFINED };
11031107

1104-
if (desired_format == BackbufferFormat::HDR10 && !device->get_device_features().supports_hdr_metadata)
1105-
{
1106-
LOGW("VK_EXT_hdr_metadata is not supported, ignoring HDR10.\n");
1107-
return format;
1108-
}
1109-
11101108
VkFormatFeatureFlags features = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
11111109
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
11121110
if ((current_extra_usage & VK_IMAGE_USAGE_STORAGE_BIT) != 0)
@@ -1123,7 +1121,29 @@ VkSurfaceFormatKHR WSI::find_suitable_present_format(const std::vector<VkSurface
11231121
if (!device->image_format_is_supported(formats[i].format, features))
11241122
continue;
11251123

1126-
if (desired_format == BackbufferFormat::HDR10)
1124+
if (desired_format == BackbufferFormat::DisplayP3)
1125+
{
1126+
if (formats[i].colorSpace == VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT &&
1127+
(formats[i].format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
1128+
formats[i].format == VK_FORMAT_A2R10G10B10_UNORM_PACK32))
1129+
{
1130+
format = formats[i];
1131+
break;
1132+
}
1133+
}
1134+
else if (desired_format == BackbufferFormat::UNORMPassthrough)
1135+
{
1136+
if (formats[i].colorSpace == VK_COLOR_SPACE_PASS_THROUGH_EXT &&
1137+
(formats[i].format == VK_FORMAT_R8G8B8A8_UNORM ||
1138+
formats[i].format == VK_FORMAT_B8G8R8A8_UNORM ||
1139+
formats[i].format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
1140+
formats[i].format == VK_FORMAT_A2R10G10B10_UNORM_PACK32))
1141+
{
1142+
format = formats[i];
1143+
break;
1144+
}
1145+
}
1146+
else if (desired_format == BackbufferFormat::HDR10)
11271147
{
11281148
if (formats[i].colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT &&
11291149
(formats[i].format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
@@ -1149,6 +1169,8 @@ VkSurfaceFormatKHR WSI::find_suitable_present_format(const std::vector<VkSurface
11491169
if (formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR &&
11501170
(formats[i].format == VK_FORMAT_R8G8B8A8_UNORM ||
11511171
formats[i].format == VK_FORMAT_B8G8R8A8_UNORM ||
1172+
formats[i].format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
1173+
formats[i].format == VK_FORMAT_A2R10G10B10_UNORM_PACK32 ||
11521174
formats[i].format == VK_FORMAT_A8B8G8R8_UNORM_PACK32))
11531175
{
11541176
format = formats[i];
@@ -1417,6 +1439,22 @@ static bool init_surface_info(Device &device, WSIPlatform &platform,
14171439
return false;
14181440
}
14191441

1442+
// Ensure that 10-bit formats come before other formats.
1443+
std::sort(info.formats.begin(), info.formats.end(), [](const VkSurfaceFormatKHR &a, const VkSurfaceFormatKHR &b) {
1444+
const auto qual = [](VkFormat fmt) {
1445+
// Prefer a consistent ordering so Fossilize caches are more effective.
1446+
if (fmt == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
1447+
return 3;
1448+
else if (fmt == VK_FORMAT_A2R10G10B10_UNORM_PACK32)
1449+
return 2;
1450+
else if (fmt == VK_FORMAT_B8G8R8A8_UNORM)
1451+
return 1;
1452+
else
1453+
return 0;
1454+
};
1455+
return qual(a.format) > qual(b.format);
1456+
});
1457+
14201458
// Allow for seamless toggle between presentation modes.
14211459
if (ext.swapchain_maintenance1_features.swapchainMaintenance1)
14221460
{
@@ -1459,10 +1497,13 @@ WSI::SwapchainError WSI::init_swapchain(unsigned width, unsigned height)
14591497
auto attempt_backbuffer_format = current_backbuffer_format;
14601498
auto surface_format = find_suitable_present_format(surface_info.formats, attempt_backbuffer_format);
14611499

1462-
if (surface_format.format == VK_FORMAT_UNDEFINED && attempt_backbuffer_format == BackbufferFormat::HDR10)
1500+
if (surface_format.format == VK_FORMAT_UNDEFINED &&
1501+
(attempt_backbuffer_format == BackbufferFormat::HDR10 ||
1502+
attempt_backbuffer_format == BackbufferFormat::DisplayP3 ||
1503+
attempt_backbuffer_format == BackbufferFormat::UNORMPassthrough))
14631504
{
1464-
LOGW("Could not find suitable present format for HDR10. Attempting fallback to sRGB.\n");
1465-
attempt_backbuffer_format = BackbufferFormat::sRGB;
1505+
LOGW("Could not find suitable present format for HDR. Attempting fallback to UNORM.\n");
1506+
attempt_backbuffer_format = BackbufferFormat::UNORM;
14661507
surface_format = find_suitable_present_format(surface_info.formats, attempt_backbuffer_format);
14671508
}
14681509

@@ -1673,8 +1714,11 @@ WSI::SwapchainError WSI::init_swapchain(unsigned width, unsigned height)
16731714
swapchain_surface_format.colorSpace,
16741715
swapchain_current_prerotate);
16751716

1676-
if (swapchain_surface_format.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT)
1717+
if (swapchain_surface_format.colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT &&
1718+
device->get_device_features().supports_hdr_metadata)
1719+
{
16771720
table->vkSetHdrMetadataEXT(device->get_device(), 1, &swapchain, &hdr_metadata);
1721+
}
16781722

16791723
return SwapchainError::None;
16801724
}

vulkan/wsi.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ enum class BackbufferFormat
155155
{
156156
UNORM,
157157
sRGB,
158-
HDR10
158+
HDR10,
159+
DisplayP3,
160+
UNORMPassthrough
159161
};
160162

161163
class WSI

0 commit comments

Comments
 (0)