[Mesa-dev] [PATCH 1/7] gallium: fold u_trim_pipe_prim call from st/mesa to drivers

Marek Olšák maraeo at gmail.com
Fri Apr 14 15:07:08 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

Most drivers don't need it and shouldn't need it because it can't be used
in some cases (indirect draws, primitive restart, count from streamout).
---
 src/gallium/drivers/etnaviv/etnaviv_context.c  |  5 +++++
 src/gallium/drivers/freedreno/freedreno_draw.c |  5 +++++
 src/gallium/drivers/i915/i915_context.c        |  3 +++
 src/gallium/drivers/nouveau/nv30/nv30_vbo.c    |  3 +++
 src/gallium/drivers/r300/r300_render.c         |  3 +++
 src/gallium/drivers/swr/swr_draw.cpp           |  5 +++++
 src/gallium/drivers/vc4/vc4_draw.c             |  5 +++++
 src/gallium/drivers/virgl/virgl_context.c      |  5 +++++
 src/mesa/state_tracker/st_draw.c               | 12 ++----------
 9 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c
index 555aa12..e835edb 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.c
@@ -139,20 +139,25 @@ etna_get_fs(struct etna_context *ctx, struct etna_shader_key key)
 }
 
 static void
 etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 {
    struct etna_context *ctx = etna_context(pctx);
    struct pipe_framebuffer_state *pfb = &ctx->framebuffer_s;
    uint32_t draw_mode;
    unsigned i;
 
+   if (!info->count_from_stream_output && !info->indirect &&
+       !info->primitive_restart &&
+       !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
+      return;
+
    if (ctx->vertex_elements == NULL || ctx->vertex_elements->num_elements == 0)
       return; /* Nothing to do */
 
    if (!(ctx->prim_hwsupport & (1 << info->mode))) {
       struct primconvert_context *primconvert = ctx->primconvert;
       util_primconvert_save_index_buffer(primconvert, &ctx->index_buffer.ib);
       util_primconvert_save_rasterizer_state(primconvert, ctx->rasterizer);
       util_primconvert_draw_vbo(primconvert, info);
       return;
    }
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index a3c35cb..07b89c1 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -58,20 +58,25 @@ resource_written(struct fd_batch *batch, struct pipe_resource *prsc)
 
 static void
 fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 {
 	struct fd_context *ctx = fd_context(pctx);
 	struct fd_batch *batch = ctx->batch;
 	struct pipe_framebuffer_state *pfb = &batch->framebuffer;
 	struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
 	unsigned i, prims, buffers = 0;
 
+	if (!info->count_from_stream_output && !info->indirect &&
+	    !info->primitive_restart &&
+	    !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
+		return;
+
 	/* if we supported transform feedback, we'd have to disable this: */
 	if (((scissor->maxx - scissor->minx) *
 			(scissor->maxy - scissor->miny)) == 0) {
 		return;
 	}
 
 	/* TODO: push down the region versions into the tiles */
 	if (!fd_render_condition_check(pctx))
 		return;
 
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 6664cfc..b201ea3 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -50,20 +50,23 @@ DEBUG_GET_ONCE_BOOL_OPTION(i915_no_vbuf, "I915_NO_VBUF", FALSE)
 
 
 static void
 i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct i915_context *i915 = i915_context(pipe);
    struct draw_context *draw = i915->draw;
    const void *mapped_indices = NULL;
    unsigned i;
 
+   if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
+      return;
+
    /*
     * Ack vs contants here, helps ipers a lot.
     */
    i915->dirty &= ~I915_NEW_VS_CONSTANTS;
 
    if (i915->dirty)
       i915_update_derived(i915);
 
    /*
     * Map vertex buffers
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
index bc9b9a1..295c394 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
@@ -543,20 +543,23 @@ nv30_draw_elements(struct nv30_context *nv30, bool shorten,
    }
 }
 
 static void
 nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct nv30_context *nv30 = nv30_context(pipe);
    struct nouveau_pushbuf *push = nv30->base.pushbuf;
    int i;
 
+   if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
+      return;
+
    /* For picking only a few vertices from a large user buffer, push is better,
     * if index count is larger and we expect repeated vertices, suggest upload.
     */
    nv30->vbo_push_hint = /* the 64 is heuristic */
       !(info->indexed &&
         ((info->max_index - info->min_index + 64) < info->count));
 
    nv30->vbo_min_index = info->min_index;
    nv30->vbo_max_index = info->max_index;
 
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index ad0f489..9702a2e 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -840,20 +840,23 @@ static void r300_draw_vbo(struct pipe_context* pipe,
 /* SW TCL elements, using Draw. */
 static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
                                 const struct pipe_draw_info *info)
 {
     struct r300_context* r300 = r300_context(pipe);
 
     if (r300->skip_rendering) {
         return;
     }
 
+    if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
+       return;
+
     r300_update_derived_state(r300);
 
     draw_vbo(r300->draw, info);
     draw_flush(r300->draw);
 }
 
 /* Object for rendering using Draw. */
 struct r300_render {
     /* Parent class */
     struct vbuf_render base;
diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp
index c43f4a5..de78cf3 100644
--- a/src/gallium/drivers/swr/swr_draw.cpp
+++ b/src/gallium/drivers/swr/swr_draw.cpp
@@ -32,20 +32,25 @@
 #include "util/u_prim.h"
 
 /*
  * Draw vertex arrays, with optional indexing, optional instancing.
  */
 static void
 swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 {
    struct swr_context *ctx = swr_context(pipe);
 
+   if (!info->count_from_stream_output && !info->indirect &&
+       !info->primitive_restart &&
+       !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
+      return;
+
    if (!swr_check_render_cond(pipe))
       return;
 
    if (info->indirect) {
       util_draw_indirect(pipe, info);
       return;
    }
 
    /* Update derived state, pass draw info to update function */
    swr_update_derived(pipe, info);
diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c
index ebd0802..61694ec 100644
--- a/src/gallium/drivers/vc4/vc4_draw.c
+++ b/src/gallium/drivers/vc4/vc4_draw.c
@@ -276,20 +276,25 @@ vc4_hw_2116_workaround(struct pipe_context *pctx, int vert_count)
                            "(too many draw calls per scene\n");
                 vc4_job_submit(vc4, job);
         }
 }
 
 static void
 vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 {
         struct vc4_context *vc4 = vc4_context(pctx);
 
+	if (!info->count_from_stream_output && !info->indirect &&
+	    !info->primitive_restart &&
+	    !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
+		return;
+
         if (info->mode >= PIPE_PRIM_QUADS) {
                 util_primconvert_save_index_buffer(vc4->primconvert, &vc4->indexbuf);
                 util_primconvert_save_rasterizer_state(vc4->primconvert, &vc4->rasterizer->base);
                 util_primconvert_draw_vbo(vc4->primconvert, info);
                 perf_debug("Fallback conversion for %d %s vertices\n",
                            info->count, u_prim_name(info->mode));
                 return;
         }
 
         /* Before setting up the draw, do any fixup blits necessary. */
diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c
index 4b990a6..5fa394d 100644
--- a/src/gallium/drivers/virgl/virgl_context.c
+++ b/src/gallium/drivers/virgl/virgl_context.c
@@ -585,20 +585,25 @@ static void virgl_clear(struct pipe_context *ctx,
 }
 
 static void virgl_draw_vbo(struct pipe_context *ctx,
                                    const struct pipe_draw_info *dinfo)
 {
    struct virgl_context *vctx = virgl_context(ctx);
    struct virgl_screen *rs = virgl_screen(ctx->screen);
    struct pipe_index_buffer ib = {};
    struct pipe_draw_info info = *dinfo;
 
+   if (!dinfo->count_from_stream_output && !dinfo->indirect &&
+       !dinfo->primitive_restart &&
+       !u_trim_pipe_prim(dinfo->mode, (unsigned*)&dinfo->count))
+      return;
+
    if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) {
       util_primconvert_save_index_buffer(vctx->primconvert, &vctx->index_buffer);
       util_primconvert_draw_vbo(vctx->primconvert, dinfo);
       return;
    }
    if (info.indexed) {
            pipe_resource_reference(&ib.buffer, vctx->index_buffer.buffer);
            ib.user_buffer = vctx->index_buffer.user_buffer;
            ib.index_size = vctx->index_buffer.index_size;
            ib.offset = vctx->index_buffer.offset + info.start * ib.index_size;
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 4a3aae8..a781209 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -242,30 +242,22 @@ st_draw_vbo(struct gl_context *ctx,
       }
 
       if (ST_DEBUG & DEBUG_DRAW) {
          debug_printf("st/draw: mode %s  start %u  count %u  indexed %d\n",
                       u_prim_name(info.mode),
                       info.start,
                       info.count,
                       info.indexed);
       }
 
-      if (info.count_from_stream_output) {
-         cso_draw_vbo(st->cso_context, &info);
-      }
-      else if (info.primitive_restart) {
-         /* don't trim, restarts might be inside index list */
-         cso_draw_vbo(st->cso_context, &info);
-      }
-      else if (u_trim_pipe_prim(prims[i].mode, &info.count)) {
-         cso_draw_vbo(st->cso_context, &info);
-      }
+      /* Don't call u_trim_pipe_prim. Drivers should do it if they need it. */
+      cso_draw_vbo(st->cso_context, &info);
    }
 }
 
 static void
 st_indirect_draw_vbo(struct gl_context *ctx,
                      GLuint mode,
                      struct gl_buffer_object *indirect_data,
                      GLsizeiptr indirect_offset,
                      unsigned draw_count,
                      unsigned stride,
-- 
2.7.4



More information about the mesa-dev mailing list