mesa: switch (Multi)DrawArrays to DrawGallium

This makes gallium faster because st/mesa doesn't have to translate
_mesa_prim.

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7679>
This commit is contained in:
Marek Olšák 2020-11-03 11:02:51 -05:00
parent fc3d165354
commit 2358da81d2

View file

@ -58,12 +58,12 @@ typedef struct {
} DrawElementsIndirectCommand; } DrawElementsIndirectCommand;
#define MAX_ALLOCA_PRIMS (50000 / sizeof(*prim)) #define MAX_ALLOCA_PRIMS(prim) (50000 / sizeof(*prim))
/* Use calloc for large allocations and alloca for small allocations. */ /* Use calloc for large allocations and alloca for small allocations. */
/* We have to use a macro because alloca is local within the function. */ /* We have to use a macro because alloca is local within the function. */
#define ALLOC_PRIMS(prim, primcount, func) do { \ #define ALLOC_PRIMS(prim, primcount, func) do { \
if (unlikely(primcount > MAX_ALLOCA_PRIMS)) { \ if (unlikely(primcount > MAX_ALLOCA_PRIMS(prim))) { \
prim = calloc(primcount, sizeof(*prim)); \ prim = calloc(primcount, sizeof(*prim)); \
if (!prim) { \ if (!prim) { \
_mesa_error(ctx, GL_OUT_OF_MEMORY, func); \ _mesa_error(ctx, GL_OUT_OF_MEMORY, func); \
@ -75,7 +75,7 @@ typedef struct {
} while (0) } while (0)
#define FREE_PRIMS(prim, primcount) do { \ #define FREE_PRIMS(prim, primcount) do { \
if (primcount > MAX_ALLOCA_PRIMS) \ if (primcount > MAX_ALLOCA_PRIMS(prim)) \
free(prim); \ free(prim); \
} while (0) } while (0)
@ -529,18 +529,29 @@ _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
/* OpenGL 4.5 says that primitive restart is ignored with non-indexed /* OpenGL 4.5 says that primitive restart is ignored with non-indexed
* draws. * draws.
*/ */
struct _mesa_prim prim = { struct pipe_draw_info info;
.begin = 1, struct pipe_draw_start_count draw;
.end = 1,
.mode = mode,
.draw_id = 0,
.start = start,
.count = count,
};
ctx->Driver.Draw(ctx, &prim, 1, NULL, info.mode = mode;
true, false, 0, start, start + count - 1, info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
numInstances, baseInstance); info.index_size = 0;
/* Packed section begin. */
info.primitive_restart = false;
info.has_user_indices = false;
info.index_bounds_valid = true;
info.increment_draw_id = false;
info._pad = 0;
/* Packed section end. */
info.start_instance = baseInstance;
info.instance_count = numInstances;
info.drawid = 0;
info.min_index = start;
info.max_index = start + count - 1;
draw.start = start;
draw.count = count;
ctx->Driver.DrawGallium(ctx, &info, &draw, 1);
if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) {
_mesa_flush(ctx); _mesa_flush(ctx);
@ -867,26 +878,36 @@ _mesa_exec_MultiDrawArrays(GLenum mode, const GLint *first,
if (skip_validated_draw(ctx)) if (skip_validated_draw(ctx))
return; return;
struct _mesa_prim *prim; struct pipe_draw_info info;
struct pipe_draw_start_count *draw;
ALLOC_PRIMS(prim, primcount, "glMultiDrawElements"); ALLOC_PRIMS(draw, primcount, "glMultiDrawElements");
info.mode = mode;
info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
info.index_size = 0;
/* Packed section begin. */
info.primitive_restart = false;
info.has_user_indices = false;
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;
for (i = 0; i < primcount; i++) { for (i = 0; i < primcount; i++) {
prim[i].begin = 1; draw[i].start = first[i];
prim[i].end = 1; draw[i].count = count[i];
prim[i].mode = mode;
prim[i].draw_id = i;
prim[i].start = first[i];
prim[i].count = count[i];
prim[i].basevertex = 0;
} }
ctx->Driver.Draw(ctx, prim, primcount, NULL, false, false, 0, 0, 0, 1, 0); ctx->Driver.DrawGallium(ctx, &info, draw, primcount);
if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
_mesa_flush(ctx); _mesa_flush(ctx);
FREE_PRIMS(prim, primcount); FREE_PRIMS(draw, primcount);
} }