struct _GdkVulkanContextPrivate {
#ifdef GDK_RENDERING_VULKAN
VkSurfaceKHR surface;
- VkSurfaceFormatKHR image_format;
+ struct {
+ VkSurfaceFormatKHR vk_format;
+ GdkMemoryFormat gdk_format;
+ } formats[4];
+ GdkMemoryDepth current_format;
VkSwapchainKHR swapchain;
VkSemaphore draw_semaphore;
.minImageCount = CLAMP (4,
capabilities.minImageCount,
capabilities.maxImageCount ? capabilities.maxImageCount : G_MAXUINT32),
- .imageFormat = priv->image_format.format,
- .imageColorSpace = priv->image_format.colorSpace,
+ .imageFormat = priv->formats[priv->current_format].vk_format.format,
+ .imageColorSpace = priv->formats[priv->current_format].vk_format.colorSpace,
.imageExtent = capabilities.currentExtent,
.imageArrayLayers = 1,
.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
guint i;
+ if (depth != priv->current_format)
+ {
+ if (priv->formats[depth].gdk_format != priv->formats[priv->current_format].gdk_format)
+ {
+ GError *error = NULL;
+ if (!gdk_vulkan_context_check_swapchain (context, &error))
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return;
+ }
+ }
+ priv->current_format = depth;
+ }
for (i = 0; i < priv->n_images; i++)
{
cairo_region_union (priv->regions[i], region);
if (surface == NULL)
{
- priv->image_format.format = VK_FORMAT_B8G8R8A8_UNORM;
- priv->image_format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+ for (i = 0; i < G_N_ELEMENTS (priv->formats); i++)
+ {
+ priv->formats[i].vk_format.format = VK_FORMAT_B8G8R8A8_UNORM;
+ priv->formats[i].vk_format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+ priv->formats[i].gdk_format = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
+ }
return TRUE;
}
&n_formats, formats);
for (i = 0; i < n_formats; i++)
{
- if (formats[i].format == VK_FORMAT_B8G8R8A8_UNORM)
- break;
+ if (formats[i].colorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
+ continue;
+
+ switch ((int) formats[i].format)
+ {
+ case VK_FORMAT_B8G8R8A8_UNORM:
+ if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED)
+ {
+ priv->formats[GDK_MEMORY_U8].vk_format = formats[i];
+ priv->formats[GDK_MEMORY_U8].gdk_format = GDK_MEMORY_B8G8R8A8_PREMULTIPLIED;
+ };
+ break;
+
+ case VK_FORMAT_R8G8B8A8_UNORM:
+ if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED)
+ {
+ priv->formats[GDK_MEMORY_U8].vk_format = formats[i];
+ priv->formats[GDK_MEMORY_U8].gdk_format = GDK_MEMORY_R8G8B8A8_PREMULTIPLIED;
+ }
+ break;
+
+ case VK_FORMAT_R16G16B16A16_UNORM:
+ priv->formats[GDK_MEMORY_U16].vk_format = formats[i];
+ priv->formats[GDK_MEMORY_U16].gdk_format = GDK_MEMORY_R16G16B16A16_PREMULTIPLIED;
+ break;
+
+ case VK_FORMAT_R16G16B16A16_SFLOAT:
+ priv->formats[GDK_MEMORY_FLOAT16].vk_format = formats[i];
+ priv->formats[GDK_MEMORY_FLOAT16].gdk_format = GDK_MEMORY_R16G16B16A16_FLOAT_PREMULTIPLIED;
+ break;
+
+ case VK_FORMAT_R32G32B32A32_SFLOAT:
+ priv->formats[GDK_MEMORY_FLOAT32].vk_format = formats[i];
+ priv->formats[GDK_MEMORY_FLOAT32].gdk_format = GDK_MEMORY_R32G32B32A32_FLOAT_PREMULTIPLIED;
+ break;
+
+ default:
+ break;
+ }
}
- if (i == n_formats)
+ if (priv->formats[GDK_MEMORY_U8].vk_format.format == VK_FORMAT_UNDEFINED)
{
g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
"No supported image format found.");
goto out_surface;
}
- priv->image_format = formats[i];
+ /* Ensure all the formats exist:
+ * - If a format was found, keep that one.
+ * - FLOAT32 chooses the best format we have.
+ * - FLOAT16 and U16 pick the format FLOAT32 uses
+ */
+ if (priv->formats[GDK_MEMORY_FLOAT32].vk_format.format == VK_FORMAT_UNDEFINED)
+ {
+ if (priv->formats[GDK_MEMORY_FLOAT16].vk_format.format != VK_FORMAT_UNDEFINED)
+ priv->formats[GDK_MEMORY_FLOAT32] = priv->formats[GDK_MEMORY_FLOAT16];
+ else if (priv->formats[GDK_MEMORY_U16].vk_format.format != VK_FORMAT_UNDEFINED)
+ priv->formats[GDK_MEMORY_FLOAT32] = priv->formats[GDK_MEMORY_U16];
+ else
+ priv->formats[GDK_MEMORY_FLOAT32] = priv->formats[GDK_MEMORY_U8];
+ }
+ if (priv->formats[GDK_MEMORY_FLOAT16].vk_format.format == VK_FORMAT_UNDEFINED)
+ priv->formats[GDK_MEMORY_FLOAT16] = priv->formats[GDK_MEMORY_FLOAT32];
+ if (priv->formats[GDK_MEMORY_U16].vk_format.format == VK_FORMAT_UNDEFINED)
+ priv->formats[GDK_MEMORY_U16] = priv->formats[GDK_MEMORY_FLOAT32];
+
priv->has_present_region = device_supports_incremental_present (display->vk_physical_device);
if (!gdk_vulkan_context_check_swapchain (context, error))
g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), VK_FORMAT_UNDEFINED);
- return priv->image_format.format;
+ return priv->formats[priv->current_format].vk_format.format;
}
/**