aboutsummaryrefslogtreecommitdiffstats
path: root/src/gbm/backends/dri/gbm_dri.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gbm/backends/dri/gbm_dri.c')
-rw-r--r--src/gbm/backends/dri/gbm_dri.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index cb3bfe1c2fb..a7ac1493658 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -39,6 +39,7 @@
#include <unistd.h>
#include <dlfcn.h>
#include <xf86drm.h>
+#include <drm_fourcc.h>
#include <GL/gl.h> /* dri_interface needs GL types */
#include <GL/internal/dri_interface.h>
@@ -53,6 +54,14 @@
#include "../../../egl/wayland/wayland-drm/wayland-drm.h"
#endif
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
+#endif
+
+#ifndef DRM_FORMAT_MOD_LINEAR
+#define DRM_FORMAT_MOD_LINEAR 0
+#endif
+
static __DRIimage *
dri_lookup_egl_image(__DRIscreen *screen, void *image, void *data)
{
@@ -735,6 +744,38 @@ gbm_dri_bo_get_offset(struct gbm_bo *_bo, int plane)
return (uint32_t)offset;
}
+static uint64_t
+gbm_dri_bo_get_modifier(struct gbm_bo *_bo)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
+ struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
+
+ if (!dri->image || dri->image->base.version < 14) {
+ errno = ENOSYS;
+ return DRM_FORMAT_MOD_INVALID;
+ }
+
+ /* Dumb buffers have no modifiers */
+ if (!bo->image)
+ return DRM_FORMAT_MOD_LINEAR;
+
+ uint64_t ret = 0;
+ int mod;
+ if (!dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER,
+ &mod))
+ return DRM_FORMAT_MOD_INVALID;
+
+ ret = (uint64_t)mod << 32;
+
+ if (!dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER,
+ &mod))
+ return DRM_FORMAT_MOD_INVALID;
+
+ ret |= mod;
+
+ return ret;
+}
+
static void
gbm_dri_bo_destroy(struct gbm_bo *_bo)
{
@@ -1278,6 +1319,7 @@ dri_device_create(int fd)
dri->base.base.bo_get_handle = gbm_dri_bo_get_handle_for_plane;
dri->base.base.bo_get_stride = gbm_dri_bo_get_stride;
dri->base.base.bo_get_offset = gbm_dri_bo_get_offset;
+ dri->base.base.bo_get_modifier = gbm_dri_bo_get_modifier;
dri->base.base.bo_destroy = gbm_dri_bo_destroy;
dri->base.base.destroy = dri_destroy;
dri->base.base.surface_create = gbm_dri_surface_create;