[Mesa-dev] [PATCH 4/5] gallium: Expose a PIPE_CAP_TILE_RASTER_ORDER on vc4.

Eric Anholt eric at anholt.net
Thu Oct 5 18:08:24 UTC 2017


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.
---
 include/drm-uapi/vc4_drm.h                       |  6 ++---
 src/gallium/docs/source/screen.rst               |  4 ++-
 src/gallium/drivers/etnaviv/etnaviv_screen.c     |  1 +
 src/gallium/drivers/freedreno/freedreno_screen.c |  1 +
 src/gallium/drivers/i915/i915_screen.c           |  1 +
 src/gallium/drivers/llvmpipe/lp_screen.c         |  1 +
 src/gallium/drivers/nouveau/nv30/nv30_screen.c   |  1 +
 src/gallium/drivers/nouveau/nv50/nv50_screen.c   |  1 +
 src/gallium/drivers/nouveau/nvc0/nvc0_screen.c   |  1 +
 src/gallium/drivers/r300/r300_screen.c           |  1 +
 src/gallium/drivers/r600/r600_pipe.c             |  1 +
 src/gallium/drivers/radeonsi/si_pipe.c           |  1 +
 src/gallium/drivers/softpipe/sp_screen.c         |  1 +
 src/gallium/drivers/svga/svga_screen.c           |  1 +
 src/gallium/drivers/swr/swr_screen.cpp           |  1 +
 src/gallium/drivers/vc4/kernel/vc4_render_cl.c   | 21 +++++++++++----
 src/gallium/drivers/vc4/vc4_blit.c               | 20 ++++++++++++++
 src/gallium/drivers/vc4/vc4_context.h            |  7 +++++
 src/gallium/drivers/vc4/vc4_draw.c               |  8 ++++++
 src/gallium/drivers/vc4/vc4_job.c                |  7 +++++
 src/gallium/drivers/vc4/vc4_screen.c             | 34 ++++++++++++++----------
 src/gallium/drivers/vc4/vc4_simulator.c          |  1 +
 src/gallium/drivers/vc4/vc4_state.c              | 12 +++++++++
 src/gallium/drivers/virgl/virgl_screen.c         |  1 +
 src/gallium/include/pipe/p_defines.h             |  1 +
 src/gallium/include/pipe/p_state.h               | 10 +++++++
 26 files changed, 122 insertions(+), 23 deletions(-)

diff --git a/include/drm-uapi/vc4_drm.h b/include/drm-uapi/vc4_drm.h
index ae8167c9612e..afae87004963 100644
--- a/include/drm-uapi/vc4_drm.h
+++ b/include/drm-uapi/vc4_drm.h
@@ -21,8 +21,8 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef _VC4_DRM_H_
-#define _VC4_DRM_H_
+#ifndef _UAPI_VC4_DRM_H_
+#define _UAPI_VC4_DRM_H_
 
 #include "drm.h"
 
@@ -337,4 +337,4 @@ struct drm_vc4_label_bo {
 }
 #endif
 
-#endif /* _VC4_DRM_H_ */
+#endif /* _UAPI_VC4_DRM_H_ */
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index 553b8e661a4f..658d1749dff5 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -406,7 +406,9 @@ The integer capabilities:
 * ``PIPE_CAP_MEMOBJ``: Whether operations on memory objects are supported.
 * ``PIPE_CAP_LOAD_CONSTBUF``: True if the driver supports TGSI_OPCODE_LOAD use
   with constant buffers.
-
+* ``PIPE_CAP_TILE_RASTER_ORDER``: Whether the driver supports
+  GL_MESA_tile_raster_order, using the tile_raster_order_* fields in
+  pipe_rasterizer_state.
 
 .. _pipe_capf:
 
diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
index ffc23c77726d..dca6c9300a5a 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
@@ -264,6 +264,7 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_QUERY_SO_OVERFLOW:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
 
    /* Stream output. */
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index e8d84f477664..91b270da0015 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -325,6 +325,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
 	case PIPE_CAP_QUERY_SO_OVERFLOW:
 	case PIPE_CAP_MEMOBJ:
 	case PIPE_CAP_LOAD_CONSTBUF:
+	case PIPE_CAP_TILE_RASTER_ORDER:
 		return 0;
 
 	case PIPE_CAP_MAX_VIEWPORTS:
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 88e66ba68417..05a9a39d4520 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -317,6 +317,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
    case PIPE_CAP_QUERY_SO_OVERFLOW:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
 
    case PIPE_CAP_MAX_VIEWPORTS:
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index ab2ba3a19a8b..d14745f1f5cd 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -360,6 +360,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
    }
    /* should only get here on unhandled cases */
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index a66b4fbe67b0..b5a857056317 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -224,6 +224,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_QUERY_SO_OVERFLOW:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index 479283e1b7cc..8cda31fbeabe 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -276,6 +276,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_QUERY_SO_OVERFLOW:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index ac850c493daf..6b24a80d9594 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -305,6 +305,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_QUERY_SO_OVERFLOW:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 894c0d996b1a..6b7bf91d91b9 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -246,6 +246,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_QUERY_SO_OVERFLOW:
         case PIPE_CAP_MEMOBJ:
         case PIPE_CAP_LOAD_CONSTBUF:
+        case PIPE_CAP_TILE_RASTER_ORDER:
             return 0;
 
         /* SWTCL-only features. */
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 655b5411ed5e..2ddc977f0db5 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -402,6 +402,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_QUERY_SO_OVERFLOW:
 	case PIPE_CAP_MEMOBJ:
 	case PIPE_CAP_LOAD_CONSTBUF:
+	case PIPE_CAP_TILE_RASTER_ORDER:
 		return 0;
 
 	case PIPE_CAP_DOUBLES:
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 33f5adbd3ad9..7bac9d865c96 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -577,6 +577,7 @@ static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 	case PIPE_CAP_UMA:
 	case PIPE_CAP_POLYGON_MODE_FILL_RECTANGLE:
 	case PIPE_CAP_POST_DEPTH_COVERAGE:
+	case PIPE_CAP_TILE_RASTER_ORDER:
 		return 0;
 
 	case PIPE_CAP_QUERY_BUFFER_OBJECT:
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 93fc76054caa..804bee4020e4 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -311,6 +311,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_NIR_SAMPLERS_AS_DEREF:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
    case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
       return 4;
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 7901e819de42..39b73525994d 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -456,6 +456,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_QUERY_SO_OVERFLOW:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
    }
 
diff --git a/src/gallium/drivers/swr/swr_screen.cpp b/src/gallium/drivers/swr/swr_screen.cpp
index df23e354f48e..b5386fe37188 100644
--- a/src/gallium/drivers/swr/swr_screen.cpp
+++ b/src/gallium/drivers/swr/swr_screen.cpp
@@ -342,6 +342,7 @@ swr_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_QUERY_SO_OVERFLOW:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
 
    case PIPE_CAP_VENDOR_ID:
diff --git a/src/gallium/drivers/vc4/kernel/vc4_render_cl.c b/src/gallium/drivers/vc4/kernel/vc4_render_cl.c
index b926d35a6233..2da797899b66 100644
--- a/src/gallium/drivers/vc4/kernel/vc4_render_cl.c
+++ b/src/gallium/drivers/vc4/kernel/vc4_render_cl.c
@@ -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);
 		}
diff --git a/src/gallium/drivers/vc4/vc4_blit.c b/src/gallium/drivers/vc4/vc4_blit.c
index 7f4c76968e77..660fa28aedd3 100644
--- a/src/gallium/drivers/vc4/vc4_blit.c
+++ b/src/gallium/drivers/vc4/vc4_blit.c
@@ -47,6 +47,19 @@ is_tile_unaligned(unsigned size, unsigned tile_size)
         return size & (tile_size - 1);
 }
 
+static uint32_t
+vc4_blitter_overlap_flags(const struct pipe_blit_info *info)
+{
+        uint32_t flags = VC4_SUBMIT_CL_FIXED_RCL_ORDER;
+
+        if (info->src.box.x > info->dst.box.x)
+                flags |= VC4_SUBMIT_CL_RCL_ORDER_INCREASING_X;
+        if (info->src.box.y > info->dst.box.y)
+                flags |= VC4_SUBMIT_CL_RCL_ORDER_INCREASING_Y;
+
+        return flags;
+}
+
 static bool
 vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
 {
@@ -152,6 +165,7 @@ vc4_tile_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
         job->msaa = msaa;
         job->needs_flush = true;
         job->resolve |= PIPE_CLEAR_COLOR;
+        job->flags = vc4_blitter_overlap_flags(info);
 
         vc4_job_submit(vc4, job);
 
@@ -205,7 +219,13 @@ vc4_render_blit(struct pipe_context *ctx, struct pipe_blit_info *info)
         }
 
         vc4_blitter_save(vc4);
+
+        if (info->src.resource == info->dst.resource) {
+                vc4->blitter_overlap_draw_flags =
+                        vc4_blitter_overlap_flags(info);
+        }
         util_blitter_blit(vc4->blitter, info);
+        vc4->blitter_overlap_draw_flags = 0;
 
         return true;
 }
diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h
index 99ec7e5d2e82..3bc38929f592 100644
--- a/src/gallium/drivers/vc4/vc4_context.h
+++ b/src/gallium/drivers/vc4/vc4_context.h
@@ -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;
 };
 
@@ -329,6 +332,7 @@ struct vc4_context {
 
         struct slab_child_pool transfer_pool;
         struct blitter_context *blitter;
+        uint32_t blitter_overlap_draw_flags;
 
         /** bitfield of VC4_DIRTY_* */
         uint32_t dirty;
@@ -398,6 +402,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 {
diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c
index 1370867293f7..9522bb94dda8 100644
--- a/src/gallium/drivers/vc4/vc4_draw.c
+++ b/src/gallium/drivers/vc4/vc4_draw.c
@@ -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) {
diff --git a/src/gallium/drivers/vc4/vc4_job.c b/src/gallium/drivers/vc4/vc4_job.c
index 6a1d1a4cebfe..2a9b58d5ebae 100644
--- a/src/gallium/drivers/vc4/vc4_job.c
+++ b/src/gallium/drivers/vc4/vc4_job.c
@@ -264,6 +264,12 @@ 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.
+         */
+        job->flags = vc4->rasterizer->tile_raster_order_flags;
+
         vc4->job = job;
 
         return job;
@@ -461,6 +467,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;
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index b31d2937a914..1c0088c48dbc 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -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:
@@ -582,20 +602,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)
 {
diff --git a/src/gallium/drivers/vc4/vc4_simulator.c b/src/gallium/drivers/vc4/vc4_simulator.c
index ff306f296104..cf9821236f38 100644
--- a/src/gallium/drivers/vc4/vc4_simulator.c
+++ b/src/gallium/drivers/vc4/vc4_simulator.c
@@ -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;
 
diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c
index 17aa7eb39715..ed8d404a4f36 100644
--- a/src/gallium/drivers/vc4/vc4_state.c
+++ b/src/gallium/drivers/vc4/vc4_state.c
@@ -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;
 }
 
diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c
index ecdd47581207..cb04c5b0f015 100644
--- a/src/gallium/drivers/virgl/virgl_screen.c
+++ b/src/gallium/drivers/virgl/virgl_screen.c
@@ -269,6 +269,7 @@ virgl_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_QUERY_SO_OVERFLOW:
    case PIPE_CAP_MEMOBJ:
    case PIPE_CAP_LOAD_CONSTBUF:
+   case PIPE_CAP_TILE_RASTER_ORDER:
       return 0;
    case PIPE_CAP_VENDOR_ID:
       return 0x1af4;
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 155d0e3979c3..356dba301c54 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -777,6 +777,7 @@ enum pipe_cap
    PIPE_CAP_QUERY_SO_OVERFLOW,
    PIPE_CAP_MEMOBJ,
    PIPE_CAP_LOAD_CONSTBUF,
+   PIPE_CAP_TILE_RASTER_ORDER,
 };
 
 #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 86c7751eb185..10bf678652d5 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -124,6 +124,16 @@ struct pipe_rasterizer_state
     */
    unsigned rasterizer_discard:1;
 
+   /**
+    * Exposed by PIPE_CAP_TILE_RASTER_ORDER.  When true,
+    * tile_raster_order_increasing_* indicate the order that the rasterizer
+    * should render tiles, to meet the requirements of
+    * GL_MESA_tile_raster_order.
+    */
+   unsigned tile_raster_order_fixed:1;
+   unsigned tile_raster_order_increasing_x:1;
+   unsigned tile_raster_order_increasing_y:1;
+
    /**
     * When false, depth clipping is disabled and the depth value will be
     * clamped later at the per-pixel level before depth testing.
-- 
2.14.2



More information about the mesa-dev mailing list