Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/intern/draw_cache_extract_mesh.c
| Show First 20 Lines • Show All 791 Lines • ▼ Show 20 Lines | BLI_INLINE eMRIterType mesh_extract_iter_type(const MeshExtract *ext) | ||||
| SET_FLAG_FROM_TEST(type, (ext->iter_ledge_bm || ext->iter_ledge_mesh), MR_ITER_LEDGE); | SET_FLAG_FROM_TEST(type, (ext->iter_ledge_bm || ext->iter_ledge_mesh), MR_ITER_LEDGE); | ||||
| SET_FLAG_FROM_TEST(type, (ext->iter_lvert_bm || ext->iter_lvert_mesh), MR_ITER_LVERT); | SET_FLAG_FROM_TEST(type, (ext->iter_lvert_bm || ext->iter_lvert_mesh), MR_ITER_LVERT); | ||||
| return type; | return type; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* ---------------------------------------------------------------------- */ | /* ---------------------------------------------------------------------- */ | ||||
| /** \name Extract Triangles Indices | /** \name Extract Triangles Indices (multi material) | ||||
| * \{ */ | * \{ */ | ||||
| typedef struct MeshExtract_Tri_Data { | typedef struct MeshExtract_Tri_Data { | ||||
| GPUIndexBufBuilder elb; | GPUIndexBufBuilder elb; | ||||
| int *tri_mat_start; | int *tri_mat_start; | ||||
| int *tri_mat_end; | int *tri_mat_end; | ||||
| } MeshExtract_Tri_Data; | } MeshExtract_Tri_Data; | ||||
| ▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | static const MeshExtract extract_tris = { | ||||
| .finish = extract_tris_finish, | .finish = extract_tris_finish, | ||||
| .data_flag = 0, | .data_flag = 0, | ||||
| .use_threading = false, | .use_threading = false, | ||||
| }; | }; | ||||
| /** \} */ | /** \} */ | ||||
| /* ---------------------------------------------------------------------- */ | /* ---------------------------------------------------------------------- */ | ||||
| /** \name Extract Triangles Indices (single material) | |||||
| * \{ */ | |||||
| static void *extract_tris_single_mat_init(const MeshRenderData *mr, | |||||
| struct MeshBatchCache *UNUSED(cache), | |||||
| void *UNUSED(ibo)) | |||||
| { | |||||
| GPUIndexBufBuilder *elb = MEM_mallocN(sizeof(*elb), __func__); | |||||
| GPU_indexbuf_init(elb, GPU_PRIM_TRIS, mr->tri_len, mr->loop_len); | |||||
| return elb; | |||||
| } | |||||
| static void extract_tris_single_mat_iter_looptri_bm(const MeshRenderData *UNUSED(mr), | |||||
| const struct ExtractTriBMesh_Params *params, | |||||
| void *elb) | |||||
| { | |||||
| EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elt, elt_index, params) | |||||
| { | |||||
| if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) { | |||||
| GPU_indexbuf_set_tri_verts(elb, | |||||
| elt_index, | |||||
| BM_elem_index_get(elt[0]), | |||||
| BM_elem_index_get(elt[1]), | |||||
| BM_elem_index_get(elt[2])); | |||||
| } | |||||
| else { | |||||
| GPU_indexbuf_set_tri_restart(elb, elt_index); | |||||
| } | |||||
| } | |||||
| EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END; | |||||
| } | |||||
| static void extract_tris_single_mat_iter_looptri_mesh(const MeshRenderData *mr, | |||||
| const struct ExtractTriMesh_Params *params, | |||||
| void *elb) | |||||
| { | |||||
| EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(mlt, mlt_index, params) | |||||
| { | |||||
| const MPoly *mp = &mr->mpoly[mlt->poly]; | |||||
| if (!(mr->use_hide && (mp->flag & ME_HIDE))) { | |||||
| GPU_indexbuf_set_tri_verts(elb, mlt_index, mlt->tri[0], mlt->tri[1], mlt->tri[2]); | |||||
| } | |||||
| else { | |||||
| GPU_indexbuf_set_tri_restart(elb, mlt_index); | |||||
| } | |||||
| } | |||||
| EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END; | |||||
| } | |||||
| static void extract_tris_single_mat_finish(const MeshRenderData *mr, | |||||
| struct MeshBatchCache *cache, | |||||
| void *ibo, | |||||
| void *_elb) | |||||
| { | |||||
| GPUIndexBufBuilder *elb = _elb; | |||||
| GPU_indexbuf_build_in_place(elb, ibo); | |||||
| /* Create ibo sub-ranges. Always do this to avoid error when the standard surface batch | |||||
| * is created before the surfaces-per-material. */ | |||||
| if (mr->use_final_mesh && cache->final.tris_per_mat) { | |||||
| MeshBufferCache *mbc = &cache->final; | |||||
| for (int i = 0; i < mr->mat_len; i++) { | |||||
| /* These IBOs have not been queried yet but we create them just in case they are needed | |||||
| * later since they are not tracked by mesh_buffer_cache_create_requested(). */ | |||||
| if (mbc->tris_per_mat[i] == NULL) { | |||||
| mbc->tris_per_mat[i] = GPU_indexbuf_calloc(); | |||||
| } | |||||
| /* Multiply by 3 because these are triangle indices. */ | |||||
| const int len = mr->tri_len * 3; | |||||
| GPU_indexbuf_create_subrange_in_place(mbc->tris_per_mat[i], ibo, 0, len); | |||||
| } | |||||
| } | |||||
| } | |||||
| static const MeshExtract extract_tris_single_mat = { | |||||
| .init = extract_tris_single_mat_init, | |||||
| .iter_looptri_bm = extract_tris_single_mat_iter_looptri_bm, | |||||
| .iter_looptri_mesh = extract_tris_single_mat_iter_looptri_mesh, | |||||
| .finish = extract_tris_single_mat_finish, | |||||
| .data_flag = 0, | |||||
| .use_threading = true, | |||||
| }; | |||||
| /** \} */ | |||||
| /* ---------------------------------------------------------------------- */ | |||||
| /** \name Extract Edges Indices | /** \name Extract Edges Indices | ||||
| * \{ */ | * \{ */ | ||||
| static void *extract_lines_init(const MeshRenderData *mr, | static void *extract_lines_init(const MeshRenderData *mr, | ||||
| struct MeshBatchCache *UNUSED(cache), | struct MeshBatchCache *UNUSED(cache), | ||||
| void *UNUSED(buf)) | void *UNUSED(buf)) | ||||
| { | { | ||||
| GPUIndexBufBuilder *elb = MEM_mallocN(sizeof(*elb), __func__); | GPUIndexBufBuilder *elb = MEM_mallocN(sizeof(*elb), __func__); | ||||
| ▲ Show 20 Lines • Show All 5,130 Lines • ▼ Show 20 Lines | #define EXTRACT(buf, name) \ | ||||
| EXTRACT(vbo, fdots_uv); | EXTRACT(vbo, fdots_uv); | ||||
| EXTRACT(vbo, fdots_edituv_data); | EXTRACT(vbo, fdots_edituv_data); | ||||
| EXTRACT(vbo, poly_idx); | EXTRACT(vbo, poly_idx); | ||||
| EXTRACT(vbo, edge_idx); | EXTRACT(vbo, edge_idx); | ||||
| EXTRACT(vbo, vert_idx); | EXTRACT(vbo, vert_idx); | ||||
| EXTRACT(vbo, fdot_idx); | EXTRACT(vbo, fdot_idx); | ||||
| EXTRACT(vbo, skin_roots); | EXTRACT(vbo, skin_roots); | ||||
| EXTRACT(ibo, tris); | if (mbc.ibo.tris) { | ||||
| if (mr->mat_len < 2) { | |||||
| /* | |||||
| * When mesh contains single material we use a multi threaded approach. | |||||
| * The downside of the multi threaded approach is that the ibo isn't compressed. | |||||
| * that leads to additional overhead when uploading the ibo to the GPU. | |||||
| */ | |||||
| extract_task_create(task_graph, | |||||
| task_node_mesh_render_data, | |||||
| task_node_user_data_init, | |||||
| &single_threaded_task_data->task_datas, | |||||
| &user_data_init_task_data->task_datas, | |||||
| scene, | |||||
| mr, | |||||
| cache, | |||||
| &extract_tris_single_mat, | |||||
| mbc.ibo.tris, | |||||
| &task_counters[counter_used++]); | |||||
| } | |||||
| else { | |||||
| /* | |||||
| * When mesh has multiple material slots the tris are sorted by slot index and hidden tris | |||||
| * are not added to reduce the amount of data to be uploaded to the GPU. The sorting is done | |||||
| * to create sub buffers for each material. | |||||
| */ | |||||
| extract_task_create(task_graph, | |||||
| task_node_mesh_render_data, | |||||
| task_node_user_data_init, | |||||
| &single_threaded_task_data->task_datas, | |||||
| &user_data_init_task_data->task_datas, | |||||
| scene, | |||||
| mr, | |||||
| cache, | |||||
| &extract_tris, | |||||
| mbc.ibo.tris, | |||||
| &task_counters[counter_used++]); | |||||
| } | |||||
| } | |||||
| if (mbc.ibo.lines) { | if (mbc.ibo.lines) { | ||||
| /* When `lines` and `lines_loose` are requested, schedule lines extraction that also creates | /* When `lines` and `lines_loose` are requested, schedule lines extraction that also creates | ||||
| * the `lines_loose` sub-buffer. */ | * the `lines_loose` sub-buffer. */ | ||||
| const MeshExtract *lines_extractor = do_lines_loose_subbuffer ? | const MeshExtract *lines_extractor = do_lines_loose_subbuffer ? | ||||
| &extract_lines_with_lines_loose : | &extract_lines_with_lines_loose : | ||||
| &extract_lines; | &extract_lines; | ||||
| extract_task_create(task_graph, | extract_task_create(task_graph, | ||||
| task_node_mesh_render_data, | task_node_mesh_render_data, | ||||
| ▲ Show 20 Lines • Show All 71 Lines • Show Last 20 Lines | |||||