Use Surface::GetWideColorSupport in VK_EXT_swapchain_colorspace
Use the newly added Surface::GetWideColorSupport to
add wide color SurfaceFormats when appropriate.
Test: compile Vulkan CTS test TBD
Change-Id: I85dbe9617b8eba8b89c3ad788d5ffc9f0d66f935
diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h
index 43dba6e..36f5ace 100644
--- a/vulkan/include/vulkan/vulkan.h
+++ b/vulkan/include/vulkan/vulkan.h
@@ -4606,6 +4606,10 @@
VkPastPresentationTimingGOOGLE* pPresentationTimings);
#endif
+#define VK_EXT_swapchain_colorspace 1
+#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 1
+#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace"
+
#define VK_EXT_hdr_metadata 1
#define VK_EXT_HDR_METADATA_SPEC_VERSION 0
#define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata"
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index 4835a56..992c5d1 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -683,12 +683,13 @@
VK_ANDROID_native_buffer
VK_EXT_debug_report
VK_EXT_hdr_metadata
+VK_EXT_swapchain_colorspace
VK_GOOGLE_display_timing
VK_KHR_android_surface
VK_KHR_incremental_present
+VK_KHR_shared_presentable_image
VK_KHR_surface
VK_KHR_swapchain
-VK_KHR_shared_presentable_image
{{end}}
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 76aa176..351caeb 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -447,6 +447,7 @@
switch (ext_bit) {
case ProcHook::KHR_android_surface:
case ProcHook::KHR_surface:
+ case ProcHook::EXT_swapchain_colorspace:
hook_extensions_.set(ext_bit);
// return now as these extensions do not require HAL support
return;
@@ -673,11 +674,13 @@
const char* pLayerName,
uint32_t* pPropertyCount,
VkExtensionProperties* pProperties) {
- static const std::array<VkExtensionProperties, 2> loader_extensions = {{
+ static const std::array<VkExtensionProperties, 3> loader_extensions = {{
// WSI extensions
{VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_SPEC_VERSION},
{VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
VK_KHR_ANDROID_SURFACE_SPEC_VERSION},
+ {VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
+ VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION},
}};
static const VkExtensionProperties loader_debug_report_extension = {
VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION,
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index c4cb544..fc3f87a 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -365,12 +365,13 @@
if (strcmp(name, "VK_ANDROID_native_buffer") == 0) return ProcHook::ANDROID_native_buffer;
if (strcmp(name, "VK_EXT_debug_report") == 0) return ProcHook::EXT_debug_report;
if (strcmp(name, "VK_EXT_hdr_metadata") == 0) return ProcHook::EXT_hdr_metadata;
+ if (strcmp(name, "VK_EXT_swapchain_colorspace") == 0) return ProcHook::EXT_swapchain_colorspace;
if (strcmp(name, "VK_GOOGLE_display_timing") == 0) return ProcHook::GOOGLE_display_timing;
if (strcmp(name, "VK_KHR_android_surface") == 0) return ProcHook::KHR_android_surface;
if (strcmp(name, "VK_KHR_incremental_present") == 0) return ProcHook::KHR_incremental_present;
+ if (strcmp(name, "VK_KHR_shared_presentable_image") == 0) return ProcHook::KHR_shared_presentable_image;
if (strcmp(name, "VK_KHR_surface") == 0) return ProcHook::KHR_surface;
if (strcmp(name, "VK_KHR_swapchain") == 0) return ProcHook::KHR_swapchain;
- if (strcmp(name, "VK_KHR_shared_presentable_image") == 0) return ProcHook::KHR_shared_presentable_image;
if (strcmp(name, "VK_KHR_get_physical_device_properties2") == 0) return ProcHook::KHR_get_physical_device_properties2;
// clang-format on
return ProcHook::EXTENSION_UNKNOWN;
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index c9dba78..738da5b 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -36,12 +36,13 @@
ANDROID_native_buffer,
EXT_debug_report,
EXT_hdr_metadata,
+ EXT_swapchain_colorspace,
GOOGLE_display_timing,
KHR_android_surface,
KHR_incremental_present,
+ KHR_shared_presentable_image,
KHR_surface,
KHR_swapchain,
- KHR_shared_presentable_image,
KHR_get_physical_device_properties2,
EXTENSION_CORE, // valid bit
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index e105922..4d6bb30 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -512,10 +512,12 @@
}
VKAPI_ATTR
-VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice /*pdev*/,
- VkSurfaceKHR /*surface*/,
+VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev,
+ VkSurfaceKHR surface_handle,
uint32_t* count,
VkSurfaceFormatKHR* formats) {
+ const InstanceData& instance_data = GetData(pdev);
+
// TODO(jessehall): Fill out the set of supported formats. Longer term, add
// a new gralloc method to query whether a (format, usage) pair is
// supported, and check that for each gralloc format that corresponds to a
@@ -528,15 +530,50 @@
{VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
};
const uint32_t kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
+ uint32_t total_num_formats = kNumFormats;
+
+ bool wide_color_support = false;
+ Surface& surface = *SurfaceFromHandle(surface_handle);
+ int err = native_window_get_wide_color_support(surface.window.get(),
+ &wide_color_support);
+ if (err) {
+ // Not allowed to return a more sensible error code, so do this
+ return VK_ERROR_OUT_OF_HOST_MEMORY;
+ }
+ ALOGV("wide_color_support is: %d", wide_color_support);
+ wide_color_support =
+ wide_color_support &&
+ instance_data.hook_extensions.test(ProcHook::EXT_swapchain_colorspace);
+
+ const VkSurfaceFormatKHR kWideColorFormats[] = {
+ {VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_SCRGB_LINEAR_EXT},
+ {VK_FORMAT_A2R10G10B10_UNORM_PACK32,
+ VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT},
+ };
+ const uint32_t kNumWideColorFormats =
+ sizeof(kWideColorFormats) / sizeof(kWideColorFormats[0]);
+ if (wide_color_support) {
+ total_num_formats += kNumWideColorFormats;
+ }
VkResult result = VK_SUCCESS;
if (formats) {
- if (*count < kNumFormats)
+ uint32_t out_count = 0;
+ uint32_t transfer_count = 0;
+ if (*count < total_num_formats)
result = VK_INCOMPLETE;
- *count = std::min(*count, kNumFormats);
- std::copy(kFormats, kFormats + *count, formats);
+ transfer_count = std::min(*count, kNumFormats);
+ std::copy(kFormats, kFormats + transfer_count, formats);
+ out_count += transfer_count;
+ if (wide_color_support) {
+ transfer_count = std::min(*count - out_count, kNumWideColorFormats);
+ std::copy(kWideColorFormats, kWideColorFormats + transfer_count,
+ formats + out_count);
+ out_count += transfer_count;
+ }
+ *count = out_count;
} else {
- *count = kNumFormats;
+ *count = total_num_formats;
}
return result;
}
@@ -597,9 +634,13 @@
ALOGV_IF(create_info->imageArrayLayers != 1,
"swapchain imageArrayLayers=%u not supported",
create_info->imageArrayLayers);
- ALOGV_IF(create_info->imageColorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
- "swapchain imageColorSpace=%u not supported",
- create_info->imageColorSpace);
+ ALOGV_IF(
+ create_info->imageColorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR &&
+ create_info->imageColorSpace != VK_COLOR_SPACE_SCRGB_LINEAR_EXT &&
+ create_info->imageColorSpace !=
+ VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT,
+ "swapchain imageColorSpace=%u not supported",
+ create_info->imageColorSpace);
ALOGV_IF((create_info->preTransform & ~kSupportedTransforms) != 0,
"swapchain preTransform=%#x not supported",
create_info->preTransform);
@@ -687,6 +728,12 @@
case VK_FORMAT_R5G6B5_UNORM_PACK16:
native_format = HAL_PIXEL_FORMAT_RGB_565;
break;
+ case VK_FORMAT_R16G16B16A16_SFLOAT:
+ native_format = HAL_PIXEL_FORMAT_RGBA_FP16;
+ break;
+ case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+ native_format = HAL_PIXEL_FORMAT_RGBA_1010102;
+ break;
default:
ALOGV("unsupported swapchain format %d", create_info->imageFormat);
break;
diff --git a/vulkan/libvulkan/swapchain.h b/vulkan/libvulkan/swapchain.h
index 4d9f18f..976c995 100644
--- a/vulkan/libvulkan/swapchain.h
+++ b/vulkan/libvulkan/swapchain.h
@@ -27,7 +27,7 @@
VKAPI_ATTR void DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* allocator);
VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice pdev, uint32_t queue_family, VkSurfaceKHR surface, VkBool32* pSupported);
VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice pdev, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities);
-VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev, VkSurfaceKHR surface, uint32_t* count, VkSurfaceFormatKHR* formats);
+VKAPI_ATTR VkResult GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev, VkSurfaceKHR surface_handle, uint32_t* count, VkSurfaceFormatKHR* formats);
VKAPI_ATTR VkResult GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice pdev, VkSurfaceKHR surface, uint32_t* count, VkPresentModeKHR* modes);
VKAPI_ATTR VkResult CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* create_info, const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchain_handle);
VKAPI_ATTR void DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain_handle, const VkAllocationCallbacks* allocator);