broadcom/vc4: Expose PIPE_CAP_TILE_RASTER_ORDER
authorEric Anholt <eric@anholt.net>
Thu, 27 Jul 2017 19:05:56 +0000 (12:05 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 10 Oct 2017 17:45:22 +0000 (10:45 -0700)
Because vc4 can control the order that tiles are rasterized in, we can use
it to implement overlapping blits using normal drawing and
GL_ARB_texture_barrier, as long as we can tell the kernel what order to
render the tiles in.

v2: Fix on the simulator.
v3: Add the cap (disabled) to other drivers, add rst docs for the cap.
v4: Rebase on PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS
v5: Split from the core gallium commit, drop some unnecessary code related
    to glBlitFramebuffer(), fix a crash with clears before state has been
    bound.

src/gallium/drivers/vc4/kernel/vc4_render_cl.c
src/gallium/drivers/vc4/vc4_context.h
src/gallium/drivers/vc4/vc4_draw.c
src/gallium/drivers/vc4/vc4_job.c
src/gallium/drivers/vc4/vc4_screen.c
src/gallium/drivers/vc4/vc4_simulator.c
src/gallium/drivers/vc4/vc4_state.c

index b926d35a62333e927a03175f2af91c2c1a45b65e..2da797899b666adfe9ced8973438e892e920f2bb 100644 (file)
@@ -255,8 +255,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;
@@ -348,10 +357,12 @@ static int vc4_create_rcl_bo(struct drm_device *dev, struct vc4_exec_info *exec,
                rcl_u32(setup, 0); /* no address, since we're in None mode */
        }
 
-       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 99ec7e5d2e827a7af22f23f89555ffdb4ad40484..4a1e4093f1a08e52532d8c36e53267693fa0a04e 100644 (file)
@@ -303,6 +303,9 @@ struct vc4_job {
          */
         uint32_t draw_calls_queued;
 
+        /** Any flags to be passed in drm_vc4_submit_cl.flags. */
+        uint32_t flags;
+
         struct vc4_job_key key;
 };
 
@@ -398,6 +401,9 @@ struct vc4_rasterizer_state {
                 uint8_t point_size[V3D21_POINT_SIZE_length];
                 uint8_t line_width[V3D21_LINE_WIDTH_length];
         } packed;
+
+        /** Raster order flags to be passed in struct drm_vc4_submit_cl.flags. */
+        uint32_t tile_raster_order_flags;
 };
 
 struct vc4_depth_stencil_alpha_state {
index 1370867293f7dd6d0549a995501c5b5fc09ebbf0..9522bb94dda845b187e1e994f2ddf7356af1fb0d 100644 (file)
@@ -308,6 +308,14 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
         struct vc4_job *job = vc4_get_job_for_fbo(vc4);
 
+        /* Make sure that the raster order flags haven't changed, which can
+         * only be set at job granularity.
+         */
+        if (job->flags != vc4->rasterizer->tile_raster_order_flags) {
+                vc4_job_submit(vc4, job);
+                job = vc4_get_job_for_fbo(vc4);
+        }
+
         vc4_get_draw_cl_space(job, info->count);
 
         if (vc4->prim_mode != info->mode) {
index 6a1d1a4cebfe512799130c17ac822e3e5afba5fb..7fe20c16bad917637e5255c3a5e5bba7c740c4fb 100644 (file)
@@ -264,6 +264,13 @@ vc4_get_job_for_fbo(struct vc4_context *vc4)
         job->draw_tiles_y = DIV_ROUND_UP(vc4->framebuffer.height,
                                          job->tile_height);
 
+        /* Initialize the job with the raster order flags -- each draw will
+         * check that we haven't changed the flags, since that requires a
+         * flush.
+         */
+        if (vc4->rasterizer)
+                job->flags = vc4->rasterizer->tile_raster_order_flags;
+
         vc4->job = job;
 
         return job;
@@ -461,6 +468,7 @@ vc4_job_submit(struct vc4_context *vc4, struct vc4_job *job)
                 submit.clear_z = job->clear_depth;
                 submit.clear_s = job->clear_stencil;
         }
+        submit.flags |= job->flags;
 
         if (!(vc4_debug & VC4_DEBUG_NORAST)) {
                 int ret;
index 120e404fa410f8f829dfd6e3a508a91749809545..9879a4db174980d231f572325e51d566232ad639 100644 (file)
@@ -113,9 +113,25 @@ vc4_screen_destroy(struct pipe_screen *pscreen)
         ralloc_free(pscreen);
 }
 
+static bool
+vc4_has_feature(struct vc4_screen *screen, uint32_t feature)
+{
+        struct drm_vc4_get_param p = {
+                .param = feature,
+        };
+        int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p);
+
+        if (ret != 0)
+                return false;
+
+        return p.value;
+}
+
 static int
 vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 {
+        struct vc4_screen *screen = vc4_screen(pscreen);
+
         switch (param) {
                 /* Supported features (boolean caps). */
         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
@@ -135,6 +151,10 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
         case PIPE_CAP_TEXTURE_BARRIER:
                 return 1;
 
+        case PIPE_CAP_TILE_RASTER_ORDER:
+                return vc4_has_feature(screen,
+                                       DRM_VC4_PARAM_SUPPORTS_FIXED_RCL_ORDER);
+
                 /* lying for GL 2.0 */
         case PIPE_CAP_OCCLUSION_QUERY:
         case PIPE_CAP_POINT_SPRITE:
@@ -266,7 +286,6 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_MEMOBJ:
         case PIPE_CAP_LOAD_CONSTBUF:
        case PIPE_CAP_TGSI_ANY_REG_AS_ADDRESS:
-       case PIPE_CAP_TILE_RASTER_ORDER:
                 return 0;
 
                 /* Stream output. */
@@ -589,20 +608,6 @@ static int handle_compare(void *key1, void *key2)
     return PTR_TO_UINT(key1) != PTR_TO_UINT(key2);
 }
 
-static bool
-vc4_has_feature(struct vc4_screen *screen, uint32_t feature)
-{
-        struct drm_vc4_get_param p = {
-                .param = feature,
-        };
-        int ret = vc4_ioctl(screen->fd, DRM_IOCTL_VC4_GET_PARAM, &p);
-
-        if (ret != 0)
-                return false;
-
-        return p.value;
-}
-
 static bool
 vc4_get_chip_info(struct vc4_screen *screen)
 {
index ff306f2961042a79ef7c7fff10b8e2eb94e21805..cf9821236f382644b6b339877a57d8c720f6bfd5 100644 (file)
@@ -615,6 +615,7 @@ vc4_simulator_get_param_ioctl(int fd, struct drm_vc4_get_param *args)
         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;
                 return 0;
 
index 17aa7eb39715ea938ec35ee8726390ea26484560..ed8d404a4f3601d27ed5f78a273a9cf1a1bec21e 100644 (file)
@@ -135,6 +135,18 @@ vc4_create_rasterizer_state(struct pipe_context *pctx,
         V3D21_POINT_SIZE_pack(NULL, so->packed.point_size, &point_size);
         V3D21_LINE_WIDTH_pack(NULL, so->packed.line_width, &line_width);
 
+        if (cso->tile_raster_order_fixed) {
+                so->tile_raster_order_flags |= VC4_SUBMIT_CL_FIXED_RCL_ORDER;
+                if (cso->tile_raster_order_increasing_x) {
+                        so->tile_raster_order_flags |=
+                                VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X;
+                }
+                if (cso->tile_raster_order_increasing_y) {
+                        so->tile_raster_order_flags |=
+                                VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y;
+                }
+        }
+
         return so;
 }