drm/vc4: Add exec flags to allow forcing a specific X/Y tile walk order.
authorEric Anholt <eric@anholt.net>
Tue, 25 Jul 2017 16:27:33 +0000 (09:27 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 8 Aug 2017 20:26:44 +0000 (13:26 -0700)
This is useful to allow GL to provide defined results for overlapping
glBlitFramebuffer, which X11 in turn uses to accelerate uncomposited
window movement without first blitting to a temporary.  x11perf
-copywinwin100 goes from 1850/sec to 4850/sec.

v2: Default to the same behavior as before when the flags aren't
    passed. (suggested by Boris)

Signed-off-by: Eric Anholt <eric@anholt.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20170725162733.28007-2-eric@anholt.net
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
drivers/gpu/drm/vc4/vc4_drv.c
drivers/gpu/drm/vc4/vc4_gem.c
drivers/gpu/drm/vc4/vc4_render_cl.c
include/uapi/drm/vc4_drm.h

index e8f0e1790d5ec066d9e7e52fc866ba9a00bf5581..1c96edcb302be825cb3aeb438ab9a59c63fb6052 100644 (file)
@@ -99,6 +99,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
        case DRM_VC4_PARAM_SUPPORTS_BRANCHES:
        case DRM_VC4_PARAM_SUPPORTS_ETC1:
        case DRM_VC4_PARAM_SUPPORTS_THREADED_FS:
+       case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER:
                args->value = true;
                break;
        default:
index 22a55cff7e64a4a6ababa7852666b78db0c304c7..d0c6bfb68c4ee9d88c2a026e5908915d331733db 100644 (file)
@@ -1007,7 +1007,10 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
        struct ww_acquire_ctx acquire_ctx;
        int ret = 0;
 
-       if ((args->flags & ~VC4_SUBMIT_CL_USE_CLEAR_COLOR) != 0) {
+       if ((args->flags & ~(VC4_SUBMIT_CL_USE_CLEAR_COLOR |
+                            VC4_SUBMIT_CL_FIXED_RCL_ORDER |
+                            VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X |
+                            VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y)) != 0) {
                DRM_DEBUG("Unknown flags: 0x%02x\n", args->flags);
                return -EINVAL;
        }
index e0539731130b83fe3498281fb55ecb21c81d973e..273984f71ae284760a92252bef233329ce17ef55 100644 (file)
@@ -261,8 +261,17 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
        uint8_t max_y_tile = args->max_y_tile;
        uint8_t xtiles = max_x_tile - min_x_tile + 1;
        uint8_t ytiles = max_y_tile - min_y_tile + 1;
-       uint8_t x, y;
+       uint8_t xi, yi;
        uint32_t size, loop_body_size;
+       bool positive_x = true;
+       bool positive_y = true;
+
+       if (args->flags & VC4_SUBMIT_CL_FIXED_RCL_ORDER) {
+               if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X))
+                       positive_x = false;
+               if (!(args->flags & VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y))
+                       positive_y = false;
+       }
 
        size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE;
        loop_body_size = VC4_PACKET_TILE_COORDINATES_SIZE;
@@ -354,10 +363,12 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
        rcl_u16(setup, args->height);
        rcl_u16(setup, args->color_write.bits);
 
-       for (y = min_y_tile; y <= max_y_tile; y++) {
-               for (x = min_x_tile; x <= max_x_tile; x++) {
-                       bool first = (x == min_x_tile && y == min_y_tile);
-                       bool last = (x == max_x_tile && y == max_y_tile);
+       for (yi = 0; yi < ytiles; yi++) {
+               int y = positive_y ? min_y_tile + yi : max_y_tile - yi;
+               for (xi = 0; xi < xtiles; xi++) {
+                       int x = positive_x ? min_x_tile + xi : max_x_tile - xi;
+                       bool first = (xi == 0 && yi == 0);
+                       bool last = (xi == xtiles - 1 && yi == ytiles - 1);
 
                        emit_tile(exec, setup, x, y, first, last);
                }
index 551628e571f955b1a69e57276f228ae1fc09af5c..afae870049636e9c5db9a10a03d40dc3beb4c6ee 100644 (file)
@@ -155,6 +155,16 @@ struct drm_vc4_submit_cl {
        __u32 pad:24;
 
 #define VC4_SUBMIT_CL_USE_CLEAR_COLOR                  (1 << 0)
+/* By default, the kernel gets to choose the order that the tiles are
+ * rendered in.  If this is set, then the tiles will be rendered in a
+ * raster order, with the right-to-left vs left-to-right and
+ * top-to-bottom vs bottom-to-top dictated by
+ * VC4_SUBMIT_CL_RCL_ORDER_INCREASING_*.  This allows overlapping
+ * blits to be implemented using the 3D engine.
+ */
+#define VC4_SUBMIT_CL_FIXED_RCL_ORDER                  (1 << 1)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X           (1 << 2)
+#define VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y           (1 << 3)
        __u32 flags;
 
        /* Returned value of the seqno of this render job (for the
@@ -294,6 +304,7 @@ struct drm_vc4_get_hang_state {
 #define DRM_VC4_PARAM_SUPPORTS_BRANCHES                3
 #define DRM_VC4_PARAM_SUPPORTS_ETC1            4
 #define DRM_VC4_PARAM_SUPPORTS_THREADED_FS     5
+#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
 
 struct drm_vc4_get_param {
        __u32 param;