23
23
#define NOMINMAX
24
24
#include " wsi.hpp"
25
25
#include " environment.hpp"
26
+ #include < algorithm>
26
27
27
28
#if defined(ANDROID) && defined(HAVE_SWAPPY)
28
29
#include " swappy/swappyVk.h"
@@ -65,8 +66,11 @@ WSI::WSI()
65
66
void WSI::set_hdr_metadata (const VkHdrMetadataEXT &hdr)
66
67
{
67
68
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
+ {
69
72
table->vkSetHdrMetadataEXT (device->get_device (), 1 , &swapchain, &hdr_metadata);
73
+ }
70
74
}
71
75
72
76
void WSIPlatform::set_window_title (const std::string &)
@@ -1101,12 +1105,6 @@ VkSurfaceFormatKHR WSI::find_suitable_present_format(const std::vector<VkSurface
1101
1105
size_t format_count = formats.size ();
1102
1106
VkSurfaceFormatKHR format = { VK_FORMAT_UNDEFINED };
1103
1107
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
-
1110
1108
VkFormatFeatureFlags features = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
1111
1109
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
1112
1110
if ((current_extra_usage & VK_IMAGE_USAGE_STORAGE_BIT) != 0 )
@@ -1123,7 +1121,29 @@ VkSurfaceFormatKHR WSI::find_suitable_present_format(const std::vector<VkSurface
1123
1121
if (!device->image_format_is_supported (formats[i].format , features))
1124
1122
continue ;
1125
1123
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)
1127
1147
{
1128
1148
if (formats[i].colorSpace == VK_COLOR_SPACE_HDR10_ST2084_EXT &&
1129
1149
(formats[i].format == VK_FORMAT_A2B10G10R10_UNORM_PACK32 ||
@@ -1149,6 +1169,8 @@ VkSurfaceFormatKHR WSI::find_suitable_present_format(const std::vector<VkSurface
1149
1169
if (formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR &&
1150
1170
(formats[i].format == VK_FORMAT_R8G8B8A8_UNORM ||
1151
1171
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 ||
1152
1174
formats[i].format == VK_FORMAT_A8B8G8R8_UNORM_PACK32))
1153
1175
{
1154
1176
format = formats[i];
@@ -1417,6 +1439,22 @@ static bool init_surface_info(Device &device, WSIPlatform &platform,
1417
1439
return false ;
1418
1440
}
1419
1441
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
+
1420
1458
// Allow for seamless toggle between presentation modes.
1421
1459
if (ext.swapchain_maintenance1_features .swapchainMaintenance1 )
1422
1460
{
@@ -1459,10 +1497,13 @@ WSI::SwapchainError WSI::init_swapchain(unsigned width, unsigned height)
1459
1497
auto attempt_backbuffer_format = current_backbuffer_format;
1460
1498
auto surface_format = find_suitable_present_format (surface_info.formats , attempt_backbuffer_format);
1461
1499
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))
1463
1504
{
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 ;
1466
1507
surface_format = find_suitable_present_format (surface_info.formats , attempt_backbuffer_format);
1467
1508
}
1468
1509
@@ -1673,8 +1714,11 @@ WSI::SwapchainError WSI::init_swapchain(unsigned width, unsigned height)
1673
1714
swapchain_surface_format.colorSpace ,
1674
1715
swapchain_current_prerotate);
1675
1716
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
+ {
1677
1720
table->vkSetHdrMetadataEXT (device->get_device (), 1 , &swapchain, &hdr_metadata);
1721
+ }
1678
1722
1679
1723
return SwapchainError::None;
1680
1724
}
0 commit comments