dmabuf: Port Vulkan to using formats directly

Instead of requiring code in the dmabuf backend to map between fourccs
and VkFormat, query the GdkMemoryFormat and GdkDataFormat enums for their
Vulkan mappings.

This reduces the code duplicationquite a lot.

A negative side effect is that unknown formats (to GTK) are no longer
supported. Previously it was possible to map fourccs to VkFormats
without having a corresponding GTK format.
This commit is contained in:
Benjamin Otte
2024-11-11 05:06:22 +01:00
parent edc7da1c25
commit 613e289be6
8 changed files with 107 additions and 830 deletions

View File

@@ -728,6 +728,12 @@ gdk_data_format_block_height (GdkDataFormat format)
return data_formats[format].block_size[1];
}
gboolean
gdk_data_format_is_yuv (GdkDataFormat format)
{
return TRUE;
}
guint32
gdk_data_format_get_dmabuf_fourcc (GdkDataFormat format)
{

View File

@@ -65,9 +65,9 @@ const char * gdk_data_format_get_name (GdkData
GdkMemoryFormat gdk_data_format_get_conversion (GdkDataFormat format) G_GNUC_CONST;
gsize gdk_data_format_n_planes (GdkDataFormat format) G_GNUC_CONST;
gsize gdk_data_format_alignment (GdkDataFormat format) G_GNUC_CONST;
gsize gdk_data_format_block_width (GdkDataFormat format) G_GNUC_CONST;
gsize gdk_data_format_block_height (GdkDataFormat format) G_GNUC_CONST;
gboolean gdk_data_format_is_yuv (GdkDataFormat format) G_GNUC_CONST;
gboolean gdk_data_format_find_by_dmabuf_fourcc (guint32 fourcc,
GdkDataFormat *out_format);

File diff suppressed because it is too large Load Diff

View File

@@ -55,12 +55,5 @@ gboolean gdk_dmabuf_fourcc_is_yuv (guint32
gboolean gdk_dmabuf_get_memory_format (guint32 fourcc,
gboolean premultiplied,
GdkMemoryFormat *out_format);
#ifdef GDK_RENDERING_VULKAN
gboolean gdk_dmabuf_vk_get_nth (gsize n,
guint32 *fourcc,
VkFormat *vk_format);
VkFormat gdk_dmabuf_get_vk_format (guint32 fourcc,
VkComponentMapping *out_components);
#endif
#endif

View File

@@ -1971,6 +1971,31 @@ gdk_memory_format_vk_rgba_format (GdkMemoryFormat format,
}
#endif
gboolean
gdk_memory_format_find_by_dmabuf_fourcc (guint32 fourcc,
gboolean premultiplied,
GdkMemoryFormat *out_format)
{
#ifdef HAVE_DMABUF
gsize i;
for (i = 0; i < G_N_ELEMENTS (memory_formats); i++)
{
if (memory_formats[i].dmabuf_fourcc == fourcc)
{
if (premultiplied)
*out_format = memory_formats[i].premultiplied;
else
*out_format = memory_formats[i].straight;
return TRUE;
}
}
#endif
*out_format = GDK_MEMORY_N_FORMATS;
return FALSE;
}
/*
* gdk_memory_format_get_dmabuf_fourcc:
* @format: The memory format

View File

@@ -95,6 +95,10 @@ VkFormat gdk_memory_format_vk_rgba_format (GdkMemoryFormat
GdkMemoryFormat *out_rgba_format,
VkComponentMapping *out_swizzle);
#endif
gboolean gdk_memory_format_find_by_dmabuf_fourcc
(guint32 fourcc,
gboolean premultiplied,
GdkMemoryFormat *out_format);
guint32 gdk_memory_format_get_dmabuf_fourcc (GdkMemoryFormat format);
const char * gdk_memory_format_get_name (GdkMemoryFormat format);

View File

@@ -24,6 +24,7 @@
#include "gdkvulkancontextprivate.h"
#include "gdkdataformatprivate.h"
#include "gdkdebugprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabuffourccprivate.h"
@@ -1916,12 +1917,12 @@ extern gboolean gsk_renderer_realize_for_display (GskRenderer *r
GdkDisplay *display,
GError **error);
void
gdk_vulkan_init_dmabuf (GdkDisplay *display)
static void
gdk_vulkan_context_add_dmabuf_format (GdkDisplay *display,
VkFormat vk_format,
guint32 fourcc,
GdkDmabufFormatsBuilder *builder)
{
#ifdef HAVE_DMABUF
GdkDmabufFormatsBuilder *vulkan_builder;
GskRenderer *renderer;
VkDrmFormatModifierPropertiesEXT modifier_list[100];
VkDrmFormatModifierPropertiesListEXT modifier_props = {
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
@@ -1932,10 +1933,45 @@ gdk_vulkan_init_dmabuf (GdkDisplay *display)
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
.pNext = &modifier_props,
};
VkFormat vk_format;
gsize i;
if (vk_format == VK_FORMAT_UNDEFINED || fourcc == 0)
return;
modifier_props.drmFormatModifierCount = sizeof (modifier_list);
vkGetPhysicalDeviceFormatProperties2 (display->vk_physical_device,
vk_format,
&props);
g_warn_if_fail (modifier_props.drmFormatModifierCount < sizeof (modifier_list));
for (i = 0; i < modifier_props.drmFormatModifierCount; i++)
{
gboolean advertise = modifier_list[i].drmFormatModifier != DRM_FORMAT_MOD_LINEAR;
GDK_DISPLAY_DEBUG (display, DMABUF,
"Vulkan %s dmabuf format %.4s::%016"G_GINT64_MODIFIER"x with %u planes and features 0x%x",
advertise ? "advertises" : "supports",
(char *) &fourcc,
modifier_list[i].drmFormatModifier,
modifier_list[i].drmFormatModifierPlaneCount,
modifier_list[i].drmFormatModifierTilingFeatures);
if (advertise)
gdk_dmabuf_formats_builder_add_format (builder,
fourcc,
modifier_list[i].drmFormatModifier);
}
}
void
gdk_vulkan_init_dmabuf (GdkDisplay *display)
{
#ifdef HAVE_DMABUF
GdkDmabufFormatsBuilder *vulkan_builder;
GskRenderer *renderer;
guint32 fourcc;
GError *error = NULL;
gsize i, j;
gsize i;
VkFormat vk_format;
if (display->vk_dmabuf_formats != NULL)
return;
@@ -1949,33 +1985,17 @@ gdk_vulkan_init_dmabuf (GdkDisplay *display)
vulkan_builder = gdk_dmabuf_formats_builder_new ();
for (i = 0; gdk_dmabuf_vk_get_nth (i, &fourcc, &vk_format); i++)
for (i = 0; i < GDK_MEMORY_N_FORMATS; i++)
{
if (vk_format == VK_FORMAT_UNDEFINED)
continue;
modifier_props.drmFormatModifierCount = sizeof (modifier_list);
vkGetPhysicalDeviceFormatProperties2 (display->vk_physical_device,
vk_format,
&props);
g_warn_if_fail (modifier_props.drmFormatModifierCount < sizeof (modifier_list));
for (j = 0; j < modifier_props.drmFormatModifierCount; j++)
{
gboolean advertise = modifier_list[j].drmFormatModifier != DRM_FORMAT_MOD_LINEAR;
GDK_DISPLAY_DEBUG (display, DMABUF,
"Vulkan %s dmabuf format %.4s::%016"G_GINT64_MODIFIER"x with %u planes and features 0x%x",
advertise ? "advertises" : "supports",
(char *) &fourcc,
modifier_list[j].drmFormatModifier,
modifier_list[j].drmFormatModifierPlaneCount,
modifier_list[j].drmFormatModifierTilingFeatures);
if (advertise)
gdk_dmabuf_formats_builder_add_format (vulkan_builder,
fourcc,
modifier_list[j].drmFormatModifier);
}
vk_format = gdk_memory_format_vk_format (i, NULL);
fourcc = gdk_memory_format_get_dmabuf_fourcc (i);
gdk_vulkan_context_add_dmabuf_format (display, vk_format, fourcc, vulkan_builder);
}
for (i = 0; i < GDK_DATA_N_FORMATS; i++)
{
vk_format = gdk_data_format_vk_format (i, NULL);
fourcc = gdk_data_format_get_dmabuf_fourcc (i);
gdk_vulkan_context_add_dmabuf_format (display, vk_format, fourcc, vulkan_builder);
}
display->vk_dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (vulkan_builder);

View File

@@ -8,6 +8,7 @@
#include "gskvulkanycbcrprivate.h"
#include "gdk/gdkdisplayprivate.h"
#include "gdk/gdkdataformatprivate.h"
#include "gdk/gdkdmabuftextureprivate.h"
#include "gdk/gdkvulkancontextprivate.h"
#include "gdk/gdkmemoryformatprivate.h"
@@ -857,6 +858,7 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
int fd;
VkResult res;
GdkMemoryFormat format;
GdkDataFormat data_format;
GskGpuImageFlags flags;
gboolean is_yuv;
@@ -866,25 +868,30 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
return NULL;
}
if (!gdk_dmabuf_get_memory_format (dmabuf->fourcc, premultiplied, &format))
if (gdk_memory_format_find_by_dmabuf_fourcc (dmabuf->fourcc, premultiplied, &format))
{
/* We should never get dmabufs with fourccs we've never checked we support */
g_return_val_if_reached (NULL);
vk_format = gdk_memory_format_vk_format (data_format, &vk_components);
is_yuv = FALSE;
}
else if (gdk_data_format_find_by_dmabuf_fourcc (dmabuf->fourcc, &data_format))
{
format = gdk_data_format_get_conversion (data_format);
vk_format = gdk_data_format_vk_format (data_format, &vk_components);
is_yuv = gdk_data_format_is_yuv (data_format);
}
else
{
vk_format = VK_FORMAT_UNDEFINED;
}
vk_device = gsk_vulkan_device_get_vk_device (device);
func_vkGetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR) vkGetDeviceProcAddr (vk_device, "vkGetMemoryFdPropertiesKHR");
vk_format = gdk_dmabuf_get_vk_format (dmabuf->fourcc, &vk_components);
if (vk_format == VK_FORMAT_UNDEFINED)
{
GDK_DEBUG (DMABUF, "GTK's Vulkan doesn't support fourcc %.4s", (char *) &dmabuf->fourcc);
return NULL;
}
if (!gdk_dmabuf_fourcc_is_yuv (dmabuf->fourcc, &is_yuv))
{
g_assert_not_reached ();
}
vk_device = gsk_vulkan_device_get_vk_device (device);
func_vkGetMemoryFdPropertiesKHR = (PFN_vkGetMemoryFdPropertiesKHR) vkGetDeviceProcAddr (vk_device, "vkGetMemoryFdPropertiesKHR");
/* FIXME: Add support for disjoint images */
if (gdk_dmabuf_is_disjoint (dmabuf))