Compare commits

...

9 Commits

Author SHA1 Message Date
Benjamin Otte
d96334b75f dmabuf: Query supported formats using new method
This makes the old table unnecessary and we can finally remove it.
2024-11-12 04:36:00 +01:00
Benjamin Otte
b92797da1f dmabuf: Make downloads use new format determination 2024-11-12 04:35:40 +01:00
Benjamin Otte
9969b0ddad dataformat: Add formats with RGBX + alpha plane
Those are formats that are not YUV formats, so we need to add a is_yuv
flag.
2024-11-11 23:40:47 +01:00
Benjamin Otte
a98088d9f9 dmabuf: Move format rejection from sanitize into build() 2024-11-11 20:36:38 +01:00
Benjamin Otte
9ab9405b71 dmabuftexture: Use the new way to lookup formats
Use gdk_memory_format_find_by_dmabuf_fourcc() and
gdk_data_format_find_by_dmabuf_fourcc() to scan for supported dmabuf
formats instead of

This means we can now stop tracking memory format and yuv-ness in the
dmabuf table.
2024-11-11 20:36:36 +01:00
Benjamin Otte
784ed101e1 dmabuftexture: Move failure cases up
We don't have to construct a GdkDmabufTexture to know that we can't
support the format. So don't.
2024-11-11 20:31:46 +01:00
Benjamin Otte
613e289be6 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.
2024-11-11 20:31:46 +01:00
Benjamin Otte
edc7da1c25 dmabuf: Don't store the data format
Instead, add a function to find the data format from a fourcc to the
GdkDataFormat machinary and use that one.
2024-11-11 20:31:46 +01:00
Benjamin Otte
8e5a69da9c dmabuf: Split out conversion functions
Create a GdkDataFormat enum and give it an API similar to
GdkMemoryFormat.

This makes the code no longer dmabuf-specific and provides a generic
method for all backends to access weird formats.

Technically, we could now add a GdkTexture implementation based on this.
2024-11-11 20:31:46 +01:00
10 changed files with 1203 additions and 2139 deletions

922
gdk/gdkdataformat.c Normal file
View File

@@ -0,0 +1,922 @@
#include "config.h"
#include "gdkdataformatprivate.h"
#include "gdk/gdkdmabuffourccprivate.h"
typedef struct _GdkDataFormatDescription GdkDataFormatDescription;
struct _GdkDataFormatDescription
{
const char *name;
GdkMemoryFormat conversion;
gboolean is_yuv;
gsize n_planes;
gsize alignment;
gsize block_size[2];
guint32 dmabuf_fourcc;
#ifdef GDK_RENDERING_VULKAN
struct {
VkFormat format;
VkComponentMapping swizzle;
} vk;
#endif
void (* convert) (const GdkDataBuffer *self,
guchar *dst_data,
gsize dst_stride);
};
typedef struct _YUVCoefficients YUVCoefficients;
struct _YUVCoefficients
{
int v_to_r;
int u_to_g;
int v_to_g;
int u_to_b;
};
/* multiplied by 65536 */
static const YUVCoefficients itu601_narrow = { 104597, -25675, -53279, 132201 };
//static const YUVCoefficients itu601_wide = { 74711, -25864, -38050, 133176 };
static inline void
get_uv_values (const YUVCoefficients *coeffs,
guint8 u,
guint8 v,
int *out_r,
int *out_g,
int *out_b)
{
int u2 = (int) u - 127;
int v2 = (int) v - 127;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values (guint8 rgb[3],
guint8 y,
int r,
int g,
int b)
{
int y2 = y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 255);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 255);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 255);
}
static inline void
gdk_convert_nv12_like (guchar *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guchar *y_data,
gsize y_stride,
const guchar *uv_data,
gsize uv_stride,
gboolean uv_swapped,
gsize x_subsample,
gsize y_subsample)
{
gsize x, y;
for (y = 0; y < height; y += y_subsample)
{
for (x = 0; x < width; x += x_subsample)
{
int r, g, b;
gsize xs, ys;
get_uv_values (&itu601_narrow,
uv_data[x / x_subsample * 2 + (uv_swapped ? 1 : 0)],
uv_data[x / x_subsample * 2 + (uv_swapped ? 0 : 1)],
&r, &g, &b);
for (ys = 0; ys < y_subsample && y + ys < height; ys++)
for (xs = 0; xs < x_subsample && x + xs < width; xs++)
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += y_subsample * dst_stride;
y_data += y_subsample * y_stride;
uv_data += uv_stride;
}
}
#define CONVERT_NV12_FUNC(name, uv_swapped, x_subsample, y_subsample) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_nv12_like (dst_data, \
dst_stride, \
self->width, \
self->height, \
self->planes[0].data, \
self->planes[0].stride, \
self->planes[1].data, \
self->planes[1].stride, \
uv_swapped, x_subsample, y_subsample); \
}
CONVERT_NV12_FUNC (nv12, FALSE, 2, 2)
CONVERT_NV12_FUNC (nv21, TRUE, 2, 2)
CONVERT_NV12_FUNC (nv16, FALSE, 2, 1)
CONVERT_NV12_FUNC (nv61, TRUE, 2, 1)
CONVERT_NV12_FUNC (nv24, FALSE, 1, 1)
CONVERT_NV12_FUNC (nv42, TRUE, 1, 1)
static inline void
get_uv_values16 (const YUVCoefficients *coeffs,
guint16 u,
guint16 v,
gint64 *out_r,
gint64 *out_g,
gint64 *out_b)
{
gint64 u2 = (gint64) u - 32767;
gint64 v2 = (gint64) v - 32767;
*out_r = coeffs->v_to_r * v2;
*out_g = coeffs->u_to_g * u2 + coeffs->v_to_g * v2;
*out_b = coeffs->u_to_b * u2;
}
static inline void
set_rgb_values16 (guint16 rgb[3],
guint16 y,
gint64 r,
gint64 g,
gint64 b)
{
gint64 y2 = (gint64) y * 65536;
rgb[0] = CLAMP ((y2 + r) >> 16, 0, 65535);
rgb[1] = CLAMP ((y2 + g) >> 16, 0, 65535);
rgb[2] = CLAMP ((y2 + b) >> 16, 0, 65535);
}
static inline void
gdk_convert_p010_like (guint16 *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guint16 *y_data,
gsize y_stride,
const guint16 *uv_data,
gsize uv_stride,
gsize bits_used,
gboolean uv_swapped,
gsize x_subsample,
gsize y_subsample)
{
gsize x, y;
guint16 mask;
mask = 0xFFFF << (16 - bits_used);
for (y = 0; y < height; y += y_subsample)
{
for (x = 0; x < width; x += x_subsample)
{
gint64 r, g, b;
gsize xs, ys;
guint16 u, v;
u = uv_data[x / x_subsample * 2 + (uv_swapped ? 1 : 0)];
u = (u & mask) | (u >> bits_used);
v = uv_data[x / x_subsample * 2 + (uv_swapped ? 0 : 1)];
v = (v & mask) | (v >> bits_used);
get_uv_values16 (&itu601_narrow, u, v, &r, &g, &b);
for (ys = 0; ys < y_subsample && y + ys < height; ys++)
for (xs = 0; xs < x_subsample && x + xs < width; xs++)
{
guint16 y_ = y_data[x + xs + y_stride * ys];
y_ = (y_ & mask) | (y_ >> bits_used);
set_rgb_values16 (&dst_data[3 * (x + xs) + dst_stride * ys], y_, r, g, b);
}
}
dst_data += y_subsample * dst_stride;
y_data += y_subsample * y_stride;
uv_data += uv_stride;
}
}
#define CONVERT_P010_FUNC(name, bits_used, uv_swapped, x_subsample, y_subsample) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_p010_like ((guint16 *) dst_data, \
dst_stride, \
self->width, \
self->height, \
(guint16 *) self->planes[0].data, \
self->planes[0].stride, \
(guint16 *) self->planes[1].data, \
self->planes[1].stride, \
bits_used, uv_swapped, x_subsample, y_subsample); \
}
CONVERT_P010_FUNC (p010, 10, FALSE, 2, 2)
CONVERT_P010_FUNC (p012, 12, FALSE, 2, 2)
CONVERT_P010_FUNC (p016, 16, FALSE, 2, 2)
static inline void
gdk_convert_3_plane (guchar *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guchar *y_data,
gsize y_stride,
const guchar *u_data,
gsize u_stride,
const guchar *v_data,
gsize v_stride,
gsize x_subsample,
gsize y_subsample)
{
gsize x, y;
for (y = 0; y < height; y += y_subsample)
{
for (x = 0; x < width; x += x_subsample)
{
int r, g, b;
gsize xs, ys;
get_uv_values (&itu601_narrow, u_data[x / x_subsample], v_data[x / x_subsample], &r, &g, &b);
for (ys = 0; ys < y_subsample && y + ys < height; ys++)
for (xs = 0; xs < x_subsample && x + xs < width; xs++)
set_rgb_values (&dst_data[3 * (x + xs) + dst_stride * ys], y_data[x + xs + y_stride * ys], r, g, b);
}
dst_data += y_subsample * dst_stride;
y_data += y_subsample * y_stride;
u_data += u_stride;
v_data += v_stride;
}
}
#define CONVERT_3_PLANE_FUNC(name, uv_swapped, x_subsample, y_subsample) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_3_plane (dst_data, \
dst_stride, \
self->width, \
self->height, \
self->planes[0].data, \
self->planes[0].stride, \
self->planes[uv_swapped ? 2 : 1].data, \
self->planes[uv_swapped ? 2 : 1].stride, \
self->planes[uv_swapped ? 1 : 2].data, \
self->planes[uv_swapped ? 1 : 2].stride, \
x_subsample, y_subsample); \
}
CONVERT_3_PLANE_FUNC (yuv410, FALSE, 4, 4)
CONVERT_3_PLANE_FUNC (yvu410, TRUE, 4, 4)
CONVERT_3_PLANE_FUNC (yuv411, FALSE, 4, 1)
CONVERT_3_PLANE_FUNC (yvu411, TRUE, 4, 1)
CONVERT_3_PLANE_FUNC (yuv420, FALSE, 2, 2)
CONVERT_3_PLANE_FUNC (yvu420, TRUE, 2, 2)
CONVERT_3_PLANE_FUNC (yuv422, FALSE, 2, 1)
CONVERT_3_PLANE_FUNC (yvu422, TRUE, 2, 1)
CONVERT_3_PLANE_FUNC (yuv444, FALSE, 1, 1)
CONVERT_3_PLANE_FUNC (yvu444, TRUE, 1, 1)
static inline void
gdk_convert_yuyv_like (guchar *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guchar *src_data,
gsize src_stride,
gsize y_index,
gsize u_index,
gsize v_index)
{
gsize x, y;
for (y = 0; y < height; y ++)
{
for (x = 0; x < width; x += 2)
{
int r, g, b;
get_uv_values (&itu601_narrow, src_data[2 * x + u_index], src_data[2 * x + v_index], &r, &g, &b);
set_rgb_values (&dst_data[3 * x], src_data[2 * x + y_index], r, g, b);
if (x + 1 < width)
set_rgb_values (&dst_data[3 * (x + 1)], src_data[2 * x + y_index + 2], r, g, b);
}
dst_data += dst_stride;
src_data += src_stride;
}
}
#define CONVERT_YUYV_FUNC(name, y_index, u_index, v_index) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_yuyv_like (dst_data, \
dst_stride, \
self->width, \
self->height, \
self->planes[0].data, \
self->planes[0].stride, \
y_index, u_index, v_index); \
}
CONVERT_YUYV_FUNC (yuyv, 0, 1, 3)
CONVERT_YUYV_FUNC (yvyu, 0, 3, 1)
CONVERT_YUYV_FUNC (uyvy, 1, 0, 2)
CONVERT_YUYV_FUNC (vyuy, 1, 2, 0)
static inline void
gdk_convert_3_1 (guchar *dst_data,
gsize dst_stride,
gsize width,
gsize height,
const guchar *xrgb_data,
gsize xrgb_stride,
const guchar *a_data,
gsize a_stride,
gsize a_index)
{
gsize x, y;
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
dst_data[4 * x + 0] = xrgb_data[4 * x + 0];
dst_data[4 * x + 1] = xrgb_data[4 * x + 1];
dst_data[4 * x + 2] = xrgb_data[4 * x + 2];
dst_data[4 * x + 3] = xrgb_data[4 * x + 3];
dst_data[4 * x + a_index] = a_data[x];
}
dst_data += dst_stride;
xrgb_data += xrgb_stride;
a_data += a_stride;
}
}
#define CONVERT_3_1_FUNC(name, a_index) \
static void \
gdk_convert_ ## name (const GdkDataBuffer *self, \
guchar *dst_data, \
gsize dst_stride) \
{ \
gdk_convert_3_1 (dst_data, \
dst_stride, \
self->width, \
self->height, \
self->planes[0].data, \
self->planes[0].stride, \
self->planes[1].data, \
self->planes[1].stride, \
a_index); \
}
CONVERT_3_1_FUNC (xrgb8_a8, 0)
CONVERT_3_1_FUNC (xbgr8_a8, 0)
CONVERT_3_1_FUNC (rgbx8_a8, 3)
CONVERT_3_1_FUNC (bgrx8_a8, 3)
#define VULKAN_SWIZZLE(_R, _G, _B, _A) { VK_COMPONENT_SWIZZLE_ ## _R, VK_COMPONENT_SWIZZLE_ ## _G, VK_COMPONENT_SWIZZLE_ ## _B, VK_COMPONENT_SWIZZLE_ ## _A }
#define VULKAN_DEFAULT_SWIZZLE VULKAN_SWIZZLE (R, G, B, A)
GdkDataFormatDescription data_formats[] = {
[GDK_DATA_NV12] = {
.name = "NV12",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_NV12,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_nv12,
},
[GDK_DATA_NV21] = {
.name = "NV21",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_NV21,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_nv21,
},
[GDK_DATA_NV16] = {
.name = "NV16",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_NV16,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_nv16,
},
[GDK_DATA_NV61] = {
.name = "NV61",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_NV61,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_nv61,
},
[GDK_DATA_NV24] = {
.name = "NV24",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_NV24,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_nv24,
},
[GDK_DATA_NV42] = {
.name = "NV42",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_NV42,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_nv42,
},
[GDK_DATA_P010] = {
.name = "P010",
.conversion = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_P010,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_p010,
},
[GDK_DATA_P012] = {
.name = "P012",
.conversion = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_P012,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_p012,
},
[GDK_DATA_P016] = {
.name = "P016",
.conversion = GDK_MEMORY_R16G16B16,
.is_yuv = TRUE,
.n_planes = 2,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_P016,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_p016,
},
[GDK_DATA_YUV410] = {
.name = "YUV410",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 4, 4 },
.dmabuf_fourcc = DRM_FORMAT_YUV410,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv410,
},
[GDK_DATA_YVU410] = {
.name = "YVU410",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 4, 4 },
.dmabuf_fourcc = DRM_FORMAT_YVU410,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yvu410,
},
[GDK_DATA_YUV411] = {
.name = "YUV411",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 4, 1 },
.dmabuf_fourcc = DRM_FORMAT_YUV411,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv411,
},
[GDK_DATA_YVU411] = {
.name = "YVU411",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 4, 1 },
.dmabuf_fourcc = DRM_FORMAT_YVU411,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yvu411,
},
[GDK_DATA_YUV420] = {
.name = "YUV420",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_YUV420,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv420,
},
[GDK_DATA_YVU420] = {
.name = "YVU420",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 2, 2 },
.dmabuf_fourcc = DRM_FORMAT_YVU420,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_yvu420,
},
[GDK_DATA_YUV422] = {
.name = "YUV422",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_YUV422,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv422,
},
[GDK_DATA_YVU422] = {
.name = "YVU422",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_YVU422,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_yvu422,
},
[GDK_DATA_YUV444] = {
.name = "YUV444",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_YUV444,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuv444,
},
[GDK_DATA_YVU444] = {
.name = "YVU444",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 3,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_YVU444,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_yvu444,
},
[GDK_DATA_YUYV] = {
.name = "YUYV",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 1,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_YUYV,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8B8G8R8_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_yuyv,
},
[GDK_DATA_YVYU] = {
.name = "YVYU",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 1,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_YVYU,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_G8B8G8R8_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_yvyu,
},
[GDK_DATA_UYVY] = {
.name = "UYVY",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 1,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_UYVY,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_B8G8R8G8_422_UNORM,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_uyvy,
},
[GDK_DATA_VYUY] = {
.name = "VYUY",
.conversion = GDK_MEMORY_R8G8B8,
.is_yuv = TRUE,
.n_planes = 1,
.alignment = 4,
.block_size = { 2, 1 },
.dmabuf_fourcc = DRM_FORMAT_VYUY,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_B8G8R8G8_422_UNORM,
.swizzle = VULKAN_SWIZZLE (B, G, R, A),
},
#endif
.convert = gdk_convert_vyuy,
},
[GDK_DATA_RGBX8_A8] = {
.name = "GDK_DATA_RGBX8_A8",
.conversion = GDK_MEMORY_R8G8B8A8,
.is_yuv = FALSE,
.n_planes = 1,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_RGBX8888_A8,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_rgbx8_a8,
},
[GDK_DATA_BGRX8_A8] = {
.name = "GDK_DATA_BGRX8_A8",
.conversion = GDK_MEMORY_B8G8R8A8,
.is_yuv = FALSE,
.n_planes = 1,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_BGRX8888_A8,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_bgrx8_a8,
},
[GDK_DATA_XRGB8_A8] = {
.name = "GDK_DATA_XRGB8_A8",
.conversion = GDK_MEMORY_A8R8G8B8,
.is_yuv = FALSE,
.n_planes = 1,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_XRGB8888_A8,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_xrgb8_a8,
},
[GDK_DATA_XBGR8_A8] = {
.name = "GDK_DATA_XBGR8_A8",
.conversion = GDK_MEMORY_A8B8G8R8,
.is_yuv = FALSE,
.n_planes = 1,
.alignment = 4,
.block_size = { 1, 1 },
.dmabuf_fourcc = DRM_FORMAT_XBGR8888_A8,
#ifdef GDK_RENDERING_VULKAN
.vk = {
.format = VK_FORMAT_UNDEFINED,
.swizzle = VULKAN_DEFAULT_SWIZZLE,
},
#endif
.convert = gdk_convert_xbgr8_a8,
},
};
const char *
gdk_data_format_get_name (GdkDataFormat format)
{
return data_formats[format].name;
}
GdkMemoryFormat
gdk_data_format_get_conversion (GdkDataFormat format)
{
return data_formats[format].conversion;
}
gsize
gdk_data_format_n_planes (GdkDataFormat format)
{
return data_formats[format].n_planes;
}
gsize
gdk_data_format_alignment (GdkDataFormat format)
{
return data_formats[format].alignment;
}
gsize
gdk_data_format_block_width (GdkDataFormat format)
{
return data_formats[format].block_size[0];
}
gsize
gdk_data_format_block_height (GdkDataFormat format)
{
return data_formats[format].block_size[1];
}
gboolean
gdk_data_format_is_yuv (GdkDataFormat format)
{
return data_formats[format].is_yuv;
}
guint32
gdk_data_format_get_dmabuf_fourcc (GdkDataFormat format)
{
return data_formats[format].dmabuf_fourcc;
}
gboolean
gdk_data_format_find_by_dmabuf_fourcc (guint32 fourcc,
GdkDataFormat *out_format)
{
gsize i;
for (i = 0; i < G_N_ELEMENTS (data_formats); i++)
{
if (data_formats[i].dmabuf_fourcc == fourcc)
{
*out_format = i;
return TRUE;
}
}
*out_format = GDK_DATA_N_FORMATS;
return FALSE;
}
#ifdef GDK_RENDERING_VULKAN
VkFormat
gdk_data_format_vk_format (GdkDataFormat format,
VkComponentMapping *out_swizzle)
{
if (out_swizzle)
*out_swizzle = data_formats[format].vk.swizzle;
return data_formats[format].vk.format;
}
#endif
void
gdk_data_convert (const GdkDataBuffer *self,
guchar *dest_data,
gsize dest_stride)
{
data_formats[self->format].convert (self,
dest_data,
dest_stride);
}

View File

@@ -0,0 +1,90 @@
#pragma once
#include "gdkenums.h"
#include "gdktypes.h"
#include "gdkmemoryformatprivate.h"
/* epoxy needs this, see https://github.com/anholt/libepoxy/issues/299 */
#ifdef GDK_WINDOWING_WIN32
#include <windows.h>
#endif
#include <epoxy/gl.h>
#ifdef GDK_RENDERING_VULKAN
#include <vulkan/vulkan.h>
#endif
G_BEGIN_DECLS
typedef enum {
GDK_DATA_NV12,
GDK_DATA_NV21,
GDK_DATA_NV16,
GDK_DATA_NV61,
GDK_DATA_NV24,
GDK_DATA_NV42,
GDK_DATA_P010,
GDK_DATA_P012,
GDK_DATA_P016,
GDK_DATA_YUV410,
GDK_DATA_YVU410,
GDK_DATA_YUV411,
GDK_DATA_YVU411,
GDK_DATA_YUV420,
GDK_DATA_YVU420,
GDK_DATA_YUV422,
GDK_DATA_YVU422,
GDK_DATA_YUV444,
GDK_DATA_YVU444,
GDK_DATA_YUYV,
GDK_DATA_YVYU,
GDK_DATA_UYVY,
GDK_DATA_VYUY,
GDK_DATA_BGRX8_A8,
GDK_DATA_RGBX8_A8,
GDK_DATA_XRGB8_A8,
GDK_DATA_XBGR8_A8,
GDK_DATA_N_FORMATS
} GdkDataFormat;
#define GDK_DATA_FORMAT_MAX_PLANES 4
typedef struct _GdkDataBuffer GdkDataBuffer;
struct _GdkDataBuffer
{
GdkDataFormat format;
gsize width;
gsize height;
struct {
const guchar *data;
gsize stride;
} planes[GDK_DATA_FORMAT_MAX_PLANES];
};
const char * gdk_data_format_get_name (GdkDataFormat format) G_GNUC_CONST;
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);
guint32 gdk_data_format_get_dmabuf_fourcc (GdkDataFormat format) G_GNUC_CONST;
#ifdef GDK_RENDERING_VULKAN
VkFormat gdk_data_format_vk_format (GdkDataFormat format,
VkComponentMapping *out_swizzle);
#endif
void gdk_data_convert (const GdkDataBuffer *self,
guchar *dest_data,
gsize dest_stride);
G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@@ -50,17 +50,4 @@ gboolean gdk_dmabuf_sanitize (GdkDmabuf
gboolean gdk_dmabuf_is_disjoint (const GdkDmabuf *dmabuf);
gboolean gdk_dmabuf_fourcc_is_yuv (guint32 fourcc,
gboolean *is_yuv);
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

@@ -21,6 +21,7 @@
#include "gdkdmabuftextureprivate.h"
#include "gdkcolorstateprivate.h"
#include "gdkdataformatprivate.h"
#include "gdkdisplayprivate.h"
#include "gdkdmabufdownloaderprivate.h"
#include "gdkdmabufformatsbuilderprivate.h"
@@ -105,8 +106,9 @@ static gboolean
gdk_dmabuf_texture_invoke_callback (gpointer data)
{
Download *download = data;
GdkDisplay *display = download->texture->display;
//GdkDisplay *display = download->texture->display;
#if 0
if (display->egl_downloader &&
gdk_dmabuf_downloader_download (display->egl_downloader,
download->texture,
@@ -127,8 +129,9 @@ gdk_dmabuf_texture_invoke_callback (gpointer data)
{
/* Successfully downloaded using Vulkan */
}
#endif
#ifdef HAVE_DMABUF
else if (gdk_dmabuf_download_mmap (GDK_TEXTURE (download->texture),
if (gdk_dmabuf_download_mmap (GDK_TEXTURE (download->texture),
download->format,
download->color_state,
download->data,
@@ -208,6 +211,9 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
GdkColorState *color_state;
int width, height;
gboolean premultiplied;
GdkMemoryFormat format;
GdkDataFormat data_format;
gboolean is_yuv;
display = gdk_dmabuf_texture_builder_get_display (builder);
width = gdk_dmabuf_texture_builder_get_width (builder);
@@ -221,14 +227,39 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
error))
return NULL;
if (gdk_memory_format_find_by_dmabuf_fourcc (dmabuf.fourcc, premultiplied, &format))
{
is_yuv = FALSE;
}
else if (gdk_data_format_find_by_dmabuf_fourcc (dmabuf.fourcc, &data_format))
{
format = gdk_data_format_get_conversion (data_format);
is_yuv = gdk_data_format_is_yuv (data_format);
}
else
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf format %.4s",
(char *) &dmabuf.fourcc);
return NULL;
}
gdk_display_init_dmabuf (display);
if (!gdk_dmabuf_formats_contains (display->dmabuf_formats, dmabuf.fourcc, dmabuf.modifier))
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf format: %.4s:%#" G_GINT64_MODIFIER "x",
(char *) &dmabuf.fourcc, dmabuf.modifier);
return NULL;
}
color_state = gdk_dmabuf_texture_builder_get_color_state (builder);
if (color_state == NULL)
{
gboolean is_yuv;
if (gdk_dmabuf_fourcc_is_yuv (dmabuf.fourcc, &is_yuv) && is_yuv)
if (is_yuv)
{
g_warning_once ("FIXME: Implement the proper colorstate for YUV dmabufs");
color_state = gdk_color_state_get_srgb ();
@@ -244,27 +275,9 @@ gdk_dmabuf_texture_new_from_builder (GdkDmabufTextureBuilder *builder,
NULL);
g_set_object (&self->display, display);
GDK_TEXTURE (self)->format = format;
self->dmabuf = dmabuf;
if (!gdk_dmabuf_get_memory_format (dmabuf.fourcc, premultiplied, &(GDK_TEXTURE (self)->format)))
{
GDK_DISPLAY_DEBUG (display, DMABUF,
"Falling back to generic RGBA for dmabuf format %.4s",
(char *) &dmabuf.fourcc);
GDK_TEXTURE (self)->format = premultiplied ? GDK_MEMORY_R8G8B8A8_PREMULTIPLIED
: GDK_MEMORY_R8G8B8A8;
}
if (!gdk_dmabuf_formats_contains (display->dmabuf_formats, dmabuf.fourcc, dmabuf.modifier))
{
g_set_error (error,
GDK_DMABUF_ERROR, GDK_DMABUF_ERROR_UNSUPPORTED_FORMAT,
"Unsupported dmabuf format: %.4s:%#" G_GINT64_MODIFIER "x",
(char *) &dmabuf.fourcc, dmabuf.modifier);
g_object_unref (self);
return NULL;
}
GDK_DISPLAY_DEBUG (display, DMABUF,
"Creating dmabuf texture, format %.4s:%#" G_GINT64_MODIFIER "x, %s%u planes, memory format %u",
(char *) &dmabuf.fourcc, dmabuf.modifier,

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

@@ -15,6 +15,7 @@ gdk_public_sources = files([
'gdkcontentproviderimpl.c',
'gdkcontentserializer.c',
'gdkcursor.c',
'gdkdataformat.c',
'gdkdevice.c',
'gdkdevicepad.c',
'gdkdevicetool.c',

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))