freedreno: split out batch draw tracking helper
authorRob Clark <robdclark@chromium.org>
Wed, 24 Jun 2020 16:23:50 +0000 (09:23 -0700)
committerMarge Bot <eric+marge@anholt.net>
Thu, 25 Jun 2020 00:55:24 +0000 (00:55 +0000)
Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5634>

src/gallium/drivers/freedreno/freedreno_draw.c

index e11c07b..70e351a 100644 (file)
@@ -59,64 +59,11 @@ 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)
+batch_draw_tracking(struct fd_batch *batch, const struct pipe_draw_info *info)
 {
-       struct fd_context *ctx = fd_context(pctx);
-       struct fd_batch *batch = fd_context_batch(ctx);
+       struct fd_context *ctx = batch->ctx;
        struct pipe_framebuffer_state *pfb = &batch->framebuffer;
-       unsigned i, prims, buffers = 0, restore_buffers = 0;
-
-       /* for debugging problems with indirect draw, it is convenient
-        * to be able to emulate it, to determine if game is feeding us
-        * bogus data:
-        */
-       if (info->indirect && (fd_mesa_debug & FD_DBG_NOINDR)) {
-               util_draw_indirect(pctx, info);
-               return;
-       }
-
-       if (!info->count_from_stream_output && !info->indirect &&
-           !info->primitive_restart &&
-           !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
-               return;
-
-       /* TODO: push down the region versions into the tiles */
-       if (!fd_render_condition_check(pctx))
-               return;
-
-       /* emulate unsupported primitives: */
-       if (!fd_supported_prim(ctx, info->mode)) {
-               if (ctx->streamout.num_targets > 0)
-                       debug_error("stream-out with emulated prims");
-               util_primconvert_save_rasterizer_state(ctx->primconvert, ctx->rasterizer);
-               util_primconvert_draw_vbo(ctx->primconvert, info);
-               return;
-       }
-
-       /* Upload a user index buffer. */
-       struct pipe_resource *indexbuf = NULL;
-       unsigned index_offset = 0;
-       struct pipe_draw_info new_info;
-       if (info->index_size) {
-               if (info->has_user_indices) {
-                       if (!util_upload_index_buffer(pctx, info, &indexbuf, &index_offset, 4))
-                               return;
-                       new_info = *info;
-                       new_info.index.resource = indexbuf;
-                       new_info.has_user_indices = false;
-                       info = &new_info;
-               } else {
-                       indexbuf = info->index.resource;
-               }
-       }
-
-       if (ctx->in_discard_blit) {
-               fd_batch_reset(batch);
-               fd_context_all_dirty(ctx);
-       }
-
-       batch->blit = ctx->in_discard_blit;
-       batch->back_blit = ctx->in_shadow;
+       unsigned buffers = 0, restore_buffers = 0;
 
        /* NOTE: needs to be before resource_written(batch->query_buf), otherwise
         * query_buf may not be created yet.
@@ -160,7 +107,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
        if (fd_logicop_enabled(ctx))
                batch->gmem_reason |= FD_GMEM_LOGICOP_ENABLED;
 
-       for (i = 0; i < pfb->nr_cbufs; i++) {
+       for (unsigned i = 0; i < pfb->nr_cbufs; i++) {
                struct pipe_resource *surf;
 
                if (!pfb->cbufs[i])
@@ -195,7 +142,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
        }
 
        if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_IMAGE) {
-               foreach_bit(i, ctx->shaderimg[PIPE_SHADER_FRAGMENT].enabled_mask) {
+               foreach_bit (i, ctx->shaderimg[PIPE_SHADER_FRAGMENT].enabled_mask) {
                        struct pipe_image_view *img =
                                        &ctx->shaderimg[PIPE_SHADER_FRAGMENT].si[i];
                        if (img->access & PIPE_IMAGE_ACCESS_WRITE)
@@ -206,25 +153,26 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
        }
 
        if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_CONST) {
-               foreach_bit(i, ctx->constbuf[PIPE_SHADER_VERTEX].enabled_mask)
+               foreach_bit (i, ctx->constbuf[PIPE_SHADER_VERTEX].enabled_mask)
                        resource_read(batch, ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer);
        }
 
        if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_CONST) {
-               foreach_bit(i, ctx->constbuf[PIPE_SHADER_FRAGMENT].enabled_mask)
+               foreach_bit (i, ctx->constbuf[PIPE_SHADER_FRAGMENT].enabled_mask)
                        resource_read(batch, ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer);
        }
 
        /* Mark VBOs as being read */
        if (ctx->dirty & FD_DIRTY_VTXBUF) {
-               foreach_bit(i, ctx->vtx.vertexbuf.enabled_mask) {
+               foreach_bit (i, ctx->vtx.vertexbuf.enabled_mask) {
                        assert(!ctx->vtx.vertexbuf.vb[i].is_user_buffer);
                        resource_read(batch, ctx->vtx.vertexbuf.vb[i].buffer.resource);
                }
        }
 
        /* Mark index buffer as being read */
-       resource_read(batch, indexbuf);
+       if (info->index_size)
+               resource_read(batch, info->index.resource);
 
        /* Mark indirect draw buffer as being read */
        if (info->indirect)
@@ -232,18 +180,18 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
        /* Mark textures as being read */
        if (ctx->dirty_shader[PIPE_SHADER_VERTEX] & FD_DIRTY_SHADER_TEX) {
-               foreach_bit(i, ctx->tex[PIPE_SHADER_VERTEX].valid_textures)
+               foreach_bit (i, ctx->tex[PIPE_SHADER_VERTEX].valid_textures)
                        resource_read(batch, ctx->tex[PIPE_SHADER_VERTEX].textures[i]->texture);
        }
 
        if (ctx->dirty_shader[PIPE_SHADER_FRAGMENT] & FD_DIRTY_SHADER_TEX) {
-               foreach_bit(i, ctx->tex[PIPE_SHADER_FRAGMENT].valid_textures)
+               foreach_bit (i, ctx->tex[PIPE_SHADER_FRAGMENT].valid_textures)
                        resource_read(batch, ctx->tex[PIPE_SHADER_FRAGMENT].textures[i]->texture);
        }
 
        /* Mark streamout buffers as being written.. */
        if (ctx->dirty & FD_DIRTY_STREAMOUT) {
-               for (i = 0; i < ctx->streamout.num_targets; i++)
+               for (unsigned i = 0; i < ctx->streamout.num_targets; i++)
                        if (ctx->streamout.targets[i])
                                resource_written(batch, ctx->streamout.targets[i]->buffer);
        }
@@ -255,12 +203,79 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
        fd_screen_unlock(ctx->screen);
 
+       /* any buffers that haven't been cleared yet, we need to restore: */
+       batch->restore |= restore_buffers & (FD_BUFFER_ALL & ~batch->invalidated);
+       /* and any buffers used, need to be resolved: */
+       batch->resolve |= buffers;
+}
+
+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 = fd_context_batch(ctx);
+       struct pipe_framebuffer_state *pfb = &batch->framebuffer;
+
+       /* for debugging problems with indirect draw, it is convenient
+        * to be able to emulate it, to determine if game is feeding us
+        * bogus data:
+        */
+       if (info->indirect && (fd_mesa_debug & FD_DBG_NOINDR)) {
+               util_draw_indirect(pctx, info);
+               return;
+       }
+
+       if (!info->count_from_stream_output && !info->indirect &&
+           !info->primitive_restart &&
+           !u_trim_pipe_prim(info->mode, (unsigned*)&info->count))
+               return;
+
+       /* TODO: push down the region versions into the tiles */
+       if (!fd_render_condition_check(pctx))
+               return;
+
+       /* emulate unsupported primitives: */
+       if (!fd_supported_prim(ctx, info->mode)) {
+               if (ctx->streamout.num_targets > 0)
+                       debug_error("stream-out with emulated prims");
+               util_primconvert_save_rasterizer_state(ctx->primconvert, ctx->rasterizer);
+               util_primconvert_draw_vbo(ctx->primconvert, info);
+               return;
+       }
+
+       /* Upload a user index buffer. */
+       struct pipe_resource *indexbuf = NULL;
+       unsigned index_offset = 0;
+       struct pipe_draw_info new_info;
+       if (info->index_size) {
+               if (info->has_user_indices) {
+                       if (!util_upload_index_buffer(pctx, info, &indexbuf, &index_offset, 4))
+                               return;
+                       new_info = *info;
+                       new_info.index.resource = indexbuf;
+                       new_info.has_user_indices = false;
+                       info = &new_info;
+               } else {
+                       indexbuf = info->index.resource;
+               }
+       }
+
+       if (ctx->in_discard_blit) {
+               fd_batch_reset(batch);
+               fd_context_all_dirty(ctx);
+       }
+
+       batch_draw_tracking(batch, info);
+
+       batch->blit = ctx->in_discard_blit;
+       batch->back_blit = ctx->in_shadow;
        batch->num_draws++;
 
        /* Counting prims in sw doesn't work for GS and tesselation. For older
         * gens we don't have those stages and don't have the hw counters enabled,
         * so keep the count accurate for non-patch geometry.
         */
+       unsigned prims;
        if (info->mode != PIPE_PRIM_PATCHES)
                prims = u_reduced_prims_for_vertices(info->mode, info->count);
        else
@@ -278,18 +293,13 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                ctx->stats.prims_emitted += prims;
        ctx->stats.prims_generated += prims;
 
-       /* any buffers that haven't been cleared yet, we need to restore: */
-       batch->restore |= restore_buffers & (FD_BUFFER_ALL & ~batch->invalidated);
-       /* and any buffers used, need to be resolved: */
-       batch->resolve |= buffers;
-
        /* Clearing last_fence must come after the batch dependency tracking
         * (resource_read()/resource_written()), as that can trigger a flush,
         * re-populating last_fence
         */
        fd_fence_ref(&ctx->last_fence, NULL);
 
-       DBG("%p: %x %ux%u num_draws=%u (%s/%s)", batch, buffers,
+       DBG("%p: %ux%u num_draws=%u (%s/%s)", batch,
                pfb->width, pfb->height, batch->num_draws,
                util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
                util_format_short_name(pipe_surface_format(pfb->zsbuf)));
@@ -299,7 +309,7 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
        batch->num_vertices += info->count * info->instance_count;
 
-       for (i = 0; i < ctx->streamout.num_targets; i++)
+       for (unsigned i = 0; i < ctx->streamout.num_targets; i++)
                ctx->streamout.offsets[i] += info->count;
 
        if (fd_mesa_debug & FD_DBG_DDRAW)