summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2017-05-02 03:18:00 (GMT)
committerVarad Gautam <varadgautam@gmail.com>2017-05-25 12:34:41 (GMT)
commit9ceaf735f9433202396af0a1ce373d9f4001e7b2 (patch)
tree6bf2fcefef8a6fd49b864299f894fc8d6b7e702a
parent45b4c2ba9715e600e6266ef6fd8cbaf75762ee8c (diff)
downloadmesa-for-daniels/wip/2017-05/dri3-v1.1.tar.gz
mesa-for-daniels/wip/2017-05/dri3-v1.1.tar.xz
DRI3: Use supported modifiers when allocating DRI imagesfor-daniels/wip/2017-05/dri3-v1.1
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
-rw-r--r--src/loader/loader_dri3_helper.c188
-rw-r--r--src/loader/loader_dri3_helper.h5
2 files changed, 146 insertions, 47 deletions
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index cecd02b..9319659 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -40,6 +40,10 @@
#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
#define DRI_CONF_VBLANK_ALWAYS_SYNC 3
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID ((1ULL<<56) - 1)
+#endif
+
static inline void
dri3_fence_reset(xcb_connection_t *c, struct loader_dri3_buffer *buffer)
{
@@ -814,6 +818,27 @@ dri3_cpp_for_format(uint32_t format) {
}
}
+/* the DRIimage createImage function takes __DRI_IMAGE_FORMAT codes, while
+ * the createImageFromFds call takes __DRI_IMAGE_FOURCC codes. To avoid
+ * complete confusion, just deal in __DRI_IMAGE_FORMAT codes for now and
+ * translate to __DRI_IMAGE_FOURCC codes in the call to createImageFromFds
+ */
+static int
+image_format_to_fourcc(int format)
+{
+
+ /* Convert from __DRI_IMAGE_FORMAT to __DRI_IMAGE_FOURCC (sigh) */
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_SARGB8: return __DRI_IMAGE_FOURCC_SARGB8888;
+ case __DRI_IMAGE_FORMAT_RGB565: return __DRI_IMAGE_FOURCC_RGB565;
+ case __DRI_IMAGE_FORMAT_XRGB8888: return __DRI_IMAGE_FOURCC_XRGB8888;
+ case __DRI_IMAGE_FORMAT_ARGB8888: return __DRI_IMAGE_FOURCC_ARGB8888;
+ case __DRI_IMAGE_FORMAT_ABGR8888: return __DRI_IMAGE_FOURCC_ABGR8888;
+ case __DRI_IMAGE_FORMAT_XBGR8888: return __DRI_IMAGE_FOURCC_XBGR8888;
+ }
+ return 0;
+}
+
/** loader_dri3_alloc_render_buffer
*
* Use the driver createImage function to construct a __DRIimage, then
@@ -830,8 +855,10 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
xcb_pixmap_t pixmap;
xcb_sync_fence_t sync_fence;
struct xshmfence *shm_fence;
- int buffer_fd, fence_fd;
- int stride;
+ int buffer_fds[4], fence_fd;
+ uint32_t fourcc_format;
+ int num_planes = 0;
+ int i, mod;
/* Create an xshmfence object and
* prepare to send that to the X server
@@ -855,14 +882,45 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
if (!buffer->cpp)
goto no_image;
+ fourcc_format = image_format_to_fourcc(format);
+ if (!fourcc_format)
+ goto no_image;
+
if (!draw->is_different_gpu) {
- buffer->image = draw->ext->image->createImage(draw->dri_screen,
- width, height,
- format,
- __DRI_IMAGE_USE_SHARE |
- __DRI_IMAGE_USE_SCANOUT |
- __DRI_IMAGE_USE_BACKBUFFER,
- buffer);
+#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1
+ if (draw->multiplanes_available &&
+ draw->ext->image->base.version >= 16 &&
+ draw->ext->image->queryDmaBufModifiers &&
+ draw->ext->image->createImageWithModifiers) {
+ uint64_t *modifiers = NULL;
+ int count;
+
+ draw->ext->image->queryDmaBufModifiers(draw->dri_screen, fourcc_format,
+ 0, NULL, &count);
+ modifiers = malloc(count * sizeof(uint64_t));
+ if (!modifiers)
+ goto no_image;
+ draw->ext->image->queryDmaBufModifiers(draw->dri_screen, fourcc_format,
+ count, modifiers, &count);
+
+ buffer->image = draw->ext->image->createImageWithModifiers(draw->dri_screen,
+ width, height,
+ format,
+ modifiers, count,
+ buffer);
+ free(modifiers);
+ }
+#endif
+
+ if (!buffer->image)
+ buffer->image = draw->ext->image->createImage(draw->dri_screen,
+ width, height,
+ format,
+ __DRI_IMAGE_USE_SHARE |
+ __DRI_IMAGE_USE_SCANOUT |
+ __DRI_IMAGE_USE_BACKBUFFER,
+ buffer);
+
pixmap_buffer = buffer->image;
if (!buffer->image)
@@ -890,25 +948,82 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
goto no_linear_buffer;
}
- /* X wants the stride, so ask the image for it
+ /* X want some information about the planes, so ask the image for it
*/
- if (!draw->ext->image->queryImage(pixmap_buffer, __DRI_IMAGE_ATTRIB_STRIDE,
- &stride))
- goto no_buffer_attrib;
-
- buffer->pitch = stride;
+ draw->ext->image->queryImage(pixmap_buffer, __DRI_IMAGE_ATTRIB_NUM_PLANES,
+ &num_planes);
+ if (num_planes <= 0)
+ num_planes = 1;
+
+ for (i = 0; i < num_planes; i++) {
+ __DRIimage *image = draw->ext->image->fromPlanar(pixmap_buffer, i, NULL);
+ int ret;
+ if (!image)
+ image = pixmap_buffer;
+ ret = draw->ext->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD,
+ &buffer_fds[i]);
+ if (!ret) {
+ if (image != pixmap_buffer)
+ draw->ext->image->destroyImage(image);
+ goto no_buffer_attrib;
+ }
+ ret = draw->ext->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE,
+ &buffer->strides[i]);
+ if (!ret) {
+ if (image != pixmap_buffer)
+ draw->ext->image->destroyImage(image);
+ goto no_buffer_attrib;
+ }
+ ret = draw->ext->image->queryImage(image, __DRI_IMAGE_ATTRIB_OFFSET,
+ &buffer->offsets[i]);
+ if (!ret)
+ buffer->offsets[i] = 0;
+ if (image != pixmap_buffer)
+ draw->ext->image->destroyImage(image);
+ }
- if (!draw->ext->image->queryImage(pixmap_buffer, __DRI_IMAGE_ATTRIB_FD,
- &buffer_fd))
- goto no_buffer_attrib;
+ if (!draw->ext->image->queryImage(pixmap_buffer,
+ __DRI_IMAGE_ATTRIB_MODIFIER_UPPER,
+ &mod)) {
+ buffer->modifier = DRM_FORMAT_MOD_INVALID;
+ } else {
+ buffer->modifier = (uint64_t) mod << 32;
+ if (!draw->ext->image->queryImage(pixmap_buffer,
+ __DRI_IMAGE_ATTRIB_MODIFIER_LOWER,
+ &mod)) {
+ buffer->modifier = DRM_FORMAT_MOD_INVALID;
+ } else {
+ buffer->modifier |= (uint64_t)(mod & 0xffffffff);
+ }
+ }
- xcb_dri3_pixmap_from_buffer(draw->conn,
- (pixmap = xcb_generate_id(draw->conn)),
- draw->drawable,
- buffer->size,
- width, height, buffer->pitch,
- depth, buffer->cpp * 8,
- buffer_fd);
+#if XCB_DRI3_MAJOR_VERSION > 1 || XCB_DRI3_MINOR_VERSION >= 1
+ if (draw->multiplanes_available) {
+ xcb_dri3_pixmap_from_buffers(draw->conn,
+ (pixmap = xcb_generate_id(draw->conn)),
+ draw->drawable,
+ num_planes,
+ width, height,
+ buffer->strides[0], buffer->offsets[0],
+ buffer->strides[1], buffer->offsets[1],
+ buffer->strides[2], buffer->offsets[2],
+ buffer->strides[3], buffer->offsets[3],
+ fourcc_format,
+ buffer->modifier >> 32,
+ buffer->modifier & 0xffffffff,
+ buffer_fds);
+ }
+ else
+#endif
+ {
+ xcb_dri3_pixmap_from_buffer(draw->conn,
+ (pixmap = xcb_generate_id(draw->conn)),
+ draw->drawable,
+ buffer->size,
+ width, height, buffer->strides[0],
+ depth, buffer->cpp * 8,
+ buffer_fds[0]);
+ }
xcb_dri3_fence_from_fd(draw->conn,
pixmap,
@@ -930,6 +1045,8 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format,
return buffer;
no_buffer_attrib:
+ while (--i >= 0)
+ close(buffer_fds[i]);
draw->ext->image->destroyImage(pixmap_buffer);
no_linear_buffer:
if (draw->is_different_gpu)
@@ -1054,27 +1171,6 @@ dri3_update_drawable(__DRIdrawable *driDrawable,
return true;
}
-/* the DRIimage createImage function takes __DRI_IMAGE_FORMAT codes, while
- * the createImageFromFds call takes __DRI_IMAGE_FOURCC codes. To avoid
- * complete confusion, just deal in __DRI_IMAGE_FORMAT codes for now and
- * translate to __DRI_IMAGE_FOURCC codes in the call to createImageFromFds
- */
-static int
-image_format_to_fourcc(int format)
-{
-
- /* Convert from __DRI_IMAGE_FORMAT to __DRI_IMAGE_FOURCC (sigh) */
- switch (format) {
- case __DRI_IMAGE_FORMAT_SARGB8: return __DRI_IMAGE_FOURCC_SARGB8888;
- case __DRI_IMAGE_FORMAT_RGB565: return __DRI_IMAGE_FOURCC_RGB565;
- case __DRI_IMAGE_FORMAT_XRGB8888: return __DRI_IMAGE_FOURCC_XRGB8888;
- case __DRI_IMAGE_FORMAT_ARGB8888: return __DRI_IMAGE_FOURCC_ARGB8888;
- case __DRI_IMAGE_FORMAT_ABGR8888: return __DRI_IMAGE_FOURCC_ABGR8888;
- case __DRI_IMAGE_FORMAT_XBGR8888: return __DRI_IMAGE_FOURCC_XBGR8888;
- }
- return 0;
-}
-
__DRIimage *
loader_dri3_create_image(xcb_connection_t *c,
xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index 247c75d..a2e327a 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -61,8 +61,11 @@ struct loader_dri3_buffer {
bool busy; /* Set on swap, cleared on IdleNotify */
bool own_pixmap; /* We allocated the pixmap ID, free on destroy */
+ uint32_t num_planes;
uint32_t size;
- uint32_t pitch;
+ int strides[4];
+ int offsets[4];
+ uint64_t modifier;
uint32_t cpp;
uint32_t flags;
uint32_t width, height;