aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErico Nunes <[email protected]>2019-11-09 13:50:52 +0100
committerErico Nunes <[email protected]>2019-12-14 07:44:43 +0100
commitce52b49348111d6e6277d1899d39440228ceaed8 (patch)
tree6519e3dcc6a47ca92c9b123ab91bef3fecb03299
parent6d46d0e82b5214120aaa4d600e9fa0a502050c56 (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.c145
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;