From 1be1ea0b8e2d5eed5202f669d11f5644fb4b5de2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 18 Feb 2020 18:37:36 -0500 Subject: [PATCH] vbo: deduplicate copy_vertices functions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit There are some differences in exec, but those look like bug fixes not ported to vbo_save. Reviewed-by: Mathias Fröhlich Reviewed-by: Ian Romanick Part-of: --- src/mesa/vbo/vbo_exec.c | 102 +++++++++++++++++++++++++++++++++++ src/mesa/vbo/vbo_exec_draw.c | 96 ++------------------------------- src/mesa/vbo/vbo_private.h | 9 ++++ src/mesa/vbo/vbo_save_api.c | 68 +---------------------- 4 files changed, 117 insertions(+), 158 deletions(-) diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c index 359483949e3..627b4a262d8 100644 --- a/src/mesa/vbo/vbo_exec.c +++ b/src/mesa/vbo/vbo_exec.c @@ -225,3 +225,105 @@ vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1) p0->count += p1->count; p0->end = p1->end; } + +/** + * Copy zero, one or two vertices from the current vertex buffer into + * the temporary "copy" buffer. + * This is used when a single primitive overflows a vertex buffer and + * we need to continue the primitive in a new vertex buffer. + * The temporary "copy" buffer holds the vertices which need to get + * copied from the old buffer to the new one. + */ +unsigned +vbo_copy_vertices(struct gl_context *ctx, + GLenum mode, + struct _mesa_prim *last_prim, + unsigned vertex_size, + bool in_dlist, + fi_type *dst, + const fi_type *src) +{ + const unsigned count = last_prim->count; + unsigned copy = 0; + + switch (mode) { + case GL_POINTS: + return 0; + case GL_LINES: + case GL_TRIANGLES: + case GL_QUADS: + if (mode == GL_LINES) + copy = count % 2; + else if (mode == GL_TRIANGLES) + copy = count % 3; + else if (mode == GL_QUADS) + copy = count % 4; + + for (unsigned i = 0; i < copy; i++) { + memcpy(dst + i * vertex_size, src + (count - copy + i) * vertex_size, + vertex_size * sizeof(GLfloat)); + } + return copy; + case GL_LINE_STRIP: + if (count == 0) + return 0; + + memcpy(dst, src + (count - 1) * vertex_size, + vertex_size * sizeof(GLfloat)); + return 1; + case GL_LINE_LOOP: + if (!in_dlist && last_prim->begin == 0) { + /* We're dealing with the second or later section of a split/wrapped + * GL_LINE_LOOP. Since we're converting line loops to line strips, + * we've already incremented the last_prim->start counter by one to + * skip the 0th vertex in the loop. We need to undo that (effectively + * subtract one from last_prim->start) so that we copy the 0th vertex + * to the next vertex buffer. + */ + assert(last_prim->start > 0); + src -= vertex_size; + } + /* fall-through */ + case GL_TRIANGLE_FAN: + case GL_POLYGON: + if (count == 0) { + return 0; + } else if (count == 1) { + memcpy(dst, src + 0, vertex_size * sizeof(GLfloat)); + return 1; + } else { + memcpy(dst, src + 0, vertex_size * sizeof(GLfloat)); + memcpy(dst + vertex_size, src + (count - 1) * vertex_size, + vertex_size * sizeof(GLfloat)); + return 2; + } + case GL_TRIANGLE_STRIP: + /* no parity issue, but need to make sure the tri is not drawn twice */ + if (count & 1) { + last_prim->count--; + } + /* fallthrough */ + case GL_QUAD_STRIP: + switch (count) { + case 0: + copy = 0; + break; + case 1: + copy = 1; + break; + default: + copy = 2 + (count & 1); + break; + } + for (unsigned i = 0; i < copy; i++) { + memcpy(dst + i * vertex_size, src + (count - copy + i) * vertex_size, + vertex_size * sizeof(GLfloat)); + } + return copy; + case PRIM_OUTSIDE_BEGIN_END: + return 0; + default: + unreachable("Unexpected primitive type"); + return 0; + } +} diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 87e7db18d67..035c1163612 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -65,104 +65,16 @@ vbo_exec_debug_verts(struct vbo_exec_context *exec) } -/** - * Copy zero, one or two vertices from the current vertex buffer into - * the temporary "copy" buffer. - * This is used when a single primitive overflows a vertex buffer and - * we need to continue the primitive in a new vertex buffer. - * The temporary "copy" buffer holds the vertices which need to get - * copied from the old buffer to the new one. - */ static GLuint -vbo_copy_vertices(struct vbo_exec_context *exec) +vbo_exec_copy_vertices(struct vbo_exec_context *exec) { struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1]; - const GLuint nr = last_prim->count; - GLuint ovf, i; 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; - switch (exec->ctx->Driver.CurrentExecPrimitive) { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); - return i; - case GL_TRIANGLES: - ovf = nr%3; - for (i = 0 ; i < ovf ; i++) - memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); - return i; - case GL_QUADS: - ovf = nr&3; - for (i = 0 ; i < ovf ; i++) - memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); - return i; - case GL_LINE_STRIP: - if (nr == 0) { - return 0; - } - else { - memcpy(dst, src+(nr-1)*sz, sz * sizeof(GLfloat)); - return 1; - } - case GL_LINE_LOOP: - if (last_prim->begin == 0) { - /* We're dealing with the second or later section of a split/wrapped - * GL_LINE_LOOP. Since we're converting line loops to line strips, - * we've already increment the last_prim->start counter by one to - * skip the 0th vertex in the loop. We need to undo that (effectively - * subtract one from last_prim->start) so that we copy the 0th vertex - * to the next vertex buffer. - */ - assert(last_prim->start > 0); - src -= sz; - } - /* fall-through */ - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) { - return 0; - } - else if (nr == 1) { - memcpy(dst, src+0, sz * sizeof(GLfloat)); - return 1; - } - else { - memcpy(dst, src+0, sz * sizeof(GLfloat)); - memcpy(dst+sz, src+(nr-1)*sz, sz * sizeof(GLfloat)); - return 2; - } - case GL_TRIANGLE_STRIP: - /* no parity issue, but need to make sure the tri is not drawn twice */ - if (nr & 1) { - last_prim->count--; - } - /* fallthrough */ - case GL_QUAD_STRIP: - switch (nr) { - case 0: - ovf = 0; - break; - case 1: - ovf = 1; - break; - default: - ovf = 2 + (nr & 1); - break; - } - for (i = 0 ; i < ovf ; i++) - memcpy(dst+i*sz, src+(nr-ovf+i)*sz, sz * sizeof(GLfloat)); - return i; - case PRIM_OUTSIDE_BEGIN_END: - return 0; - default: - unreachable("Unexpected primitive type"); - return 0; - } + return vbo_copy_vertices(exec->ctx, exec->ctx->Driver.CurrentExecPrimitive, + last_prim, sz, false, dst, src); } @@ -392,7 +304,7 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec) if (exec->vtx.prim_count && exec->vtx.vert_count) { - exec->vtx.copied.nr = vbo_copy_vertices(exec); + exec->vtx.copied.nr = vbo_exec_copy_vertices(exec); if (exec->vtx.copied.nr != exec->vtx.vert_count) { struct gl_context *ctx = exec->ctx; diff --git a/src/mesa/vbo/vbo_private.h b/src/mesa/vbo/vbo_private.h index c94215a20f5..93224d79ccd 100644 --- a/src/mesa/vbo/vbo_private.h +++ b/src/mesa/vbo/vbo_private.h @@ -185,6 +185,15 @@ void vbo_merge_prims(struct _mesa_prim *p0, const struct _mesa_prim *p1); +unsigned +vbo_copy_vertices(struct gl_context *ctx, + GLenum mode, + struct _mesa_prim *last_prim, + unsigned vertex_size, + bool in_dlist, + fi_type *dst, + const fi_type *src); + /** * Get the filter mask for vbo draws depending on the vertex_processing_mode. */ diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 1ef6043ad0c..50047f4aed5 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -111,79 +111,15 @@ copy_vertices(struct gl_context *ctx, const fi_type * src_buffer) { struct vbo_save_context *save = &vbo_context(ctx)->save; - const struct _mesa_prim *prim = &node->prims[node->prim_count - 1]; - GLuint nr = prim->count; + struct _mesa_prim *prim = &node->prims[node->prim_count - 1]; GLuint sz = save->vertex_size; const fi_type *src = src_buffer + prim->start * sz; fi_type *dst = save->copied.buffer; - GLuint ovf, i; if (prim->end) return 0; - switch (prim->mode) { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr & 1; - for (i = 0; i < ovf; i++) - memcpy(dst + i * sz, src + (nr - ovf + i) * sz, - sz * sizeof(GLfloat)); - return i; - case GL_TRIANGLES: - ovf = nr % 3; - for (i = 0; i < ovf; i++) - memcpy(dst + i * sz, src + (nr - ovf + i) * sz, - sz * sizeof(GLfloat)); - return i; - case GL_QUADS: - ovf = nr & 3; - for (i = 0; i < ovf; i++) - memcpy(dst + i * sz, src + (nr - ovf + i) * sz, - sz * sizeof(GLfloat)); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - else { - memcpy(dst, src + (nr - 1) * sz, sz * sizeof(GLfloat)); - return 1; - } - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - memcpy(dst, src + 0, sz * sizeof(GLfloat)); - return 1; - } - else { - memcpy(dst, src + 0, sz * sizeof(GLfloat)); - memcpy(dst + sz, src + (nr - 1) * sz, sz * sizeof(GLfloat)); - return 2; - } - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - switch (nr) { - case 0: - ovf = 0; - break; - case 1: - ovf = 1; - break; - default: - ovf = 2 + (nr & 1); - break; - } - for (i = 0; i < ovf; i++) - memcpy(dst + i * sz, src + (nr - ovf + i) * sz, - sz * sizeof(GLfloat)); - return i; - default: - unreachable("Unexpected primitive type"); - return 0; - } + return vbo_copy_vertices(ctx, prim->mode, prim, sz, true, dst, src); } -- 2.30.2