From e3ddc9be2bb3b65fde0524181f5cc0eb0c404bfd Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 20 Jun 2025 18:21:18 +0200 Subject: [PATCH] Grease Pencil: Avoid overhead when filling triangle index buffer Avoid 4 function calls and computing the min and max index for every triangle. Instead just fill the index buffer data directly. For me this gives a 6% FPS playback improvement in the 4.3 splash screen file. Pull Request: https://projects.blender.org/blender/blender/pulls/140684 --- .../intern/draw_cache_impl_grease_pencil.cc | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc index 05deb65c91a..35c1b8507f6 100644 --- a/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_grease_pencil.cc @@ -1166,11 +1166,13 @@ static void grease_pencil_geom_batch_ensure(Object &object, GPU_vertbuf_data_alloc(*cache->vbo, total_verts_num + 2); GPU_vertbuf_data_alloc(*cache->vbo_col, total_verts_num + 2); - GPUIndexBufBuilder ibo; MutableSpan verts = cache->vbo->data(); MutableSpan cols = cache->vbo_col->data(); /* Create IBO. */ - GPU_indexbuf_init(&ibo, GPU_PRIM_TRIS, total_triangles_num, 0xFFFFFFFFu); + GPUIndexBufBuilder ibo; + GPU_indexbuf_init(&ibo, GPU_PRIM_TRIS, total_triangles_num, INT_MAX); + MutableSpan triangle_ibo_data = GPU_indexbuf_get_data(&ibo).cast(); + int triangle_ibo_index = 0; /* Fill buffers with data. */ for (const int drawing_i : drawings.index_range()) { @@ -1264,8 +1266,10 @@ static void grease_pencil_geom_batch_ensure(Object &object, c_vert.fcol[3] = (int(c_vert.fcol[3] * 10000.0f) * 10.0f) + fill_opacities[curve_i]; int v_mat = (verts_range[idx] << GP_VERTEX_ID_SHIFT) | GP_IS_STROKE_VERTEX_BIT; - GPU_indexbuf_add_tri_verts(&ibo, v_mat + 0, v_mat + 1, v_mat + 2); - GPU_indexbuf_add_tri_verts(&ibo, v_mat + 2, v_mat + 1, v_mat + 3); + triangle_ibo_data[triangle_ibo_index] = uint3(v_mat + 0, v_mat + 1, v_mat + 2); + triangle_ibo_index++; + triangle_ibo_data[triangle_ibo_index] = uint3(v_mat + 2, v_mat + 1, v_mat + 3); + triangle_ibo_index++; }; visible_strokes.foreach_index([&](const int curve_i, const int pos) { @@ -1288,10 +1292,11 @@ static void grease_pencil_geom_batch_ensure(Object &object, if (points.size() >= 3) { const Span tris_slice = triangles.slice(tris_start_offset, points.size() - 2); for (const int3 tri : tris_slice) { - GPU_indexbuf_add_tri_verts(&ibo, - (verts_range[1] + tri.x) << GP_VERTEX_ID_SHIFT, - (verts_range[1] + tri.y) << GP_VERTEX_ID_SHIFT, - (verts_range[1] + tri.z) << GP_VERTEX_ID_SHIFT); + triangle_ibo_data[triangle_ibo_index] = uint3( + (verts_range[1] + tri.x) << GP_VERTEX_ID_SHIFT, + (verts_range[1] + tri.y) << GP_VERTEX_ID_SHIFT, + (verts_range[1] + tri.z) << GP_VERTEX_ID_SHIFT); + triangle_ibo_index++; } } @@ -1341,7 +1346,7 @@ static void grease_pencil_geom_batch_ensure(Object &object, verts[0].mat = -1; /* Finish the IBO. */ - cache->ibo = GPU_indexbuf_build(&ibo); + cache->ibo = GPU_indexbuf_build_ex(&ibo, 0, INT_MAX, false); /* Create the batches */ cache->geom_batch = GPU_batch_create(GPU_PRIM_TRIS, cache->vbo, cache->ibo); /* Allow creation of buffer texture. */