vulkan: Add support for enumerating dmabuf formats

This code does not add a downloader, so we do not claim support for all
the new formats.

It just queries the formats. But this can be used to import dmabufs
directly into the Vulkaan renderer.
This commit is contained in:
Benjamin Otte
2023-10-19 13:34:40 +02:00
parent f21938cae6
commit 16a3a04405
6 changed files with 103 additions and 1 deletions

View File

@@ -40,7 +40,7 @@
#include "gdkglcontextprivate.h"
#include "gdkmonitorprivate.h"
#include "gdkrectangle.h"
#include "gdkvulkancontext.h"
#include "gdkvulkancontextprivate.h"
#ifdef HAVE_EGL
#include <epoxy/egl.h>
@@ -416,6 +416,13 @@ gdk_display_dispose (GObject *object)
g_clear_pointer (&display->egl_dmabuf_formats, gdk_dmabuf_formats_unref);
g_clear_pointer (&display->egl_external_formats, gdk_dmabuf_formats_unref);
#ifdef GDK_RENDERING_VULKAN
if (display->vk_dmabuf_formats)
{
gdk_display_unref_vulkan (display);
g_assert (display->vk_dmabuf_formats == NULL);
}
#endif
g_clear_object (&priv->gl_context);
#ifdef HAVE_EGL
@@ -1939,6 +1946,10 @@ gdk_display_init_dmabuf (GdkDisplay *self)
#ifdef HAVE_DMABUF
if (!GDK_DISPLAY_DEBUG_CHECK (self, DMABUF_DISABLE))
{
#ifdef GDK_RENDERING_VULKAN
gdk_display_add_dmabuf_downloader (self, gdk_vulkan_get_dmabuf_downloader (self, builder));
#endif
#ifdef HAVE_EGL
gdk_display_add_dmabuf_downloader (self, gdk_dmabuf_get_egl_downloader (self, builder));
#endif

View File

@@ -112,6 +112,7 @@ struct _GdkDisplay
char *vk_pipeline_cache_etag;
guint vk_save_pipeline_cache_source;
GHashTable *vk_shader_modules;
GdkDmabufFormats *vk_dmabuf_formats;
GdkVulkanFeatures vulkan_features;
guint vulkan_refcount;

View File

@@ -1919,6 +1919,19 @@ gdk_dmabuf_get_memory_format (guint32 fourcc,
}
#ifdef GDK_RENDERING_VULKAN
gboolean
gdk_dmabuf_vk_get_nth (gsize n,
guint32 *fourcc,
VkFormat *vk_format)
{
if (n >= G_N_ELEMENTS (supported_formats))
return FALSE;
*fourcc = supported_formats[n].fourcc;
*vk_format = supported_formats[n].vk.format;
return TRUE;
}
VkFormat
gdk_dmabuf_get_vk_format (guint32 fourcc,
VkComponentMapping *out_components)

View File

@@ -54,6 +54,9 @@ gboolean gdk_dmabuf_get_memory_format (guint32
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

View File

@@ -24,6 +24,10 @@
#include "gdkvulkancontextprivate.h"
#include "gdkdebugprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
#include "gdkdmabuffourccprivate.h"
#include "gdkdmabuftextureprivate.h"
#include "gdkdisplayprivate.h"
#include <glib/gi18n-lib.h>
#include <math.h>
@@ -1726,6 +1730,7 @@ gdk_display_unref_vulkan (GdkDisplay *display)
GDK_DEBUG (VULKAN, "Closing Vulkan instance");
display->vulkan_features = 0;
g_clear_pointer (&display->vk_dmabuf_formats, gdk_dmabuf_formats_unref);
g_hash_table_iter_init (&iter, display->vk_shader_modules);
while (g_hash_table_iter_next (&iter, &key, &value))
{
@@ -1763,6 +1768,70 @@ gdk_display_unref_vulkan (GdkDisplay *display)
display->vk_instance = VK_NULL_HANDLE;
}
GdkDmabufDownloader *
gdk_vulkan_get_dmabuf_downloader (GdkDisplay *display,
GdkDmabufFormatsBuilder *builder)
{
GdkDmabufFormatsBuilder *vulkan_builder;
VkDrmFormatModifierPropertiesEXT modifier_list[100];
VkDrmFormatModifierPropertiesListEXT modifier_props = {
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
.pNext = NULL,
.pDrmFormatModifierProperties = modifier_list,
};
VkFormatProperties2 props = {
.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
.pNext = &modifier_props,
};
VkFormat vk_format;
guint32 fourcc;
gsize i, j;
g_assert (display->vk_dmabuf_formats == NULL);
if (!gdk_display_init_vulkan (display, NULL))
return NULL;
if ((display->vulkan_features & GDK_VULKAN_FEATURE_DMABUF) == 0)
return NULL;
vulkan_builder = gdk_dmabuf_formats_builder_new ();
for (i = 0; gdk_dmabuf_vk_get_nth (i, &fourcc, &vk_format); 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++)
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Vulkan supports dmabuf format %.4s::%016llx with %u planes and features 0x%x",
(char *) &fourcc,
(long long unsigned) modifier_list[j].drmFormatModifier,
modifier_list[j].drmFormatModifierPlaneCount,
modifier_list[j].drmFormatModifierTilingFeatures);
if (modifier_list[j].drmFormatModifier == DRM_FORMAT_MOD_LINEAR)
continue;
gdk_dmabuf_formats_builder_add_format (vulkan_builder,
fourcc,
modifier_list[j].drmFormatModifier);
}
}
display->vk_dmabuf_formats = gdk_dmabuf_formats_builder_free_to_formats (vulkan_builder);
gdk_dmabuf_formats_builder_add_formats (builder, display->vk_dmabuf_formats);
return NULL;
}
VkShaderModule
gdk_display_get_vk_shader_module (GdkDisplay *self,
const char *resource_name)

View File

@@ -23,6 +23,8 @@
#include "gdkvulkancontext.h"
#include "gdkdebugprivate.h"
#include "gdkdmabufprivate.h"
#include "gdkdmabufdownloaderprivate.h"
#include "gdkdrawcontextprivate.h"
#include "gdkenums.h"
@@ -74,6 +76,9 @@ gboolean gdk_display_init_vulkan (GdkDisp
void gdk_display_ref_vulkan (GdkDisplay *display);
void gdk_display_unref_vulkan (GdkDisplay *display);
GdkDmabufDownloader * gdk_vulkan_get_dmabuf_downloader (GdkDisplay *display,
GdkDmabufFormatsBuilder *builder);
VkShaderModule gdk_display_get_vk_shader_module (GdkDisplay *display,
const char *resource_name);