Fix #122455: Wireframe overlay can crash with loose geometry

The `nor` vertex buffer wasn't large enough for the indices in the lines
index buffer. This is undefined behavior at best AFAIK. On some drivers
it caused crashes when there was only loose geometry.

This commit makes the VBO large enough for all indices, filling the loose
geometry normals with (0,0,0,0), which the overlay wireframe shader
already checks for.

Pull Request: https://projects.blender.org/blender/blender/pulls/122720
This commit is contained in:
Hans Goudey 2024-06-04 17:43:11 +02:00 committed by Hans Goudey
parent b5a4786064
commit aa81e2dd4a

@ -215,6 +215,7 @@ static void extract_normals_bm(const MeshRenderData &mr, MutableSpan<GPUType> no
void extract_normals(const MeshRenderData &mr, const bool use_hq, gpu::VertBuf &vbo)
{
const int size = mr.corners_num + mr.loose_indices_num;
if (use_hq) {
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
@ -223,15 +224,19 @@ void extract_normals(const MeshRenderData &mr, const bool use_hq, gpu::VertBuf &
}
GPU_vertbuf_init_with_format(&vbo, &format);
GPU_vertbuf_data_alloc(&vbo, mr.corners_num);
MutableSpan vbo_data(static_cast<short4 *>(GPU_vertbuf_get_data(&vbo)), mr.corners_num);
MutableSpan vbo_data(static_cast<short4 *>(GPU_vertbuf_get_data(&vbo)), size);
MutableSpan corners_data = vbo_data.take_front(mr.corners_num);
MutableSpan loose_data = vbo_data.take_back(mr.loose_indices_num);
if (mr.extract_type == MR_EXTRACT_MESH) {
extract_normals_mesh(mr, vbo_data);
extract_paint_overlay_flags(mr, vbo_data);
extract_normals_mesh(mr, corners_data);
extract_paint_overlay_flags(mr, corners_data);
}
else {
extract_normals_bm(mr, vbo_data);
extract_normals_bm(mr, corners_data);
}
loose_data.fill(short4(0));
}
else {
static GPUVertFormat format = {0};
@ -240,17 +245,20 @@ void extract_normals(const MeshRenderData &mr, const bool use_hq, gpu::VertBuf &
GPU_vertformat_alias_add(&format, "lnor");
}
GPU_vertbuf_init_with_format(&vbo, &format);
GPU_vertbuf_data_alloc(&vbo, mr.corners_num);
MutableSpan vbo_data(static_cast<GPUPackedNormal *>(GPU_vertbuf_get_data(&vbo)),
mr.corners_num);
GPU_vertbuf_data_alloc(&vbo, size);
MutableSpan vbo_data(static_cast<GPUPackedNormal *>(GPU_vertbuf_get_data(&vbo)), size);
MutableSpan corners_data = vbo_data.take_front(mr.corners_num);
MutableSpan loose_data = vbo_data.take_back(mr.loose_indices_num);
if (mr.extract_type == MR_EXTRACT_MESH) {
extract_normals_mesh(mr, vbo_data);
extract_paint_overlay_flags(mr, vbo_data);
extract_normals_mesh(mr, corners_data);
extract_paint_overlay_flags(mr, corners_data);
}
else {
extract_normals_bm(mr, vbo_data);
extract_normals_bm(mr, corners_data);
}
loose_data.fill(GPUPackedNormal{});
}
}