diff options
author | Erico Nunes <[email protected]> | 2019-11-09 13:50:52 +0100 |
---|---|---|
committer | Erico Nunes <[email protected]> | 2019-12-14 07:44:43 +0100 |
commit | ce52b49348111d6e6277d1899d39440228ceaed8 (patch) | |
tree | 6519e3dcc6a47ca92c9b123ab91bef3fecb03299 | |
parent | 6d46d0e82b5214120aaa4d600e9fa0a502050c56 (diff) |
lima: split draw calls on 64k vertices
The Mali400 only supports draws with up to 64k vertices per command.
To handle this, break the draw_vbo call into multiple commands.
Indexed drawing is left to a separate code path.
This implementation was ported from vc4_draw_vbo.
Signed-off-by: Erico Nunes <[email protected]>
Reviewed-by: Vasily Khoruzhick <[email protected]>
Reviewed-by: Andreas Baierl <[email protected]>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2445>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/2445>
-rw-r--r-- | src/gallium/drivers/lima/lima_draw.c | 145 |
1 files changed, 97 insertions, 48 deletions
diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c index 0a6e9cc18ac..718f90546c7 100644 --- a/src/gallium/drivers/lima/lima_draw.c +++ b/src/gallium/drivers/lima/lima_draw.c @@ -31,6 +31,7 @@ #include "util/u_inlines.h" #include "util/u_pack_color.h" #include "util/hash_table.h" +#include "util/u_split_draw.h" #include "util/u_upload_mgr.h" #include "util/u_prim.h" #include "util/u_vbuf.h" @@ -1317,59 +1318,13 @@ lima_update_varying(struct lima_context *ctx, const struct pipe_draw_info *info) } static void -lima_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) +lima_draw_vbo_update(struct pipe_context *pctx, + const struct pipe_draw_info *info) { - /* check if draw mode and vertex/index count match, - * otherwise gp will hang */ - if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) { - debug_printf("draw mode and vertex/index count mismatch\n"); - return; - } - struct lima_context *ctx = lima_context(pctx); - struct pipe_resource *indexbuf = NULL; - - if (!ctx->vs || !ctx->fs) { - debug_warn_once("no shader, skip draw\n"); - return; - } - - if (!lima_update_vs_state(ctx) || !lima_update_fs_state(ctx)) - return; - - if (info->index_size) { - if (info->has_user_indices) { - util_upload_index_buffer(&ctx->base, info, &indexbuf, &ctx->index_offset, 0x40); - ctx->index_res = lima_resource(indexbuf); - } - else - ctx->index_res = lima_resource(info->index.resource); - - lima_submit_add_bo(ctx->gp_submit, ctx->index_res->bo, LIMA_SUBMIT_BO_READ); - } - - lima_dump_command_stream_print( - ctx->vs->bo->map, ctx->vs->shader_size, false, - "add vs at va %x\n", ctx->vs->bo->va); - - lima_dump_command_stream_print( - ctx->fs->bo->map, ctx->fs->shader_size, false, - "add fs at va %x\n", ctx->fs->bo->va); - - lima_submit_add_bo(ctx->gp_submit, ctx->vs->bo, LIMA_SUBMIT_BO_READ); - lima_submit_add_bo(ctx->pp_submit, ctx->fs->bo, LIMA_SUBMIT_BO_READ); lima_update_submit_bo(ctx); - /* Mali Utgard GPU always need min/max index info for index draw, - * compute it if upper layer does not do for us */ - if (info->index_size && info->max_index == ~0u) - u_vbuf_get_minmax_index(pctx, info, &ctx->min_index, &ctx->max_index); - else { - ctx->min_index = info->min_index; - ctx->max_index = info->max_index; - } - lima_update_gp_attribute_info(ctx, info); if ((ctx->dirty & LIMA_CONTEXT_DIRTY_CONST_BUFF && @@ -1404,12 +1359,106 @@ lima_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) } ctx->dirty = 0; +} + +static void +lima_draw_vbo_indexed(struct pipe_context *pctx, + const struct pipe_draw_info *info) +{ + struct lima_context *ctx = lima_context(pctx); + struct pipe_resource *indexbuf = NULL; + + /* Mali Utgard GPU always need min/max index info for index draw, + * compute it if upper layer does not do for us */ + if (info->max_index == ~0u) + u_vbuf_get_minmax_index(pctx, info, &ctx->min_index, &ctx->max_index); + else { + ctx->min_index = info->min_index; + ctx->max_index = info->max_index; + } + + if (info->has_user_indices) { + util_upload_index_buffer(&ctx->base, info, &indexbuf, &ctx->index_offset, 0x40); + ctx->index_res = lima_resource(indexbuf); + } + else { + ctx->index_res = lima_resource(info->index.resource); + ctx->index_offset = 0; + } + + lima_submit_add_bo(ctx->gp_submit, ctx->index_res->bo, LIMA_SUBMIT_BO_READ); + lima_submit_add_bo(ctx->pp_submit, ctx->index_res->bo, LIMA_SUBMIT_BO_READ); + lima_draw_vbo_update(pctx, info); if (indexbuf) pipe_resource_reference(&indexbuf, NULL); } static void +lima_draw_vbo_count(struct pipe_context *pctx, + const struct pipe_draw_info *info) +{ + static const uint32_t max_verts = 65535; + + struct pipe_draw_info local_info = *info; + unsigned start = info->start; + unsigned count = info->count; + + while (count) { + unsigned this_count = count; + unsigned step; + + u_split_draw(info, max_verts, &this_count, &step); + + local_info.start = start; + local_info.count = this_count; + + lima_draw_vbo_update(pctx, &local_info); + + count -= step; + start += step; + } +} + +static void +lima_draw_vbo(struct pipe_context *pctx, + const struct pipe_draw_info *info) +{ + /* check if draw mode and vertex/index count match, + * otherwise gp will hang */ + if (!u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) { + debug_printf("draw mode and vertex/index count mismatch\n"); + return; + } + + struct lima_context *ctx = lima_context(pctx); + + if (!ctx->vs || !ctx->fs) { + debug_warn_once("no shader, skip draw\n"); + return; + } + + if (!lima_update_vs_state(ctx) || !lima_update_fs_state(ctx)) + return; + + lima_dump_command_stream_print( + ctx->vs->bo->map, ctx->vs->shader_size, false, + "add vs at va %x\n", ctx->vs->bo->va); + + lima_dump_command_stream_print( + ctx->fs->bo->map, ctx->fs->shader_size, false, + "add fs at va %x\n", ctx->fs->bo->va); + + lima_submit_add_bo(ctx->gp_submit, ctx->vs->bo, LIMA_SUBMIT_BO_READ); + lima_submit_add_bo(ctx->pp_submit, ctx->fs->bo, LIMA_SUBMIT_BO_READ); + + if (info->index_size) + lima_draw_vbo_indexed(pctx, info); + else + lima_draw_vbo_count(pctx, info); +} + +static void lima_finish_plbu_cmd(struct lima_context *ctx) { int i = 0; |