summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/hwdec/hwdec_vaapi.c451
-rw-r--r--video/out/vulkan/context_wayland.c2
-rw-r--r--video/out/vulkan/context_xlib.c2
-rw-r--r--wscript5
-rw-r--r--wscript_build.py2
5 files changed, 304 insertions, 158 deletions
diff --git a/video/out/hwdec/hwdec_vaapi.c b/video/out/hwdec/hwdec_vaapi.c
index 2ff0d98df3..eed79799e9 100644
--- a/video/out/hwdec/hwdec_vaapi.c
+++ b/video/out/hwdec/hwdec_vaapi.c
@@ -20,9 +20,6 @@
#include <assert.h>
#include <unistd.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
#include <va/va_drmcommon.h>
#include <libavutil/common.h>
@@ -34,8 +31,17 @@
#include "video/out/gpu/hwdec.h"
#include "video/mp_image_pool.h"
#include "video/vaapi.h"
-#include "common.h"
-#include "ra_gl.h"
+
+#if HAVE_VULKAN
+#include "video/out/placebo/ra_pl.h"
+#include "video/out/vulkan/common.h"
+#endif
+
+#if HAVE_GL
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include "video/out/opengl/common.h"
+#include "video/out/opengl/ra_gl.h"
#include "libmpv/render_gl.h"
#ifndef GL_OES_EGL_image
@@ -53,6 +59,8 @@ typedef void *EGLImageKHR;
#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
#endif
+#endif // HAVE_GL
+
#if HAVE_VAAPI_X11
#include <va/va_x11.h>
@@ -124,9 +132,12 @@ struct priv_owner {
struct priv {
int num_planes;
+ struct mp_image layout;
struct ra_tex *tex[4];
+#if HAVE_GL
GLuint gl_textures[4];
EGLImageKHR images[4];
+#endif
VAImage current_image;
bool buffer_acquired;
#if VA_CHECK_VERSION(1, 1, 0)
@@ -135,11 +146,13 @@ struct priv {
bool surface_acquired;
#endif
+#if HAVE_GL
EGLImageKHR (EGLAPIENTRY *CreateImageKHR)(EGLDisplay, EGLContext,
EGLenum, EGLClientBuffer,
const EGLint *);
EGLBoolean (EGLAPIENTRY *DestroyImageKHR)(EGLDisplay, EGLImageKHR);
void (EGLAPIENTRY *EGLImageTargetTexture2DOES)(GLenum, GLeglImageOES);
+#endif
};
static void determine_working_formats(struct ra_hwdec *hw);
@@ -156,19 +169,38 @@ static int init(struct ra_hwdec *hw)
{
struct priv_owner *p = hw->priv;
- if (!ra_is_gl(hw->ra) || !eglGetCurrentContext())
- return -1;
+#if HAVE_GL
+ if (ra_is_gl(hw->ra)) {
+ if (!eglGetCurrentContext())
+ return -1;
- const char *exts = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
- if (!exts)
- return -1;
+ const char *exts = eglQueryString(eglGetCurrentDisplay(), EGL_EXTENSIONS);
+ if (!exts)
+ return -1;
- GL *gl = ra_gl_get(hw->ra);
- if (!strstr(exts, "EXT_image_dma_buf_import") ||
- !strstr(exts, "EGL_KHR_image_base") ||
- !strstr(gl->extensions, "GL_OES_EGL_image") ||
- !(gl->mpgl_caps & MPGL_CAP_TEX_RG))
- return -1;
+ GL *gl = ra_gl_get(hw->ra);
+ if (!strstr(exts, "EXT_image_dma_buf_import") ||
+ !strstr(exts, "EGL_KHR_image_base") ||
+ !strstr(gl->extensions, "GL_OES_EGL_image") ||
+ !(gl->mpgl_caps & MPGL_CAP_TEX_RG))
+ return -1;
+
+ MP_VERBOSE(hw, "using VAAPI EGL interop\n");
+ }
+#endif
+
+#if HAVE_VULKAN
+ if (ra_pl_get(hw->ra)) {
+ const struct pl_gpu *gpu = ra_pl_get(hw->ra);
+ if (!(gpu->import_caps.tex & PL_HANDLE_DMA_BUF)) {
+ MP_VERBOSE(hw, "VAAPI Vulkan interop requires support for "
+ "dma_buf import in Vulkan.\n");
+ return -1;
+ }
+
+ MP_VERBOSE(hw, "using VAAPI Vulkan interop\n");
+ }
+#endif
p->display = create_native_va_display(hw->ra, hw->log);
if (!p->display) {
@@ -190,8 +222,6 @@ static int init(struct ra_hwdec *hw)
return -1;
}
- MP_VERBOSE(hw, "using VAAPI EGL interop\n");
-
determine_working_formats(hw);
if (!p->formats || !p->formats[0]) {
return -1;
@@ -209,11 +239,26 @@ static void mapper_unmap(struct ra_hwdec_mapper *mapper)
VADisplay *display = p_owner->display;
struct priv *p = mapper->priv;
VAStatus status;
+#if HAVE_GL
+ bool is_gl = ra_is_gl(mapper->ra);
+#endif
+#if HAVE_VULKAN
+ const struct pl_gpu *gpu = ra_pl_get(mapper->ra);
+#endif
for (int n = 0; n < 4; n++) {
- if (p->images[n])
- p->DestroyImageKHR(eglGetCurrentDisplay(), p->images[n]);
- p->images[n] = 0;
+#if HAVE_GL
+ if (is_gl) {
+ if (p->images[n])
+ p->DestroyImageKHR(eglGetCurrentDisplay(), p->images[n]);
+ p->images[n] = 0;
+ }
+#endif
+#if HAVE_VULKAN
+ if (gpu) {
+ ra_tex_free(mapper->ra, &mapper->tex[n]);
+ }
+#endif
}
#if VA_CHECK_VERSION(1, 1, 0)
@@ -238,14 +283,18 @@ static void mapper_unmap(struct ra_hwdec_mapper *mapper)
static void mapper_uninit(struct ra_hwdec_mapper *mapper)
{
+#if HAVE_GL
struct priv *p = mapper->priv;
- GL *gl = ra_gl_get(mapper->ra);
- gl->DeleteTextures(4, p->gl_textures);
- for (int n = 0; n < 4; n++) {
- p->gl_textures[n] = 0;
- ra_tex_free(mapper->ra, &p->tex[n]);
+ if (ra_is_gl(mapper->ra)) {
+ GL *gl = ra_gl_get(mapper->ra);
+ gl->DeleteTextures(4, p->gl_textures);
+ for (int n = 0; n < 4; n++) {
+ p->gl_textures[n] = 0;
+ ra_tex_free(mapper->ra, &p->tex[n]);
+ }
}
+#endif
}
static bool check_fmt(struct ra_hwdec_mapper *mapper, int fmt)
@@ -262,61 +311,71 @@ static int mapper_init(struct ra_hwdec_mapper *mapper)
{
struct priv_owner *p_owner = mapper->owner->priv;
struct priv *p = mapper->priv;
- GL *gl = ra_gl_get(mapper->ra);
+#if HAVE_GL
+ bool is_gl = ra_is_gl(mapper->ra);
+#endif
p->current_image.buf = p->current_image.image_id = VA_INVALID_ID;
- // EGL_KHR_image_base
- p->CreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR");
- p->DestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR");
- // GL_OES_EGL_image
- p->EGLImageTargetTexture2DOES =
- (void *)eglGetProcAddress("glEGLImageTargetTexture2DOES");
-
- if (!p->CreateImageKHR || !p->DestroyImageKHR ||
- !p->EGLImageTargetTexture2DOES)
- return -1;
+#if HAVE_GL
+ if (is_gl) {
+ // EGL_KHR_image_base
+ p->CreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR");
+ p->DestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR");
+ // GL_OES_EGL_image
+ p->EGLImageTargetTexture2DOES =
+ (void *)eglGetProcAddress("glEGLImageTargetTexture2DOES");
+
+ if (!p->CreateImageKHR || !p->DestroyImageKHR ||
+ !p->EGLImageTargetTexture2DOES)
+ return -1;
+ }
+#endif
mapper->dst_params = mapper->src_params;
mapper->dst_params.imgfmt = mapper->src_params.hw_subfmt;
mapper->dst_params.hw_subfmt = 0;
struct ra_imgfmt_desc desc = {0};
- struct mp_image layout = {0};
if (!ra_get_imgfmt_desc(mapper->ra, mapper->dst_params.imgfmt, &desc))
return -1;
p->num_planes = desc.num_planes;
- mp_image_set_params(&layout, &mapper->dst_params);
-
- gl->GenTextures(4, p->gl_textures);
- for (int n = 0; n < desc.num_planes; n++) {
- gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl->BindTexture(GL_TEXTURE_2D, 0);
-
- struct ra_tex_params params = {
- .dimensions = 2,
- .w = mp_image_plane_w(&layout, n),
- .h = mp_image_plane_h(&layout, n),
- .d = 1,
- .format = desc.planes[n],
- .render_src = true,
- .src_linear = true,
- };
-
- if (params.format->ctype != RA_CTYPE_UNORM)
- return -1;
-
- p->tex[n] = ra_create_wrapped_tex(mapper->ra, &params,
- p->gl_textures[n]);
- if (!p->tex[n])
- return -1;
+ mp_image_set_params(&p->layout, &mapper->dst_params);
+
+#if HAVE_GL
+ if (is_gl) {
+ GL *gl = ra_gl_get(mapper->ra);
+ gl->GenTextures(4, p->gl_textures);
+ for (int n = 0; n < desc.num_planes; n++) {
+ gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl->BindTexture(GL_TEXTURE_2D, 0);
+
+ struct ra_tex_params params = {
+ .dimensions = 2,
+ .w = mp_image_plane_w(&p->layout, n),
+ .h = mp_image_plane_h(&p->layout, n),
+ .d = 1,
+ .format = desc.planes[n],
+ .render_src = true,
+ .src_linear = true,
+ };
+
+ if (params.format->ctype != RA_CTYPE_UNORM)
+ return -1;
+
+ p->tex[n] = ra_create_wrapped_tex(mapper->ra, &params,
+ p->gl_textures[n]);
+ if (!p->tex[n])
+ return -1;
+ }
}
+#endif
if (!p_owner->probing_formats && !check_fmt(mapper, mapper->dst_params.imgfmt))
{
@@ -340,9 +399,13 @@ static int mapper_map(struct ra_hwdec_mapper *mapper)
{
struct priv_owner *p_owner = mapper->owner->priv;
struct priv *p = mapper->priv;
- GL *gl = ra_gl_get(mapper->ra);
+#if HAVE_GL
+ bool is_gl = ra_is_gl(mapper->ra);
+#endif
+#if HAVE_VULKAN
+ const struct pl_gpu *gpu = ra_pl_get(mapper->ra);
+#endif
VAStatus status;
- VAImage *va_image = &p->current_image;
VADisplay *display = p_owner->display;
#if VA_CHECK_VERSION(1, 1, 0)
@@ -354,49 +417,110 @@ static int mapper_map(struct ra_hwdec_mapper *mapper)
VA_EXPORT_SURFACE_READ_ONLY |
VA_EXPORT_SURFACE_SEPARATE_LAYERS,
&p->desc);
- if (!CHECK_VA_STATUS(mapper, "vaAcquireSurfaceHandle()")) {
+ if (!CHECK_VA_STATUS(mapper, "vaExportSurfaceHandle()")) {
if (status == VA_STATUS_ERROR_UNIMPLEMENTED)
p->esh_not_implemented = true;
goto esh_failed;
}
p->surface_acquired = true;
- for (int n = 0; n < p->num_planes; n++) {
- int attribs[20] = {EGL_NONE};
- int num_attribs = 0;
-
- ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, p->desc.layers[n].drm_format);
- ADD_ATTRIB(EGL_WIDTH, p->tex[n]->params.w);
- ADD_ATTRIB(EGL_HEIGHT, p->tex[n]->params.h);
-
-#define ADD_PLANE_ATTRIBS(plane) do { \
- ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _FD_EXT, \
- p->desc.objects[p->desc.layers[n].object_index[plane]].fd); \
- ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _OFFSET_EXT, \
- p->desc.layers[n].offset[plane]); \
- ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _PITCH_EXT, \
- p->desc.layers[n].pitch[plane]); \
- } while (0)
-
- ADD_PLANE_ATTRIBS(0);
- if (p->desc.layers[n].num_planes > 1)
- ADD_PLANE_ATTRIBS(1);
- if (p->desc.layers[n].num_planes > 2)
- ADD_PLANE_ATTRIBS(2);
- if (p->desc.layers[n].num_planes > 3)
- ADD_PLANE_ATTRIBS(3);
-
- p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(),
- EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
- if (!p->images[n])
+#if HAVE_GL
+ if (is_gl) {
+ GL *gl = ra_gl_get(mapper->ra);
+ for (int n = 0; n < p->num_planes; n++) {
+ int attribs[20] = {EGL_NONE};
+ int num_attribs = 0;
+
+ ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, p->desc.layers[n].drm_format);
+ ADD_ATTRIB(EGL_WIDTH, p->tex[n]->params.w);
+ ADD_ATTRIB(EGL_HEIGHT, p->tex[n]->params.h);
+
+ #define ADD_PLANE_ATTRIBS(plane) do { \
+ ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _FD_EXT, \
+ p->desc.objects[p->desc.layers[n].object_index[plane]].fd); \
+ ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _OFFSET_EXT, \
+ p->desc.layers[n].offset[plane]); \
+ ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _PITCH_EXT, \
+ p->desc.layers[n].pitch[plane]); \
+ } while (0)
+
+ ADD_PLANE_ATTRIBS(0);
+ if (p->desc.layers[n].num_planes > 1)
+ ADD_PLANE_ATTRIBS(1);
+ if (p->desc.layers[n].num_planes > 2)
+ ADD_PLANE_ATTRIBS(2);
+ if (p->desc.layers[n].num_planes > 3)
+ ADD_PLANE_ATTRIBS(3);
+
+ p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(),
+ EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
+ if (!p->images[n])
+ goto esh_failed;
+
+ gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
+ p->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, p->images[n]);
+
+ mapper->tex[n] = p->tex[n];
+ }
+ gl->BindTexture(GL_TEXTURE_2D, 0);
+ }
+#endif
+#if HAVE_VULKAN
+ if (gpu) {
+ struct ra_imgfmt_desc desc = {0};
+ if (!ra_get_imgfmt_desc(mapper->ra, mapper->dst_params.imgfmt, &desc))
goto esh_failed;
- gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
- p->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, p->images[n]);
-
- mapper->tex[n] = p->tex[n];
+ for (int n = 0; n < p->desc.num_layers; n++) {
+ if (p->desc.layers[n].num_planes > 1) {
+ // Should never happen because we request separate layers
+ MP_ERR(mapper, "Multi-plane VA surfaces are not supported\n");
+ goto esh_failed;
+ }
+
+ const struct ra_format *format = desc.planes[n];
+ int id = p->desc.layers[n].object_index[0];
+ int fd = p->desc.objects[id].fd;
+ uint32_t size = p->desc.objects[id].size;
+ uint32_t offset = p->desc.layers[n].offset[0];
+
+ struct pl_tex_params tex_params = {
+ .w = mp_image_plane_w(&p->layout, n),
+ .h = mp_image_plane_h(&p->layout, n),
+ .d = 0,
+ .format = format->priv,
+ .sampleable = true,
+ .sample_mode = format->linear_filter ? PL_TEX_SAMPLE_LINEAR
+ : PL_TEX_SAMPLE_NEAREST,
+ .import_handle = PL_HANDLE_DMA_BUF,
+ .shared_mem = (struct pl_shared_mem) {
+ .handle = {
+ .fd = fd,
+ },
+ .size = size,
+ .offset = offset,
+ },
+ };
+
+ const struct pl_tex *pltex = pl_tex_create(gpu, &tex_params);
+ if (!pltex) {
+ goto esh_failed;
+ }
+
+ struct ra_tex *ratex = talloc_ptrtype(NULL, ratex);
+ int ret = mppl_wrap_tex(mapper->ra, pltex, ratex);
+ if (!ret) {
+ pl_tex_destroy(gpu, &pltex);
+ talloc_free(ratex);
+ goto esh_failed;
+ }
+ mapper->tex[n] = ratex;
+
+ MP_TRACE(mapper, "Object %d with fd %d imported as %p\n",
+ id, fd, ratex);
+ }
}
- gl->BindTexture(GL_TEXTURE_2D, 0);
+#endif
if (p->desc.fourcc == VA_FOURCC_YV12)
MPSWAP(struct ra_tex*, mapper->tex[1], mapper->tex[2]);
@@ -409,67 +533,80 @@ esh_failed:
close(p->desc.objects[n].fd);
p->surface_acquired = false;
}
-#endif
-
- status = vaDeriveImage(display, va_surface_id(mapper->src), va_image);
- if (!CHECK_VA_STATUS(mapper, "vaDeriveImage()"))
- goto err;
-
- VABufferInfo buffer_info = {.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME};
- status = vaAcquireBufferHandle(display, va_image->buf, &buffer_info);
- if (!CHECK_VA_STATUS(mapper, "vaAcquireBufferHandle()"))
- goto err;
- p->buffer_acquired = true;
-
- int drm_fmts[8] = {
- // 1 bytes per component, 1-4 components
- MKTAG('R', '8', ' ', ' '), // DRM_FORMAT_R8
- MKTAG('G', 'R', '8', '8'), // DRM_FORMAT_GR88
- 0, // untested (DRM_FORMAT_RGB888?)
- 0, // untested (DRM_FORMAT_RGBA8888?)
- // 2 bytes per component, 1-4 components
- MKTAG('R', '1', '6', ' '), // proposed DRM_FORMAT_R16
- MKTAG('G', 'R', '3', '2'), // proposed DRM_FORMAT_GR32
- 0, // N/A
- 0, // N/A
- };
-
- for (int n = 0; n < p->num_planes; n++) {
- int attribs[20] = {EGL_NONE};
- int num_attribs = 0;
-
- const struct ra_format *fmt = p->tex[n]->params.format;
- int n_comp = fmt->num_components;
- int comp_s = fmt->component_size[n] / 8;
- if (n_comp < 1 || n_comp > 3 || comp_s < 1 || comp_s > 2)
- goto err;
- int drm_fmt = drm_fmts[n_comp - 1 + (comp_s - 1) * 4];
- if (!drm_fmt)
+#endif // VA_CHECK_VERSION
+
+#if HAVE_GL
+ if (is_gl) {
+ GL *gl = ra_gl_get(mapper->ra);
+ VAImage *va_image = &p->current_image;
+ status = vaDeriveImage(display, va_surface_id(mapper->src), va_image);
+ if (!CHECK_VA_STATUS(mapper, "vaDeriveImage()"))
goto err;
- ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, drm_fmt);
- ADD_ATTRIB(EGL_WIDTH, p->tex[n]->params.w);
- ADD_ATTRIB(EGL_HEIGHT, p->tex[n]->params.h);
- ADD_ATTRIB(EGL_DMA_BUF_PLANE0_FD_EXT, buffer_info.handle);
- ADD_ATTRIB(EGL_DMA_BUF_PLANE0_OFFSET_EXT, va_image->offsets[n]);
- ADD_ATTRIB(EGL_DMA_BUF_PLANE0_PITCH_EXT, va_image->pitches[n]);
-
- p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(),
- EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
- if (!p->images[n])
+ VABufferInfo buffer_info = {.mem_type = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME};
+ status = vaAcquireBufferHandle(display, va_image->buf, &buffer_info);
+ if (!CHECK_VA_STATUS(mapper, "vaAcquireBufferHandle()"))
goto err;
+ p->buffer_acquired = true;
+
+ int drm_fmts[8] = {
+ // 1 bytes per component, 1-4 components
+ MKTAG('R', '8', ' ', ' '), // DRM_FORMAT_R8
+ MKTAG('G', 'R', '8', '8'), // DRM_FORMAT_GR88
+ 0, // untested (DRM_FORMAT_RGB888?)
+ 0, // untested (DRM_FORMAT_RGBA8888?)
+ // 2 bytes per component, 1-4 components
+ MKTAG('R', '1', '6', ' '), // proposed DRM_FORMAT_R16
+ MKTAG('G', 'R', '3', '2'), // proposed DRM_FORMAT_GR32
+ 0, // N/A
+ 0, // N/A
+ };
- gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
- p->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, p->images[n]);
-
- mapper->tex[n] = p->tex[n];
- }
- gl->BindTexture(GL_TEXTURE_2D, 0);
+ for (int n = 0; n < p->num_planes; n++) {
+ int attribs[20] = {EGL_NONE};
+ int num_attribs = 0;
+
+ const struct ra_format *fmt = p->tex[n]->params.format;
+ int n_comp = fmt->num_components;
+ int comp_s = fmt->component_size[n] / 8;
+ if (n_comp < 1 || n_comp > 3 || comp_s < 1 || comp_s > 2)
+ goto err;
+ int drm_fmt = drm_fmts[n_comp - 1 + (comp_s - 1) * 4];
+ if (!drm_fmt)
+ goto err;
+
+ ADD_ATTRIB(EGL_LINUX_DRM_FOURCC_EXT, drm_fmt);
+ ADD_ATTRIB(EGL_WIDTH, p->tex[n]->params.w);
+ ADD_ATTRIB(EGL_HEIGHT, p->tex[n]->params.h);
+ ADD_ATTRIB(EGL_DMA_BUF_PLANE0_FD_EXT, buffer_info.handle);
+ ADD_ATTRIB(EGL_DMA_BUF_PLANE0_OFFSET_EXT, va_image->offsets[n]);
+ ADD_ATTRIB(EGL_DMA_BUF_PLANE0_PITCH_EXT, va_image->pitches[n]);
+
+ p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(),
+ EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
+ if (!p->images[n])
+ goto err;
+
+ gl->BindTexture(GL_TEXTURE_2D, p->gl_textures[n]);
+ p->EGLImageTargetTexture2DOES(GL_TEXTURE_2D, p->images[n]);
+
+ mapper->tex[n] = p->tex[n];
+ }
+ gl->BindTexture(GL_TEXTURE_2D, 0);
- if (va_image->format.fourcc == VA_FOURCC_YV12)
- MPSWAP(struct ra_tex*, mapper->tex[1], mapper->tex[2]);
+ if (va_image->format.fourcc == VA_FOURCC_YV12)
+ MPSWAP(struct ra_tex*, mapper->tex[1], mapper->tex[2]);
- return 0;
+ return 0;
+ }
+#endif
+#if HAVE_VULKAN
+ // Seems unnecessary to support Vulkan interop with old libva API.
+ if (gpu) {
+ mapper_unmap(mapper);
+ goto err;
+ }
+#endif
err:
if (!p_owner->probing_formats)
diff --git a/video/out/vulkan/context_wayland.c b/video/out/vulkan/context_wayland.c
index f1091a534f..160e8f9da4 100644
--- a/video/out/vulkan/context_wayland.c
+++ b/video/out/vulkan/context_wayland.c
@@ -69,6 +69,8 @@ static bool wayland_vk_init(struct ra_ctx *ctx)
if (!ra_vk_ctx_init(ctx, vk, VK_PRESENT_MODE_MAILBOX_KHR))
goto error;
+ ra_add_native_resource(ctx->ra, "wl", ctx->vo->wl->display);
+
return true;
error:
diff --git a/video/out/vulkan/context_xlib.c b/video/out/vulkan/context_xlib.c
index 9baa7c4dc4..e2fc732e00 100644
--- a/video/out/vulkan/context_xlib.c
+++ b/video/out/vulkan/context_xlib.c
@@ -66,6 +66,8 @@ static bool xlib_init(struct ra_ctx *ctx)
if (!ra_vk_ctx_init(ctx, vk, VK_PRESENT_MODE_FIFO_KHR))
goto error;
+ ra_add_native_resource(ctx->ra, "x11", ctx->vo->x11->display);
+
return true;
error:
diff --git a/wscript b/wscript
index 733faa86c9..121f3613af 100644
--- a/wscript
+++ b/wscript
@@ -827,6 +827,11 @@ video_output_features = [
'deps': 'libplacebo',
'func': check_pkg_config('vulkan'),
}, {
+ 'name': 'vaapi-vulkan',
+ 'desc': 'VAAPI Vulkan',
+ 'deps': 'vaapi && vulkan',
+ 'func': check_true,
+ }, {
'name': 'egl-helpers',
'desc': 'EGL helper functions',
'deps': 'egl-x11 || mali-fbdev || rpi || gl-wayland || egl-drm || ' +
diff --git a/wscript_build.py b/wscript_build.py
index 9438b8c3ed..4c0a12283e 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -449,7 +449,7 @@ def build(ctx):
( "video/out/hwdec/hwdec_cuda.c", "cuda-hwaccel" ),
( "video/out/hwdec/hwdec_cuda_gl.c", "cuda-hwaccel && gl" ),
( "video/out/hwdec/hwdec_cuda_vk.c", "cuda-hwaccel && vulkan" ),
- ( "video/out/hwdec/hwdec_vaapi.c", "vaapi-egl" ),
+ ( "video/out/hwdec/hwdec_vaapi.c", "vaapi-egl || vaapi-vulkan" ),
( "video/out/placebo/ra_pl.c", "libplacebo" ),
( "video/out/placebo/utils.c", "libplacebo" ),
( "video/out/opengl/angle_dynamic.c", "egl-angle" ),