From dcbf2423d284b7bf2d0dc3e622c73de00c7d5bf4 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 3 Jan 2022 10:55:38 +0100 Subject: [PATCH] vbo/dlist: add vertices to incomplete primitives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a primitive is added with missing vertices, this will shift all the vertices and produce incorrect rendering. In issue #5786 the app uses GL_LINE_STRIPS with a single vertex. Adding extra vertices can make the initial estimation for the index buffer size incorrect, so this buffer can now be growed if needed. Fixes: ac3d4c7635b ("vbo/dlist: convert LINE_STRIPS to LINES") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5786 Acked-by: Marek Olšák Part-of: --- src/mesa/vbo/vbo_save_api.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index bae9fd6ad0c..258359a4de7 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -117,6 +117,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "util/u_memory.h" #include "util/hash_table.h" #include "util/indices/u_indices.h" +#include "util/u_prim.h" #include "gallium/include/pipe/p_state.h" @@ -599,10 +600,8 @@ compile_vertex_list(struct gl_context *ctx) /* converting primitive types may result in many more indices */ bool all_prims_supported = (ctx->Const.DriverSupportedPrimMask & BITFIELD_MASK(PIPE_PRIM_MAX)) == BITFIELD_MASK(PIPE_PRIM_MAX); int max_index_count = total_vert_count * (all_prims_supported ? 2 : 3); - - int size = max_index_count * sizeof(uint32_t); - uint32_t* indices = (uint32_t*) malloc(size); - void *tmp_indices = all_prims_supported ? NULL : malloc(size); + uint32_t* indices = (uint32_t*) malloc(max_index_count * sizeof(uint32_t)); + void *tmp_indices = all_prims_supported ? NULL : malloc(max_index_count * sizeof(uint32_t)); struct _mesa_prim *merged_prims = NULL; int idx = 0; @@ -632,6 +631,13 @@ compile_vertex_list(struct gl_context *ctx) continue; } + /* Increase indices storage if the original estimation was too small. */ + if (idx + 3 * vertex_count > max_index_count) { + max_index_count = max_index_count + 3 * vertex_count; + indices = (uint32_t*) realloc(indices, max_index_count * sizeof(uint32_t)); + tmp_indices = all_prims_supported ? NULL : realloc(tmp_indices, max_index_count * sizeof(uint32_t)); + } + /* Line strips may get converted to lines */ if (mode == GL_LINE_STRIP) mode = GL_LINES; @@ -719,6 +725,16 @@ compile_vertex_list(struct gl_context *ctx) temp_vertices_buffer, &max_index); } } + + /* Duplicate the last vertex for incomplete primitives */ + unsigned min_vert = u_prim_vertex_count(mode)->min; + for (unsigned j = vertex_count; j < min_vert; j++) { + indices[idx++] = add_vertex(save, vertex_to_index, + converted_prim ? CAST_INDEX(tmp_indices, index_size, vertex_count - 1) : + original_prims[i].start + vertex_count - 1, + temp_vertices_buffer, &max_index); + } + #undef CAST_INDEX if (merge_prims) { /* Update vertex count. */