From: Rob Clark Date: Wed, 24 Jun 2020 16:23:50 +0000 (-0700) Subject: freedreno: split out batch draw tracking helper X-Git-Tag: upstream/21.0.0~8280 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ad136945e6da8f81c454c60c6702995066b9dfdb;p=platform%2Fupstream%2Fmesa.git freedreno: split out batch draw tracking helper Signed-off-by: Rob Clark Part-of: --- diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index e11c07b..70e351a 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -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)