From: Benjamin Otte Date: Sun, 18 Jun 2023 12:00:39 +0000 (+0200) Subject: vulkan: Add support for high bit depth X-Git-Tag: archive/raspbian/4.12.3+ds-1+rpi1~1^2^2^2~22^2~1^2~127^2~2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=aa6c670f15c3533284717019d3c021461b0e3cbb;p=gtk4.git vulkan: Add support for high bit depth --- diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index a1a670a262..99ab8da959 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -47,7 +47,11 @@ typedef struct _GdkVulkanContextPrivate GdkVulkanContextPrivate; 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; @@ -429,8 +433,8 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context, .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, @@ -527,6 +531,20 @@ gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context, 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); @@ -676,8 +694,12 @@ gdk_vulkan_context_real_init (GInitable *initable, 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; } @@ -715,16 +737,71 @@ gdk_vulkan_context_real_init (GInitable *initable, &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)) @@ -851,7 +928,7 @@ gdk_vulkan_context_get_image_format (GdkVulkanContext *context) 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; } /** diff --git a/gsk/vulkan/gskvulkanrenderer.c b/gsk/vulkan/gskvulkanrenderer.c index 35a4269da6..694786e13f 100644 --- a/gsk/vulkan/gskvulkanrenderer.c +++ b/gsk/vulkan/gskvulkanrenderer.c @@ -13,6 +13,7 @@ #include "gskvulkanglyphcacheprivate.h" #include "gdk/gdkdisplayprivate.h" +#include "gdk/gdkdrawcontextprivate.h" #include "gdk/gdktextureprivate.h" #include "gdk/gdkprofilerprivate.h" @@ -341,7 +342,9 @@ gsk_vulkan_renderer_render (GskRenderer *renderer, gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time); #endif - gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->vulkan), region); + gdk_draw_context_begin_frame_full (GDK_DRAW_CONTEXT (self->vulkan), + gsk_render_node_get_preferred_depth (root), + region); render = gsk_vulkan_renderer_get_render (self); render_region = get_render_region (self);