#include <time.h>
#ifdef HAVE_LIBDRM
#include <xf86drm.h>
-#include <drm_fourcc.h>
+#include "drm-uapi/drm_fourcc.h"
#endif
#include <GL/gl.h>
#include <GL/internal/dri_interface.h>
#include "util/u_vector.h"
#include "mapi/glapi/glapi.h"
+/* Additional definitions not yet in the drm_fourcc.h.
+ */
+#ifndef DRM_FORMAT_P010
+#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') /* 2x2 subsampled Cb:Cr plane 10 bits per channel */
+#endif
+
+#ifndef DRM_FORMAT_P012
+#define DRM_FORMAT_P012 fourcc_code('P', '0', '1', '2') /* 2x2 subsampled Cb:Cr plane 12 bits per channel */
+#endif
+
+#ifndef DRM_FORMAT_P016
+#define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cb:Cr plane 16 bits per channel */
+#endif
+
#define NUM_ATTRIBS 12
static void
dri_is_thread_safe(void *loaderPrivate)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
- _EGLDisplay *display = dri2_surf->base.Resource.Display;
+ MAYBE_UNUSED _EGLDisplay *display = dri2_surf->base.Resource.Display;
#ifdef HAVE_X11_PLATFORM
Display *xdpy = (Display*)display->PlatformDisplay;
bind_to_texture_rgb = 0;
bind_to_texture_rgba = 0;
- for (int i = 0; dri2_dpy->core->indexConfigAttrib(dri_config, i, &attrib,
- &value); ++i) {
+ for (int i = 0; i < __DRI_ATTRIB_MAX; ++i) {
+ if (!dri2_dpy->core->indexConfigAttrib(dri_config, i, &attrib, &value))
+ break;
+
switch (attrib) {
case __DRI_ATTRIB_RENDER_TYPE:
if (value & __DRI_ATTRIB_RGBA_BIT)
search_path_vars);
}
-EGLBoolean
-dri2_load_driver_dri3(_EGLDisplay *disp)
+static EGLBoolean
+dri2_load_driver_common(_EGLDisplay *disp,
+ const struct dri2_extension_match *driver_extensions)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
const __DRIextension **extensions;
if (!extensions)
return EGL_FALSE;
- if (!dri2_bind_extensions(dri2_dpy, dri3_driver_extensions, extensions, false)) {
+ if (!dri2_bind_extensions(dri2_dpy, driver_extensions, extensions, false)) {
dlclose(dri2_dpy->driver);
return EGL_FALSE;
}
EGLBoolean
dri2_load_driver(_EGLDisplay *disp)
{
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- const __DRIextension **extensions;
-
- extensions = dri2_open_driver(disp);
- if (!extensions)
- return EGL_FALSE;
-
- if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions, false)) {
- dlclose(dri2_dpy->driver);
- return EGL_FALSE;
- }
- dri2_dpy->driver_extensions = extensions;
-
- dri2_bind_extensions(dri2_dpy, optional_driver_extensions, extensions, true);
+ return dri2_load_driver_common(disp, dri2_driver_extensions);
+}
- return EGL_TRUE;
+EGLBoolean
+dri2_load_driver_dri3(_EGLDisplay *disp)
+{
+ return dri2_load_driver_common(disp, dri3_driver_extensions);
}
EGLBoolean
dri2_load_driver_swrast(_EGLDisplay *disp)
{
- struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- const __DRIextension **extensions;
-
- extensions = dri2_open_driver(disp);
- if (!extensions)
- return EGL_FALSE;
-
- if (!dri2_bind_extensions(dri2_dpy, swrast_driver_extensions, extensions, false)) {
- dlclose(dri2_dpy->driver);
- return EGL_FALSE;
- }
- dri2_dpy->driver_extensions = extensions;
-
- dri2_bind_extensions(dri2_dpy, optional_driver_extensions, extensions, true);
-
- return EGL_TRUE;
+ return dri2_load_driver_common(disp, swrast_driver_extensions);
}
static unsigned
case _EGL_PLATFORM_SURFACELESS:
ret = dri2_initialize_surfaceless(drv, disp);
break;
+ case _EGL_PLATFORM_DEVICE:
+ ret = dri2_initialize_device(drv, disp);
+ break;
case _EGL_PLATFORM_X11:
ret = dri2_initialize_x11(drv, disp);
break;
EGLBoolean
dri2_init_surface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type,
- _EGLConfig *conf, const EGLint *attrib_list, EGLBoolean enable_out_fence)
+ _EGLConfig *conf, const EGLint *attrib_list,
+ EGLBoolean enable_out_fence, void *native_surface)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
dri2_surf->enable_out_fence = enable_out_fence;
}
- return _eglInitSurface(surf, disp, type, conf, attrib_list);
+ return _eglInitSurface(surf, disp, type, conf, attrib_list, native_surface);
}
static void
dri2_surface_set_out_fence_fd(surf, fence_fd);
}
+EGLBoolean
+dri2_create_drawable(struct dri2_egl_display *dri2_dpy,
+ const __DRIconfig *config,
+ struct dri2_egl_surface *dri2_surf,
+ void *loaderPrivate)
+{
+ __DRIcreateNewDrawableFunc createNewDrawable;
+
+ if (dri2_dpy->image_driver)
+ createNewDrawable = dri2_dpy->image_driver->createNewDrawable;
+ else if (dri2_dpy->dri2)
+ createNewDrawable = dri2_dpy->dri2->createNewDrawable;
+ else if (dri2_dpy->swrast)
+ createNewDrawable = dri2_dpy->swrast->createNewDrawable;
+ else
+ return _eglError(EGL_BAD_ALLOC, "no createNewDrawable");
+
+ dri2_surf->dri_drawable = (*createNewDrawable)(dri2_dpy->dri_screen,
+ config, loaderPrivate);
+ if (dri2_surf->dri_drawable == NULL)
+ return _eglError(EGL_BAD_ALLOC, "createNewDrawable");
+
+ return EGL_TRUE;
+}
+
/**
* Called via eglMakeCurrent(), drv->API.MakeCurrent().
*/
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
case DRM_FORMAT_AYUV:
+ case DRM_FORMAT_XYUV8888:
return 1;
case DRM_FORMAT_NV12:
case DRM_FORMAT_NV21:
case DRM_FORMAT_NV16:
case DRM_FORMAT_NV61:
+ case DRM_FORMAT_P010:
+ case DRM_FORMAT_P012:
+ case DRM_FORMAT_P016:
return 2;
case DRM_FORMAT_YUV410:
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+ EGLint nplanes;
(void) drv;
if (!dri2_can_export_dma_buf_image(disp, img))
return EGL_FALSE;
+ /* EGL_MESA_image_dma_buf_export spec says:
+ * "If the number of fds is less than the number of planes, then
+ * subsequent fd slots should contain -1."
+ */
+ if (fds) {
+ /* Query nplanes so that we know how big the given array is. */
+ dri2_dpy->image->queryImage(dri2_img->dri_image,
+ __DRI_IMAGE_ATTRIB_NUM_PLANES, &nplanes);
+ memset(fds, -1, nplanes * sizeof(int));
+ }
+
/* rework later to provide multiple fds/strides/offsets */
if (fds)
dri2_dpy->image->queryImage(dri2_img->dri_image,