Commit 3be8eddd authored by Eric Anholt's avatar Eric Anholt

drm/vc4: Add exec flags to allow forcing a specific X/Y tile walk order.

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: default avatarEric Anholt <eric@anholt.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20170725162733.28007-2-eric@anholt.netReviewed-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent fb95992a
...@@ -99,6 +99,7 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data, ...@@ -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_BRANCHES:
case DRM_VC4_PARAM_SUPPORTS_ETC1: case DRM_VC4_PARAM_SUPPORTS_ETC1:
case DRM_VC4_PARAM_SUPPORTS_THREADED_FS: case DRM_VC4_PARAM_SUPPORTS_THREADED_FS:
case DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER:
args->value = true; args->value = true;
break; break;
default: default:
......
...@@ -1007,7 +1007,10 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, ...@@ -1007,7 +1007,10 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
struct ww_acquire_ctx acquire_ctx; struct ww_acquire_ctx acquire_ctx;
int ret = 0; 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); DRM_DEBUG("Unknown flags: 0x%02x\n", args->flags);
return -EINVAL; return -EINVAL;
} }
......
...@@ -261,8 +261,17 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec, ...@@ -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 max_y_tile = args->max_y_tile;
uint8_t xtiles = max_x_tile - min_x_tile + 1; uint8_t xtiles = max_x_tile - min_x_tile + 1;
uint8_t ytiles = max_y_tile - min_y_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; 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; size = VC4_PACKET_TILE_RENDERING_MODE_CONFIG_SIZE;
loop_body_size = VC4_PACKET_TILE_COORDINATES_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, ...@@ -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->height);
rcl_u16(setup, args->color_write.bits); rcl_u16(setup, args->color_write.bits);
for (y = min_y_tile; y <= max_y_tile; y++) { for (yi = 0; yi < ytiles; yi++) {
for (x = min_x_tile; x <= max_x_tile; x++) { int y = positive_y ? min_y_tile + yi : max_y_tile - yi;
bool first = (x == min_x_tile && y == min_y_tile); for (xi = 0; xi < xtiles; xi++) {
bool last = (x == max_x_tile && y == max_y_tile); 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); emit_tile(exec, setup, x, y, first, last);
} }
......
...@@ -155,6 +155,16 @@ struct drm_vc4_submit_cl { ...@@ -155,6 +155,16 @@ struct drm_vc4_submit_cl {
__u32 pad:24; __u32 pad:24;
#define VC4_SUBMIT_CL_USE_CLEAR_COLOR (1 << 0) #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; __u32 flags;
/* Returned value of the seqno of this render job (for the /* Returned value of the seqno of this render job (for the
...@@ -294,6 +304,7 @@ struct drm_vc4_get_hang_state { ...@@ -294,6 +304,7 @@ struct drm_vc4_get_hang_state {
#define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3 #define DRM_VC4_PARAM_SUPPORTS_BRANCHES 3
#define DRM_VC4_PARAM_SUPPORTS_ETC1 4 #define DRM_VC4_PARAM_SUPPORTS_ETC1 4
#define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5 #define DRM_VC4_PARAM_SUPPORTS_THREADED_FS 5
#define DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER 6
struct drm_vc4_get_param { struct drm_vc4_get_param {
__u32 param; __u32 param;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment