From 375453bb8b1d010d97336f81a80052a6384f77ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Mon, 2 Nov 2020 02:00:37 -0500 Subject: [PATCH] vbo: switch immediate Begin/End to DrawGallium MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes gallium faster because st/mesa doesn't have to translate _mesa_prim. Reviewed-by: Zoltán Böszörményi Part-of: --- src/mesa/vbo/vbo.h | 29 +++++++++++-- src/mesa/vbo/vbo_exec_api.c | 81 ++++++++++++++++++++---------------- src/mesa/vbo/vbo_exec_draw.c | 32 ++++++++------ 3 files changed, 92 insertions(+), 50 deletions(-) diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h index 5237e0fa262..da9c5e49216 100644 --- a/src/mesa/vbo/vbo.h +++ b/src/mesa/vbo/vbo.h @@ -37,6 +37,7 @@ #include "main/draw.h" #include "main/macros.h" #include "vbo_attrib.h" +#include "gallium/include/pipe/p_state.h" #ifdef __cplusplus extern "C" { @@ -80,20 +81,42 @@ struct vbo_exec_copied_vtx { GLuint nr; }; +struct vbo_markers +{ + /** + * If false and the primitive is a line loop, the first vertex is + * the beginning of the line loop and it won't be drawn. + * Instead, it will be moved to the end. + * + * Drivers shouldn't reset the line stipple pattern walker if begin is + * false and mode is a line strip. + */ + bool begin; + + /** + * If true and the primitive is a line loop, it will be closed. + */ + bool end; +}; + struct vbo_exec_context { GLvertexformat vtxfmt; GLvertexformat vtxfmt_noop; struct { + /* Multi draw where the mode can vary between draws. */ + struct pipe_draw_info info; + struct pipe_draw_start_count draw[VBO_MAX_PRIM]; + GLubyte mode[VBO_MAX_PRIM]; /**< primitive modes per draw */ + struct vbo_markers markers[VBO_MAX_PRIM]; + unsigned prim_count; + struct gl_buffer_object *bufferobj; GLuint vertex_size; /* in dwords */ GLuint vertex_size_no_pos; - struct _mesa_prim prim[VBO_MAX_PRIM]; - GLuint prim_count; - fi_type *buffer_map; fi_type *buffer_ptr; /* cursor, points into buffer */ GLuint buffer_used; /* in bytes */ diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index c25a7ea7a2f..c9a36b07fb4 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -82,29 +82,30 @@ vbo_exec_wrap_buffers(struct vbo_exec_context *exec) } else { struct gl_context *ctx = gl_context_from_vbo_exec(exec); - struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1]; - const GLuint last_begin = last_prim->begin; + unsigned last = exec->vtx.prim_count - 1; + struct pipe_draw_start_count *last_draw = &exec->vtx.draw[last]; + const bool last_begin = exec->vtx.markers[last].begin; GLuint last_count = 0; if (_mesa_inside_begin_end(ctx)) { - last_prim->count = exec->vtx.vert_count - last_prim->start; - last_count = last_prim->count; - last_prim->end = 0; + last_draw->count = exec->vtx.vert_count - last_draw->start; + last_count = last_draw->count; + exec->vtx.markers[last].end = 0; } /* Special handling for wrapping GL_LINE_LOOP */ - if (last_prim->mode == GL_LINE_LOOP && + if (exec->vtx.mode[last] == GL_LINE_LOOP && last_count > 0 && - !last_prim->end) { + !exec->vtx.markers[last].end) { /* draw this section of the incomplete line loop as a line strip */ - last_prim->mode = GL_LINE_STRIP; - if (!last_prim->begin) { + exec->vtx.mode[last] = GL_LINE_STRIP; + if (!last_begin) { /* This is not the first section of the line loop, so don't * draw the 0th vertex. We're saving it until we draw the * very last section of the loop. */ - last_prim->start++; - last_prim->count--; + last_draw->start++; + last_draw->count--; } } @@ -122,13 +123,13 @@ vbo_exec_wrap_buffers(struct vbo_exec_context *exec) assert(exec->vtx.prim_count == 0); if (_mesa_inside_begin_end(ctx)) { - exec->vtx.prim[0].mode = ctx->Driver.CurrentExecPrimitive; - exec->vtx.prim[0].begin = 0; - exec->vtx.prim[0].start = 0; + exec->vtx.mode[0] = ctx->Driver.CurrentExecPrimitive; + exec->vtx.draw[0].start = 0; + exec->vtx.markers[0].begin = 0; exec->vtx.prim_count++; if (exec->vtx.copied.nr == last_count) - exec->vtx.prim[0].begin = last_begin; + exec->vtx.markers[0].begin = last_begin; } } } @@ -836,9 +837,9 @@ vbo_exec_Begin(GLenum mode) vbo_exec_FlushVertices_internal(exec, FLUSH_STORED_VERTICES); i = exec->vtx.prim_count++; - exec->vtx.prim[i].mode = mode; - exec->vtx.prim[i].begin = 1; - exec->vtx.prim[i].start = exec->vtx.vert_count; + exec->vtx.mode[i] = mode; + exec->vtx.draw[i].start = exec->vtx.vert_count; + exec->vtx.markers[i].begin = 1; ctx->Driver.CurrentExecPrimitive = mode; @@ -864,22 +865,27 @@ vbo_exec_Begin(GLenum mode) static void try_vbo_merge(struct vbo_exec_context *exec) { - struct _mesa_prim *cur = &exec->vtx.prim[exec->vtx.prim_count - 1]; + unsigned cur = exec->vtx.prim_count - 1; assert(exec->vtx.prim_count >= 1); - vbo_try_prim_conversion(&cur->mode, &cur->count); + vbo_try_prim_conversion(&exec->vtx.mode[cur], &exec->vtx.draw[cur].count); if (exec->vtx.prim_count >= 2) { struct gl_context *ctx = gl_context_from_vbo_exec(exec); - struct _mesa_prim *prev = &exec->vtx.prim[exec->vtx.prim_count - 2]; - assert(prev == cur - 1); + unsigned prev = cur - 1; if (vbo_merge_draws(ctx, false, - prev->mode, cur->mode, prev->start, cur->start, - &prev->count, cur->count, - prev->basevertex, cur->basevertex, - &prev->end, cur->begin, cur->end)) + exec->vtx.mode[prev], + exec->vtx.mode[cur], + exec->vtx.draw[prev].start, + exec->vtx.draw[cur].start, + &exec->vtx.draw[prev].count, + exec->vtx.draw[cur].count, + 0, 0, + &exec->vtx.markers[prev].end, + exec->vtx.markers[cur].begin, + exec->vtx.markers[cur].end)) exec->vtx.prim_count--; /* drop the last primitive */ } } @@ -910,31 +916,33 @@ vbo_exec_End(void) if (exec->vtx.prim_count > 0) { /* close off current primitive */ - struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1]; - unsigned count = exec->vtx.vert_count - last_prim->start; + unsigned last = exec->vtx.prim_count - 1; + struct pipe_draw_start_count *last_draw = &exec->vtx.draw[last]; + unsigned count = exec->vtx.vert_count - last_draw->start; - last_prim->end = 1; - last_prim->count = count; + last_draw->count = count; + exec->vtx.markers[last].end = 1; if (count) ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; /* Special handling for GL_LINE_LOOP */ - if (last_prim->mode == GL_LINE_LOOP && last_prim->begin == 0) { + if (exec->vtx.mode[last] == GL_LINE_LOOP && + exec->vtx.markers[last].begin == 0) { /* We're finishing drawing a line loop. Append 0th vertex onto * end of vertex buffer so we can draw it as a line strip. */ const fi_type *src = exec->vtx.buffer_map + - last_prim->start * exec->vtx.vertex_size; + last_draw->start * exec->vtx.vertex_size; fi_type *dst = exec->vtx.buffer_map + exec->vtx.vert_count * exec->vtx.vertex_size; /* copy 0th vertex to end of buffer */ memcpy(dst, src, exec->vtx.vertex_size * sizeof(fi_type)); - last_prim->start++; /* skip vertex0 */ - /* note that last_prim->count stays unchanged */ - last_prim->mode = GL_LINE_STRIP; + last_draw->start++; /* skip vertex0 */ + /* note that the count stays unchanged */ + exec->vtx.mode[last] = GL_LINE_STRIP; /* Increment the vertex count so the next primitive doesn't * overwrite the last vertex which we just added. @@ -1037,6 +1045,9 @@ vbo_exec_vtx_init(struct vbo_exec_context *exec, bool use_buffer_objects) exec->vtx.enabled = u_bit_consecutive64(0, VBO_ATTRIB_MAX); /* reset all */ vbo_reset_all_attr(exec); + + exec->vtx.info.instance_count = 1; + exec->vtx.info.max_index = ~0; } diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 1932da08ee8..d4eb3801f38 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -53,14 +53,13 @@ vbo_exec_debug_verts(struct vbo_exec_context *exec) exec->vtx.vertex_size); for (i = 0 ; i < exec->vtx.prim_count ; i++) { - struct _mesa_prim *prim = &exec->vtx.prim[i]; printf(" prim %d: %s %d..%d %s %s\n", i, - _mesa_lookup_prim_by_nr(prim->mode), - prim->start, - prim->start + prim->count, - prim->begin ? "BEGIN" : "(wrap)", - prim->end ? "END" : "(wrap)"); + _mesa_lookup_prim_by_nr(exec->vtx.mode[i]), + exec->vtx.draw[i].start, + exec->vtx.draw[i].start + exec->vtx.draw[i].count, + exec->vtx.markers[i].begin ? "BEGIN" : "(wrap)", + exec->vtx.markers[i].end ? "END" : "(wrap)"); } } @@ -69,14 +68,17 @@ static GLuint vbo_exec_copy_vertices(struct vbo_exec_context *exec) { struct gl_context *ctx = gl_context_from_vbo_exec(exec); - struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1]; const GLuint sz = exec->vtx.vertex_size; fi_type *dst = exec->vtx.copied.buffer; - const fi_type *src = exec->vtx.buffer_map + last_prim->start * sz; + unsigned last = exec->vtx.prim_count - 1; + unsigned start = exec->vtx.draw[last].start; + const fi_type *src = exec->vtx.buffer_map + start * sz; return vbo_copy_vertices(ctx, ctx->Driver.CurrentExecPrimitive, - last_prim->start, &last_prim->count, - last_prim->begin, sz, false, dst, src); + start, + &exec->vtx.draw[last].count, + exec->vtx.markers[last].begin, + sz, false, dst, src); } @@ -328,8 +330,14 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec) printf("%s %d %d\n", __func__, exec->vtx.prim_count, exec->vtx.vert_count); - ctx->Driver.Draw(ctx, exec->vtx.prim, exec->vtx.prim_count, NULL, - true, false, 0, 0, exec->vtx.vert_count - 1, 1, 0); + exec->vtx.info.vertices_per_patch = + ctx->TessCtrlProgram.patch_vertices; + + ctx->Driver.DrawGalliumComplex(ctx, &exec->vtx.info, + exec->vtx.draw, + exec->vtx.mode, + NULL, + exec->vtx.prim_count); /* Get new storage -- unless asked not to. */ if (!persistent_mapping)