diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2017-05-02 03:18:00 (GMT) |
---|---|---|
committer | Varad Gautam <varadgautam@gmail.com> | 2017-05-25 12:34:41 (GMT) |
commit | 9ceaf735f9433202396af0a1ce373d9f4001e7b2 (patch) | |
tree | 6bf2fcefef8a6fd49b864299f894fc8d6b7e702a | |
parent | 45b4c2ba9715e600e6266ef6fd8cbaf75762ee8c (diff) | |
download | mesa-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.c | 188 | ||||
-rw-r--r-- | src/loader/loader_dri3_helper.h | 5 |
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; |