configure.ac | 18 ++ exynos/exynos_fimg2d.c | 23 --- include/drm/drm.h | 10 + include/drm/drm_mode.h | 37 ++++ include/drm/nouveau_drm.h | 1 intel/intel_chipset.h | 11 + nouveau/abi16.c | 3 nouveau/nouveau.h | 1 nouveau/pushbuf.c | 4 radeon/r600_pci_ids.h | 1 tests/exynos/exynos_fimg2d_test.c | 112 ++------------ tests/kmstest/main.c | 1 tests/modetest/buffers.c | 30 +-- tests/modetest/modetest.c | 49 +++--- xf86drm.c | 14 - xf86drmMode.c | 289 ++++++++++++++++++++++++++++++++++++-- xf86drmMode.h | 24 +++ 17 files changed, 459 insertions(+), 169 deletions(-)
New commits: commit ba4b5ac010ab85406ec52e3906e13d58cd9aa782 Author: Emil Velikov <emil.l.veli...@gmail.com> Date: Mon Jun 29 19:25:35 2015 +0100 configure.ac: bump version to 2.4.62 for release Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/configure.ac b/configure.ac index 32d034e..1456b90 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_PREREQ([2.63]) AC_INIT([libdrm], - [2.4.61], + [2.4.62], [https://bugs.freedesktop.org/enter_bug.cgi?product=DRI], [libdrm]) commit 2bf0d5bf63cda5a0abd79f2fd4b5737cb852b476 Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:14 2015 +0200 tests/exynos: handle G2D_IMGBUF_COLOR in switch statements This fixes a compiler warning about missing handling of enum values in the switch statements. Also remove the silent mapping to G2D_IMGBUF_GEM when an unknown buffer type is encountered. We have full control about the type here, and if it's unknown then we obviously have a bug in the code. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index 59de4ba..8794dac 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -270,9 +270,10 @@ static int g2d_copy_test(struct exynos_device *dev, struct exynos_bo *src, src_img.user_ptr[0].userptr = userptr; src_img.user_ptr[0].size = size; break; + case G2D_IMGBUF_COLOR: default: - type = G2D_IMGBUF_GEM; - break; + ret = -EFAULT; + goto fail; } printf("copy test with %s.\n", @@ -306,6 +307,7 @@ err_free_userptr: if (userptr) free((void *)userptr); +fail: g2d_fini(ctx); return ret; @@ -349,9 +351,10 @@ static int g2d_copy_with_scale_test(struct exynos_device *dev, src_img.user_ptr[0].userptr = userptr; src_img.user_ptr[0].size = size; break; + case G2D_IMGBUF_COLOR: default: - type = G2D_IMGBUF_GEM; - break; + ret = -EFAULT; + goto fail; } printf("copy and scale test with %s.\n", @@ -390,6 +393,7 @@ err_free_userptr: if (userptr) free((void *)userptr); +fail: g2d_fini(ctx); return 0; @@ -435,9 +439,10 @@ static int g2d_blend_test(struct exynos_device *dev, src_img.user_ptr[0].userptr = userptr; src_img.user_ptr[0].size = size; break; + case G2D_IMGBUF_COLOR: default: - type = G2D_IMGBUF_GEM; - break; + ret = -EFAULT; + goto fail; } printf("blend test with %s.\n", @@ -487,6 +492,7 @@ err_free_userptr: if (userptr) free((void *)userptr); +fail: g2d_fini(ctx); return 0; @@ -532,6 +538,7 @@ static int g2d_checkerboard_test(struct exynos_device *dev, src_img.user_ptr[0].userptr = (unsigned long)checkerboard; src_img.user_ptr[0].size = img_w * img_h * 4; break; + case G2D_IMGBUF_COLOR: default: ret = -EFAULT; goto fail; commit b26c8efb6566e78d12a93fee7c01f6857e07f611 Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:13 2015 +0200 tests/exynos: remove connector_find_plane No test uses DRM planes at the moment so this function is never called. Inspection of the git history shows that DRM planes were also never used in these tests in the past. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index 1ec7340..59de4ba 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -112,37 +112,6 @@ static void connector_find_mode(int fd, struct connector *c, c->crtc = c->encoder->crtc_id; } -static int connector_find_plane(int fd, unsigned int *plane_id) -{ - drmModePlaneRes *plane_resources; - drmModePlane *ovr; - int i; - - plane_resources = drmModeGetPlaneResources(fd); - if (!plane_resources) { - fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", - strerror(errno)); - return -1; - } - - for (i = 0; i < plane_resources->count_planes; i++) { - plane_id[i] = 0; - - ovr = drmModeGetPlane(fd, plane_resources->planes[i]); - if (!ovr) { - fprintf(stderr, "drmModeGetPlane failed: %s\n", - strerror(errno)); - continue; - } - - if (ovr->possible_crtcs & (1 << 0)) - plane_id[i] = ovr->plane_id; - drmModeFreePlane(ovr); - } - - return 0; -} - static int drm_set_crtc(struct exynos_device *dev, struct connector *c, unsigned int fb_id) { commit 13ad10afc306a76f9a61e6a339e412a34a59bfe4 Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:12 2015 +0200 tests/exynos: simplify drm_set_crtc We can just return 'ret' here, the goto serves no purpose. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index de6a2b7..1ec7340 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -150,14 +150,9 @@ static int drm_set_crtc(struct exynos_device *dev, struct connector *c, ret = drmModeSetCrtc(dev->fd, c->crtc, fb_id, 0, 0, &c->id, 1, c->mode); - if (ret) { + if (ret) drmMsg("failed to set mode: %s\n", strerror(errno)); - goto err; - } - - return 0; -err: return ret; } commit 28d896c763e0cc2ab8f9679ee75b756bdd587da7 Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:11 2015 +0200 tests/exynos: remove struct fimg2d_test_case It doesn't make sense to keep this structure, since we can just call all tests directly. An inspection of the git history shows that no code ever used this abstraction in the past. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index 080d178..de6a2b7 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -37,30 +37,6 @@ static unsigned int screen_width, screen_height; -/* - * A structure to test fimg2d hw. - * - * @solid_fill: fill given color data to source buffer. - * @copy: copy source to destination buffer. - * @copy_with_scale: copy source to destination buffer scaling up or - * down properly. - * @blend: blend source to destination buffer. - */ -struct fimg2d_test_case { - int (*solid_fill)(struct exynos_device *dev, struct exynos_bo *dst); - int (*copy)(struct exynos_device *dev, struct exynos_bo *src, - struct exynos_bo *dst, enum e_g2d_buf_type); - int (*copy_with_scale)(struct exynos_device *dev, - struct exynos_bo *src, struct exynos_bo *dst, - enum e_g2d_buf_type); - int (*blend)(struct exynos_device *dev, - struct exynos_bo *src, struct exynos_bo *dst, - enum e_g2d_buf_type); - int (*checkerboard)(struct exynos_device *dev, - struct exynos_bo *src, struct exynos_bo *dst, - enum e_g2d_buf_type); -}; - struct connector { uint32_t id; char mode_str[64]; @@ -630,14 +606,6 @@ fail: return ret; } -static struct fimg2d_test_case test_case = { - .solid_fill = &g2d_solid_fill_test, - .copy = &g2d_copy_test, - .copy_with_scale = &g2d_copy_with_scale_test, - .blend = &g2d_blend_test, - .checkerboard = &g2d_checkerboard_test, -}; - static void usage(char *name) { fprintf(stderr, "usage: %s [-s]\n", name); @@ -747,7 +715,7 @@ int main(int argc, char **argv) if (ret < 0) goto err_rm_fb; - ret = test_case.solid_fill(dev, bo); + ret = g2d_solid_fill_test(dev, bo); if (ret < 0) { fprintf(stderr, "failed to solid fill operation.\n"); goto err_rm_fb; @@ -761,7 +729,7 @@ int main(int argc, char **argv) goto err_rm_fb; } - ret = test_case.copy(dev, src, bo, G2D_IMGBUF_GEM); + ret = g2d_copy_test(dev, src, bo, G2D_IMGBUF_GEM); if (ret < 0) { fprintf(stderr, "failed to test copy operation.\n"); goto err_free_src; @@ -769,7 +737,7 @@ int main(int argc, char **argv) wait_for_user_input(0); - ret = test_case.copy_with_scale(dev, src, bo, G2D_IMGBUF_GEM); + ret = g2d_copy_with_scale_test(dev, src, bo, G2D_IMGBUF_GEM); if (ret < 0) { fprintf(stderr, "failed to test copy and scale operation.\n"); goto err_free_src; @@ -777,7 +745,7 @@ int main(int argc, char **argv) wait_for_user_input(0); - ret = test_case.checkerboard(dev, src, bo, G2D_IMGBUF_GEM); + ret = g2d_checkerboard_test(dev, src, bo, G2D_IMGBUF_GEM); if (ret < 0) { fprintf(stderr, "failed to issue checkerboard test.\n"); goto err_free_src; @@ -794,7 +762,7 @@ int main(int argc, char **argv) * Disable the test for now, until the kernel code has been sanitized. */ #if 0 - ret = test_case.blend(dev, src, bo, G2D_IMGBUF_USERPTR); + ret = g2d_blend_test(dev, src, bo, G2D_IMGBUF_USERPTR); if (ret < 0) fprintf(stderr, "failed to test blend operation.\n"); commit 3aeea6198d3c62bab2ce98450f47ff91e402784b Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:10 2015 +0200 tests/exynos: remove unused define It doesn't make sense to limit the number of test cases anyway. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index 6af9277..080d178 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -34,7 +34,6 @@ #include "exynos_fimg2d.h" #define DRM_MODULE_NAME "exynos" -#define MAX_TEST_CASE 8 static unsigned int screen_width, screen_height; commit 0536d33f077ef92b5e9577c32a8772dd79f31c43 Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:09 2015 +0200 tests/exynos: clean struct connector Remove all unused struct members. An inspection of the git history shows that these members were also never used in the past. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index 64dacfa..6af9277 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -65,17 +65,9 @@ struct fimg2d_test_case { struct connector { uint32_t id; char mode_str[64]; - char format_str[5]; - unsigned int fourcc; drmModeModeInfo *mode; drmModeEncoder *encoder; int crtc; - int pipe; - int plane_zpos; - unsigned int fb_id[2], current_fb_id; - struct timeval start; - - int swap_count; }; static void connector_find_mode(int fd, struct connector *c, @@ -750,8 +742,6 @@ int main(int argc, char **argv) if (ret < 0) goto err_destroy_buffer; - con.plane_zpos = -1; - memset(bo->vaddr, 0xff, screen_width * screen_height * 4); ret = drm_set_crtc(dev, &con, fb_id); commit 53b1081da1b05e6225d93d4a6890fba4eba8313e Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:08 2015 +0200 exynos/fimg2d: simplify g2d_fini() free()ing a nullptr is a noop, so remove the check. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c index 5ea42e6..24a06d0 100644 --- a/exynos/exynos_fimg2d.c +++ b/exynos/exynos_fimg2d.c @@ -254,8 +254,7 @@ struct g2d_context *g2d_init(int fd) void g2d_fini(struct g2d_context *ctx) { - if (ctx) - free(ctx); + free(ctx); } /** commit 8d8bbbb9722c3eed3e2736da95d2fef4613d97fb Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:07 2015 +0200 tests/exynos: replace return by break The 'usage' function already does exit(0), so that this 'return -EINVAL' is never called. Just put a break there to avoid confusion. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/tests/exynos/exynos_fimg2d_test.c b/tests/exynos/exynos_fimg2d_test.c index e64bb32..64dacfa 100644 --- a/tests/exynos/exynos_fimg2d_test.c +++ b/tests/exynos/exynos_fimg2d_test.c @@ -689,7 +689,7 @@ int main(int argc, char **argv) break; default: usage(argv[0]); - return -EINVAL; + break; } } commit 7da8f07274cfe57cfd157e184f1f0b4c15405b9e Author: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Date: Fri Jun 12 20:15:06 2015 +0200 exynos: fimg2d: fix return codes Even if flushing the command buffer doesn't succeed, the G2D calls would still return zero. Fix this by just passing the flush return code. In fact error handling currently ignores the fact that g2d_add_cmd() can fail. This is going to be handled in a later patch. Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de> Acked-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/exynos/exynos_fimg2d.c b/exynos/exynos_fimg2d.c index 86ae898..5ea42e6 100644 --- a/exynos/exynos_fimg2d.c +++ b/exynos/exynos_fimg2d.c @@ -330,9 +330,7 @@ g2d_solid_fill(struct g2d_context *ctx, struct g2d_image *img, bitblt.data.fast_solid_color_fill_en = 1; g2d_add_cmd(ctx, BITBLT_COMMAND_REG, bitblt.val); - g2d_flush(ctx); - - return 0; + return g2d_flush(ctx); } /** @@ -415,9 +413,7 @@ g2d_copy(struct g2d_context *ctx, struct g2d_image *src, rop4.data.unmasked_rop3 = G2D_ROP3_SRC; g2d_add_cmd(ctx, ROP4_REG, rop4.val); - g2d_flush(ctx); - - return 0; + return g2d_flush(ctx); } /** @@ -527,9 +523,7 @@ g2d_copy_with_scale(struct g2d_context *ctx, struct g2d_image *src, pt.data.y = dst_y + dst_h; g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val); - g2d_flush(ctx); - - return 0; + return g2d_flush(ctx); } /** @@ -636,9 +630,7 @@ g2d_blend(struct g2d_context *ctx, struct g2d_image *src, pt.data.y = dst_y + h; g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val); - g2d_flush(ctx); - - return 0; + return g2d_flush(ctx); } /** @@ -766,7 +758,5 @@ g2d_scale_and_blend(struct g2d_context *ctx, struct g2d_image *src, pt.data.y = dst_y + dst_h; g2d_add_cmd(ctx, DST_RIGHT_BOTTOM_REG, pt.val); - g2d_flush(ctx); - - return 0; + return g2d_flush(ctx); } commit 47a2de27a0f087908e3063fdd6dfdececd2db75b Author: Matt Turner <matts...@gmail.com> Date: Mon Jun 22 09:56:33 2015 -0700 configure: Add flag to disable valgrind support. v2 [Emil Velikov]: Autodetect valgrind. Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/configure.ac b/configure.ac index 78a0010..32d034e 100644 --- a/configure.ac +++ b/configure.ac @@ -403,11 +403,25 @@ else fi AM_CONDITIONAL([HAVE_MANPAGES_STYLESHEET], [test "x$HAVE_MANPAGES_STYLESHEET" = "xyes"]) +AC_ARG_ENABLE(valgrind, + [AS_HELP_STRING([--enable-valgrind], + [Build libdrm with valgrind support (default: auto)])], + [VALGRIND=$enableval], [VALGRIND=yes]) PKG_CHECK_MODULES(VALGRIND, [valgrind], [have_valgrind=yes], [have_valgrind=no]) -if test "x$have_valgrind" = "xyes"; then +AC_MSG_CHECKING([whether to enable Valgrind support]) +if test "x$VALGRIND" = xauto; then + VALGRIND="$have_valgrind" +fi + +if test "x$VALGRIND" = "xyes"; then + if ! test "x$have_valgrind" = xyes; then + AC_MSG_ERROR([Valgrind support required but not present]) + fi AC_DEFINE([HAVE_VALGRIND], 1, [Use valgrind intrinsics to suppress false warnings]) fi +AC_MSG_RESULT([$VALGRIND]) + AC_ARG_WITH([kernel-source], [AS_HELP_STRING([--with-kernel-source], [specify path to linux kernel source])], commit 5f76273d51fee5c176302ae5f57673461b80333b Author: Emil Velikov <emil.l.veli...@gmail.com> Date: Mon Jun 29 17:32:21 2015 +0100 xf86drmMode: include config.h before anything else Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/xf86drmMode.c b/xf86drmMode.c index 206d1c2..f4b8d14 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -37,6 +37,11 @@ * TODO the types we are after are defined in diffrent headers on diffrent * platforms find which headers to include to get uint32_t */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <limits.h> #include <stdint.h> #include <stdlib.h> @@ -44,10 +49,6 @@ #include <stdio.h> #include <stdbool.h> -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - #include "xf86drmMode.h" #include "xf86drm.h" #include <drm.h> commit 8426967d4e34ef5924a30166662c60d1003072bd Author: Emil Velikov <emil.l.veli...@gmail.com> Date: Mon Jun 22 17:58:05 2015 +0000 xf86drmMode: remove unused valgrind(VG) macros Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/xf86drmMode.c b/xf86drmMode.c index 73c8695..206d1c2 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -56,14 +56,6 @@ #include <unistd.h> #include <errno.h> -#ifdef HAVE_VALGRIND -#include <valgrind.h> -#include <memcheck.h> -#define VG(x) x -#else -#define VG(x) -#endif - #define memclear(s) memset(&s, 0, sizeof(s)) #define U642VOID(x) ((void *)(unsigned long)(x)) commit 32471b265c6fbce6d519f0420a0ffeb608296502 Author: Daniel Stone <dani...@collabora.com> Date: Mon Jun 22 17:26:03 2015 +0100 Add blob property create/destroy ioctl wrappers v2: Use memclear to zero out structure. Signed-off-by: Daniel Stone <dani...@collabora.com> Reviewed-by: Rob Clark <robcl...@freedesktop.org> diff --git a/include/drm/drm.h b/include/drm/drm.h index d1dc3e3..167b7b8 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -766,6 +766,8 @@ struct drm_prime_handle { #define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) #define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) #define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic) +#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob) +#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob) /** * Device specific ioctls should only be in their respective headers diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 66f856f..69c1ac3 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -523,4 +523,25 @@ struct drm_mode_atomic { __u64 user_data; }; +/** + * Create a new 'blob' data property, copying length bytes from data pointer, + * and returning new blob ID. + */ +struct drm_mode_create_blob { + /** Pointer to data to copy. */ + __u64 data; + /** Length of data to copy. */ + __u32 length; + /** Return: new property ID. */ + __u32 blob_id; +}; + +/** + * Destroy a user-created blob property. + */ +struct drm_mode_destroy_blob { + __u32 blob_id; +}; + + #endif diff --git a/xf86drmMode.c b/xf86drmMode.c index a75eca3..73c8695 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -1387,3 +1387,37 @@ out: return ret; } + +int +drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id) +{ + struct drm_mode_create_blob create; + int ret; + + if (length >= 0xffffffff) + return -ERANGE; + + memclear(create); + + create.length = length; + create.data = (uintptr_t) data; + create.blob_id = 0; + *id = 0; + + ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create); + if (ret != 0) + return ret; + + *id = create.blob_id; + return 0; +} + +int +drmModeDestroyPropertyBlob(int fd, uint32_t id) +{ + struct drm_mode_destroy_blob destroy; + + memclear(destroy); + destroy.blob_id = id; + return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy); +} diff --git a/xf86drmMode.h b/xf86drmMode.h index 317ea23..1c10023 100644 --- a/xf86drmMode.h +++ b/xf86drmMode.h @@ -503,6 +503,11 @@ extern int drmModeAtomicCommit(int fd, uint32_t flags, void *user_data); +extern int drmModeCreatePropertyBlob(int fd, const void *data, size_t size, + uint32_t *id); +extern int drmModeDestroyPropertyBlob(int fd, uint32_t id); + + #if defined(__cplusplus) || defined(c_plusplus) } #endif commit ed44e0b9585c563905447eceed12af9c1c7ca8d4 Author: Ville Syrjälä <ville.syrj...@linux.intel.com> Date: Mon Jun 22 17:26:02 2015 +0100 Support atomic modesetting ioctl Add support for the atomic modesetting ioctl through a property-set API. v1: Squashed intermediate patches from Ville, Rob and myself. Updated for current kernel interface (no blobs). v2: Rewrite user-facing API to provide transactional/cursor interface. Use memclear to zero out ioctl. Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com> Signed-off-by: Rob Clark <robcl...@freedesktop.org> Signed-off-by: Daniel Stone <dani...@collabora.com> v3 [Emil Velikov]: Remove DRM_CAP_ATOMIC - superseded by DRM_CLIENT_CAP_ATOMIC. Signed-off-by: Emil Velikov <emil.l.veli...@gmail.com> diff --git a/include/drm/drm.h b/include/drm/drm.h index 229a29f..d1dc3e3 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -635,6 +635,13 @@ struct drm_get_cap { */ #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 +/** + * DRM_CLIENT_CAP_ATOMIC + * + * If set to 1, the DRM core will allow atomic modesetting requests. + */ +#define DRM_CLIENT_CAP_ATOMIC 3 + /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ struct drm_set_client_cap { __u64 capability; @@ -758,6 +765,7 @@ struct drm_prime_handle { #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) #define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) #define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) +#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic) /** * Device specific ioctls should only be in their respective headers diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index a2ab88a..66f856f 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -507,4 +507,20 @@ struct drm_mode_destroy_dumb { __u32 handle; }; +/* page-flip flags are valid, plus: */ +#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100 +#define DRM_MODE_ATOMIC_NONBLOCK 0x0200 +#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400 + +struct drm_mode_atomic { + __u32 flags; + __u32 count_objs; + __u64 objs_ptr; + __u64 count_props_ptr; + __u64 props_ptr; + __u64 prop_values_ptr; + __u64 reserved; + __u64 user_data; +}; + #endif diff --git a/xf86drmMode.c b/xf86drmMode.c index 1333da4..a75eca3 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -37,9 +37,12 @@ * TODO the types we are after are defined in diffrent headers on diffrent * platforms find which headers to include to get uint32_t */ +#include <limits.h> #include <stdint.h> +#include <stdlib.h> #include <sys/ioctl.h> #include <stdio.h> +#include <stdbool.h> #ifdef HAVE_CONFIG_H #include "config.h" @@ -1147,3 +1150,240 @@ int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type, return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop); } + +typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr; + +struct _drmModeAtomicReqItem { + uint32_t object_id; + uint32_t property_id; + uint64_t value; +}; + +struct _drmModeAtomicReq { + uint32_t cursor; + uint32_t size_items; + drmModeAtomicReqItemPtr items; +}; + +drmModeAtomicReqPtr drmModeAtomicAlloc(void) +{ + drmModeAtomicReqPtr req; + + req = drmMalloc(sizeof *req); + if (!req) + return NULL; + + req->items = NULL; + req->cursor = 0; + req->size_items = 0; + + return req; +} + +drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old) +{ + drmModeAtomicReqPtr new; + + new = drmMalloc(sizeof *new); + if (!new) + return NULL; + + new->cursor = old->cursor; + new->size_items = old->size_items; + + if (old->size_items) { + new->items = drmMalloc(old->size_items * sizeof(*new->items)); + if (!new->items) { + free(new); + return NULL; + } + memcpy(new->items, old->items, + old->size_items * sizeof(*new->items)); + } else { + new->items = NULL; + } + + return new; +} + +int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment) +{ + if (!augment || augment->cursor == 0) + return 0; + + if (base->cursor + augment->cursor >= base->size_items) { + drmModeAtomicReqItemPtr new; + int saved_size = base->size_items; + + base->size_items = base->cursor + augment->cursor; + new = realloc(base->items, + base->size_items * sizeof(*base->items)); + if (!new) { + base->size_items = saved_size; + return -ENOMEM; + } + base->items = new; + } + + memcpy(&base->items[base->cursor], augment->items, + augment->cursor * sizeof(*augment->items)); + base->cursor += augment->cursor; + + return 0; +} + +int drmModeAtomicGetCursor(drmModeAtomicReqPtr req) +{ + return req->cursor; +} + +void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor) +{ + req->cursor = cursor; +} + +int drmModeAtomicAddProperty(drmModeAtomicReqPtr req, + uint32_t object_id, + uint32_t property_id, + uint64_t value) +{ + if (req->cursor >= req->size_items) { + drmModeAtomicReqItemPtr new; + + req->size_items += 16; + new = realloc(req->items, req->size_items * sizeof(*req->items)); + if (!new) { + req->size_items -= 16; + return -ENOMEM; + } + req->items = new; + } + + req->items[req->cursor].object_id = object_id; + req->items[req->cursor].property_id = property_id; + req->items[req->cursor].value = value; + req->cursor++; + + return req->cursor; +} + +void drmModeAtomicFree(drmModeAtomicReqPtr req) +{ + if (!req) + return; + + if (req->items) + drmFree(req->items); + drmFree(req); +} + +static int sort_req_list(const void *misc, const void *other) +{ + const drmModeAtomicReqItem *first = misc; + const drmModeAtomicReqItem *second = other; + + if (first->object_id < second->object_id) + return -1; + else if (first->object_id > second->object_id) + return 1; + else + return second->property_id - first->property_id; +} + +int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags, + void *user_data) +{ + drmModeAtomicReqPtr sorted = drmModeAtomicDuplicate(req); + struct drm_mode_atomic atomic; + uint32_t *objs_ptr = NULL; + uint32_t *count_props_ptr = NULL; + uint32_t *props_ptr = NULL; + uint64_t *prop_values_ptr = NULL; + uint32_t last_obj_id = 0; + uint32_t i; + int obj_idx = -1; + int ret = -1; + + if (!sorted) + return -ENOMEM; + -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: https://lists.debian.org/e1zajxz-0000q4...@moszumanska.debian.org