Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_buffers.c
| Show First 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | struct GPU_PBVH_Buffers { | ||||
| /* The PBVH ensures that either all faces in the node are | /* The PBVH ensures that either all faces in the node are | ||||
| * smooth-shaded or all faces are flat-shaded */ | * smooth-shaded or all faces are flat-shaded */ | ||||
| bool smooth; | bool smooth; | ||||
| bool show_mask; | bool show_mask; | ||||
| }; | }; | ||||
| static struct { | static struct { | ||||
| uint pos, nor, msk; | uint pos, nor, msk, col; | ||||
| } g_vbo_id = {0}; | } g_vbo_id = {0}; | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name PBVH Utils | /** \name PBVH Utils | ||||
| * \{ */ | * \{ */ | ||||
| Show All 23 Lines | |||||
| #else | #else | ||||
| if (buffers->vert_buf == NULL) { | if (buffers->vert_buf == NULL) { | ||||
| /* Initialize vertex buffer (match 'VertexBufferFormat'). */ | /* Initialize vertex buffer (match 'VertexBufferFormat'). */ | ||||
| static GPUVertFormat format = {0}; | static GPUVertFormat format = {0}; | ||||
| if (format.attr_len == 0) { | if (format.attr_len == 0) { | ||||
| g_vbo_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); | g_vbo_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); | ||||
| g_vbo_id.nor = GPU_vertformat_attr_add( | g_vbo_id.nor = GPU_vertformat_attr_add( | ||||
| &format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); | &format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); | ||||
| /* TODO: Do not allocate these `.msk` and `.col` when they are not used. */ | |||||
| g_vbo_id.msk = GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); | g_vbo_id.msk = GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); | ||||
| g_vbo_id.col = GPU_vertformat_attr_add( | |||||
fclem: I'm not really happy with that but we have the same issue with the "msk" attrib. It's always… | |||||
| &format, "c", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); | |||||
| } | } | ||||
| buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC); | buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC); | ||||
| } | } | ||||
| GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); | GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); | ||||
| #endif | #endif | ||||
| return buffers->vert_buf->data != NULL; | return buffers->vert_buf->data != NULL; | ||||
| } | } | ||||
| Show All 35 Lines | |||||
| /** \name Mesh PBVH | /** \name Mesh PBVH | ||||
| * \{ */ | * \{ */ | ||||
| void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, | void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, | ||||
| const MVert *mvert, | const MVert *mvert, | ||||
| const int *vert_indices, | const int *vert_indices, | ||||
| int totvert, | int totvert, | ||||
| const float *vmask, | const float *vmask, | ||||
| const MLoopCol *vcol, | |||||
| const int (*face_vert_indices)[3], | const int (*face_vert_indices)[3], | ||||
| const int update_flags) | const int update_flags) | ||||
| { | { | ||||
| const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | ||||
| const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0; | |||||
| bool empty_mask = true; | bool empty_mask = true; | ||||
| { | { | ||||
| int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3)); | int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3)); | ||||
| /* Build VBO */ | /* Build VBO */ | ||||
| if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { | if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { | ||||
| /* Vertex data is shared if smooth-shaded, but separate | /* Vertex data is shared if smooth-shaded, but separate | ||||
| Show All 13 Lines | if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { | ||||
| int vidx = face_vert_indices[i][j]; | int vidx = face_vert_indices[i][j]; | ||||
| int v_index = buffers->mloop[lt->tri[j]].v; | int v_index = buffers->mloop[lt->tri[j]].v; | ||||
| float fmask = vmask[v_index]; | float fmask = vmask[v_index]; | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vidx, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vidx, &fmask); | ||||
| empty_mask = empty_mask && (fmask == 0.0f); | empty_mask = empty_mask && (fmask == 0.0f); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (vcol && show_vcol) { | |||||
Done Inline ActionsI think we should only do that if the vcol is also being displayed. (i.e. have a bool show_vcol) fclem: I think we should only do that if the vcol is also being displayed. (i.e. have a bool show_vcol) | |||||
| for (uint i = 0; i < buffers->face_indices_len; i++) { | |||||
| const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]]; | |||||
| for (int j = 0; j < 3; j++) { | |||||
| const int loop_index = lt->tri[j]; | |||||
| const int vidx = face_vert_indices[i][j]; | |||||
| const uchar *elem = &vcol[loop_index].r; | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, elem); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| /* calculate normal for each polygon only once */ | /* calculate normal for each polygon only once */ | ||||
| uint mpoly_prev = UINT_MAX; | uint mpoly_prev = UINT_MAX; | ||||
| short no[3]; | short no[3]; | ||||
| int vbo_index = 0; | int vbo_index = 0; | ||||
| for (uint i = 0; i < buffers->face_indices_len; i++) { | for (uint i = 0; i < buffers->face_indices_len; i++) { | ||||
| Show All 24 Lines | if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { | ||||
| for (uint j = 0; j < 3; j++) { | for (uint j = 0; j < 3; j++) { | ||||
| const MVert *v = &mvert[vtri[j]]; | const MVert *v = &mvert[vtri[j]]; | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, v->co); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, v->co); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); | ||||
| if (vcol && show_vcol) { | |||||
| const uint loop_index = lt->tri[j]; | |||||
| const uchar *elem = &vcol[loop_index].r; | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, elem); | |||||
| } | |||||
| vbo_index++; | vbo_index++; | ||||
| } | } | ||||
| empty_mask = empty_mask && (fmask == 0.0f); | empty_mask = empty_mask && (fmask == 0.0f); | ||||
| } | } | ||||
| } | } | ||||
| gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); | gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); | ||||
| ▲ Show 20 Lines • Show All 239 Lines • ▼ Show 20 Lines | void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers, | ||||
| CCGElem **grids, | CCGElem **grids, | ||||
| const DMFlagMat *grid_flag_mats, | const DMFlagMat *grid_flag_mats, | ||||
| int *grid_indices, | int *grid_indices, | ||||
| int totgrid, | int totgrid, | ||||
| const CCGKey *key, | const CCGKey *key, | ||||
| const int update_flags) | const int update_flags) | ||||
| { | { | ||||
| const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | ||||
| const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0; | |||||
| bool empty_mask = true; | bool empty_mask = true; | ||||
| int i, j, k, x, y; | int i, j, k, x, y; | ||||
| const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; | const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; | ||||
| static char vcol[4] = {255, 255, 255, 255}; | |||||
| /* Build VBO */ | /* Build VBO */ | ||||
| const int has_mask = key->has_mask; | const int has_mask = key->has_mask; | ||||
| uint vert_per_grid = (smooth) ? key->grid_area : (SQUARE(key->grid_size - 1) * 4); | uint vert_per_grid = (smooth) ? key->grid_area : (SQUARE(key->grid_size - 1) * 4); | ||||
| uint vert_count = totgrid * vert_per_grid; | uint vert_count = totgrid * vert_per_grid; | ||||
| if (buffers->smooth != smooth) { | if (buffers->smooth != smooth) { | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | for (i = 0; i < totgrid; ++i) { | ||||
| normal_float_to_short_v3(no_short, CCG_elem_no(key, elem)); | normal_float_to_short_v3(no_short, CCG_elem_no(key, elem)); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); | ||||
| if (has_mask && show_mask) { | if (has_mask && show_mask) { | ||||
| float fmask = *CCG_elem_mask(key, elem); | float fmask = *CCG_elem_mask(key, elem); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); | ||||
| empty_mask = empty_mask && (fmask == 0.0f); | empty_mask = empty_mask && (fmask == 0.0f); | ||||
| } | } | ||||
| if (show_vcol) { | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, &vcol); | |||||
| } | |||||
| vbo_index += 1; | vbo_index += 1; | ||||
| } | } | ||||
| } | } | ||||
| vbo_index_offset += key->grid_area; | vbo_index_offset += key->grid_area; | ||||
| } | } | ||||
| else { | else { | ||||
| for (j = 0; j < key->grid_size - 1; j++) { | for (j = 0; j < key->grid_size - 1; j++) { | ||||
| for (k = 0; k < key->grid_size - 1; k++) { | for (k = 0; k < key->grid_size - 1; k++) { | ||||
| Show All 30 Lines | for (i = 0; i < totgrid; ++i) { | ||||
| *CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) * | *CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) * | ||||
| 0.25f; | 0.25f; | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 0, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 0, &fmask); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 1, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 1, &fmask); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 2, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 2, &fmask); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &fmask); | ||||
| empty_mask = empty_mask && (fmask == 0.0f); | empty_mask = empty_mask && (fmask == 0.0f); | ||||
| } | } | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 0, &vcol); | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 1, &vcol); | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 2, &vcol); | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 3, &vcol); | |||||
| vbo_index += 4; | vbo_index += 4; | ||||
| } | } | ||||
| } | } | ||||
| vbo_index_offset += SQUARE(key->grid_size - 1) * 4; | vbo_index_offset += SQUARE(key->grid_size - 1) * 4; | ||||
| } | } | ||||
| } | } | ||||
| gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); | gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); | ||||
| Show All 38 Lines | |||||
| */ | */ | ||||
| static void gpu_bmesh_vert_to_buffer_copy__gwn(BMVert *v, | static void gpu_bmesh_vert_to_buffer_copy__gwn(BMVert *v, | ||||
| GPUVertBuf *vert_buf, | GPUVertBuf *vert_buf, | ||||
| int *v_index, | int *v_index, | ||||
| const float fno[3], | const float fno[3], | ||||
| const float *fmask, | const float *fmask, | ||||
| const int cd_vert_mask_offset, | const int cd_vert_mask_offset, | ||||
| const bool show_mask, | const bool show_mask, | ||||
| const bool show_vcol, | |||||
| bool *empty_mask) | bool *empty_mask) | ||||
| { | { | ||||
| if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { | if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { | ||||
| /* Set coord, normal, and mask */ | /* Set coord, normal, and mask */ | ||||
| GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, *v_index, v->co); | GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, *v_index, v->co); | ||||
| short no_short[3]; | short no_short[3]; | ||||
| normal_float_to_short_v3(no_short, fno ? fno : v->no); | normal_float_to_short_v3(no_short, fno ? fno : v->no); | ||||
| GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short); | GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short); | ||||
| if (show_mask) { | if (show_mask) { | ||||
| float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset); | float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset); | ||||
| GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, *v_index, &effective_mask); | GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, *v_index, &effective_mask); | ||||
| *empty_mask = *empty_mask && (effective_mask == 0.0f); | *empty_mask = *empty_mask && (effective_mask == 0.0f); | ||||
| } | } | ||||
| if (show_vcol) { | |||||
| static char vcol[4] = {255, 255, 255, 255}; | |||||
| GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, *v_index, &vcol); | |||||
| } | |||||
| /* Assign index for use in the triangle index buffer */ | /* Assign index for use in the triangle index buffer */ | ||||
| /* note: caller must set: bm->elem_index_dirty |= BM_VERT; */ | /* note: caller must set: bm->elem_index_dirty |= BM_VERT; */ | ||||
| BM_elem_index_set(v, (*v_index)); /* set_dirty! */ | BM_elem_index_set(v, (*v_index)); /* set_dirty! */ | ||||
| (*v_index)++; | (*v_index)++; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
| void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers, | void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers, | ||||
| BMesh *bm, | BMesh *bm, | ||||
| GSet *bm_faces, | GSet *bm_faces, | ||||
| GSet *bm_unique_verts, | GSet *bm_unique_verts, | ||||
| GSet *bm_other_verts, | GSet *bm_other_verts, | ||||
| const int update_flags) | const int update_flags) | ||||
| { | { | ||||
| const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | ||||
| const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0; | |||||
| int tottri, totvert, maxvert = 0; | int tottri, totvert, maxvert = 0; | ||||
| bool empty_mask = true; | bool empty_mask = true; | ||||
| /* TODO, make mask layer optional for bmesh buffer */ | /* TODO, make mask layer optional for bmesh buffer */ | ||||
| const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK); | const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK); | ||||
| /* Count visible triangles */ | /* Count visible triangles */ | ||||
| tottri = gpu_bmesh_face_visible_count(bm_faces); | tottri = gpu_bmesh_face_visible_count(bm_faces); | ||||
| Show All 32 Lines | if (buffers->smooth) { | ||||
| GSET_ITER (gs_iter, bm_unique_verts) { | GSET_ITER (gs_iter, bm_unique_verts) { | ||||
| gpu_bmesh_vert_to_buffer_copy__gwn(BLI_gsetIterator_getKey(&gs_iter), | gpu_bmesh_vert_to_buffer_copy__gwn(BLI_gsetIterator_getKey(&gs_iter), | ||||
| buffers->vert_buf, | buffers->vert_buf, | ||||
| &v_index, | &v_index, | ||||
| NULL, | NULL, | ||||
| NULL, | NULL, | ||||
| cd_vert_mask_offset, | cd_vert_mask_offset, | ||||
| show_mask, | show_mask, | ||||
| show_vcol, | |||||
| &empty_mask); | &empty_mask); | ||||
| } | } | ||||
| GSET_ITER (gs_iter, bm_other_verts) { | GSET_ITER (gs_iter, bm_other_verts) { | ||||
| gpu_bmesh_vert_to_buffer_copy__gwn(BLI_gsetIterator_getKey(&gs_iter), | gpu_bmesh_vert_to_buffer_copy__gwn(BLI_gsetIterator_getKey(&gs_iter), | ||||
| buffers->vert_buf, | buffers->vert_buf, | ||||
| &v_index, | &v_index, | ||||
| NULL, | NULL, | ||||
| NULL, | NULL, | ||||
| cd_vert_mask_offset, | cd_vert_mask_offset, | ||||
| show_mask, | show_mask, | ||||
| show_vcol, | |||||
| &empty_mask); | &empty_mask); | ||||
| } | } | ||||
| maxvert = v_index; | maxvert = v_index; | ||||
| } | } | ||||
| else { | else { | ||||
| GSetIterator gs_iter; | GSetIterator gs_iter; | ||||
| Show All 25 Lines | else { | ||||
| for (i = 0; i < 3; i++) { | for (i = 0; i < 3; i++) { | ||||
| gpu_bmesh_vert_to_buffer_copy__gwn(v[i], | gpu_bmesh_vert_to_buffer_copy__gwn(v[i], | ||||
| buffers->vert_buf, | buffers->vert_buf, | ||||
| &v_index, | &v_index, | ||||
| f->no, | f->no, | ||||
| &fmask, | &fmask, | ||||
| cd_vert_mask_offset, | cd_vert_mask_offset, | ||||
| show_mask, | show_mask, | ||||
| show_vcol, | |||||
| &empty_mask); | &empty_mask); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines); | buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines); | ||||
| buffers->tot_tri = tottri; | buffers->tot_tri = tottri; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 174 Lines • Show Last 20 Lines | |||||
I'm not really happy with that but we have the same issue with the "msk" attrib. It's always allocated even if not used.
I have no real solution for this at the moment. So maybe add a TODO about this as comment.