From: Marek Olšák Date: Sun, 1 Nov 2020 22:07:03 +0000 (-0500) Subject: mesa: switch MultiDrawElements(BaseVertex) to DrawGallium* X-Git-Tag: upstream/21.0.0~763 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9d90b44a23e9e59ce57c6125403b9ef9c9c2c301;p=platform%2Fupstream%2Fmesa.git mesa: switch MultiDrawElements(BaseVertex) to DrawGallium* This makes gallium faster because st/mesa doesn't have to translate _mesa_prim. Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index 4f42657..326ac6a 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -1428,7 +1428,6 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, const GLvoid * const *indices, GLsizei primcount, const GLint *basevertex) { - struct _mesa_index_buffer ib; uintptr_t min_index_ptr, max_index_ptr; bool fallback = false; int i; @@ -1436,14 +1435,14 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, if (primcount == 0) return; - ib.index_size_shift = get_index_size_shift(type); + unsigned index_size_shift = get_index_size_shift(type); min_index_ptr = (uintptr_t) indices[0]; max_index_ptr = 0; for (i = 0; i < primcount; i++) { min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]); max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] + - (count[i] << ib.index_size_shift)); + (count[i] << index_size_shift)); } /* Check if we can handle this thing as a bunch of index offsets from the @@ -1452,87 +1451,105 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, * Check that the difference between each prim's indexes is a multiple of * the index/element size. */ - if (ib.index_size_shift) { + if (index_size_shift) { for (i = 0; i < primcount; i++) { if ((((uintptr_t) indices[i] - min_index_ptr) & - ((1 << ib.index_size_shift) - 1)) != 0) { + ((1 << index_size_shift) - 1)) != 0) { fallback = true; break; } } } - if (ctx->Const.MultiDrawWithUserIndices) { - /* "max_index_ptr - min_index_ptr >> index_size_shift" is stored - * in prims[i].start. The driver will multiply it later by index_size - * so make sure the final value won't overflow. - */ - if (max_index_ptr - min_index_ptr > UINT32_MAX) - fallback = true; - } else { - /* If the index buffer isn't in a VBO, then treating the application's - * subranges of the index buffer as one large index buffer may lead to - * us reading unmapped memory. - */ - if (!ctx->Array.VAO->IndexBufferObj) - fallback = true; + /* See if BaseVertex is constant across all draws. */ + bool basevertex_is_constant = true; + if (basevertex) { + for (int i = 1; i < primcount; i++) { + if (basevertex[i] != basevertex[0]) { + basevertex_is_constant = false; + break; + } + } } - if (!fallback) { - struct _mesa_prim *prim; + struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; + struct pipe_draw_info info; + + info.mode = mode; + info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; + info.index_size = 1 << index_size_shift; + /* Packed section begin. */ + info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; + info.has_user_indices = index_bo == NULL; + info.index_bounds_valid = false; + info.increment_draw_id = primcount > 1; + info._pad = 0; + /* Packed section end. */ + info.start_instance = 0; + info.instance_count = 1; + info.drawid = 0; + info.restart_index = ctx->Array._RestartIndex[index_size_shift]; - ALLOC_PRIMS(prim, primcount, "glMultiDrawElements"); + if (info.has_user_indices) + info.index.user = (void*)min_index_ptr; + else + info.index.gl_bo = index_bo; - ib.count = (max_index_ptr - min_index_ptr) >> ib.index_size_shift; - ib.obj = ctx->Array.VAO->IndexBufferObj; - ib.ptr = (void *) min_index_ptr; + if (!fallback && + (!info.has_user_indices || + /* "max_index_ptr - min_index_ptr >> index_size_shift" is stored + * in draw[i].start. The driver will multiply it later by index_size + * so make sure the final value won't overflow. + * + * For real index buffers, gallium doesn't support index buffer offsets + * greater than UINT32_MAX bytes. + */ + max_index_ptr - min_index_ptr <= UINT32_MAX)) { + struct pipe_draw_start_count *draw; + + ALLOC_PRIMS(draw, primcount, "glMultiDrawElements"); + + if (info.has_user_indices) { + for (int i = 0; i < primcount; i++) { + draw[i].start = + ((uintptr_t)indices[i] - min_index_ptr) >> index_size_shift; + draw[i].count = count[i]; + } + } else { + for (int i = 0; i < primcount; i++) { + draw[i].start = (uintptr_t)indices[i] >> index_size_shift; + draw[i].count = count[i]; + } + } - for (i = 0; i < primcount; i++) { - prim[i].begin = 1; - prim[i].end = 1; - prim[i].mode = mode; - prim[i].start = - ((uintptr_t) indices[i] - min_index_ptr) >> ib.index_size_shift; - prim[i].count = count[i]; - prim[i].draw_id = i; - if (basevertex != NULL) - prim[i].basevertex = basevertex[i]; - else - prim[i].basevertex = 0; + if (basevertex_is_constant) { + info.index_bias = basevertex ? basevertex[0] : 0; + ctx->Driver.DrawGallium(ctx, &info, draw, primcount); + } else { + ctx->Driver.DrawGalliumComplex(ctx, &info, draw, NULL, basevertex, + primcount); } + FREE_PRIMS(draw, primcount); + } else { + /* draw[i].start would overflow. Draw one at a time. */ + assert(info.has_user_indices); + info.increment_draw_id = false; - ctx->Driver.Draw(ctx, prim, primcount, &ib, false, - ctx->Array._PrimitiveRestart[ib.index_size_shift], - ctx->Array._RestartIndex[ib.index_size_shift], - 0, ~0, 1, 0); - FREE_PRIMS(prim, primcount); - } - else { - /* render one prim at a time */ - for (i = 0; i < primcount; i++) { - if (count[i] == 0) + for (int i = 0; i < primcount; i++) { + struct pipe_draw_start_count draw; + + if (!count[i]) continue; - ib.count = count[i]; - ib.obj = ctx->Array.VAO->IndexBufferObj; - ib.ptr = indices[i]; + /* Reset these, because the callee can change them. */ + info.index_bounds_valid = false; + info.index_bias = basevertex ? basevertex[i] : 0; + info.drawid = i; + info.index.user = indices[i]; + draw.start = 0; + draw.count = count[i]; - struct _mesa_prim prim; - prim.begin = 1; - prim.end = 1; - prim.mode = mode; - prim.start = 0; - prim.count = count[i]; - prim.draw_id = i; - if (basevertex != NULL) - prim.basevertex = basevertex[i]; - else - prim.basevertex = 0; - - ctx->Driver.Draw(ctx, &prim, 1, &ib, false, - ctx->Array._PrimitiveRestart[ib.index_size_shift], - ctx->Array._RestartIndex[ib.index_size_shift], - 0, ~0, 1, 0); + ctx->Driver.DrawGallium(ctx, &info, &draw, 1); } }