From a20f36737958e5857aafaad84f7fe8590427cd08 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Thu, 26 Jun 2025 13:59:20 -0400 Subject: [PATCH 1/2] Fix #141026: Degenerate Dissolve crashes Blender. The code added in commit ffc204d1faca to dissolve redundant 2-edged vertices after a manifold boolean assumed that after dissolving such vertices a valid face would remain. This is not true of the face started out degenerate (all vertices on the same line). Fixed by checking for such cases and in any case not creating any faces with less than three vertices. --- .../geometry/intern/mesh_boolean_manifold.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/source/blender/geometry/intern/mesh_boolean_manifold.cc b/source/blender/geometry/intern/mesh_boolean_manifold.cc index b3e296df54d..7e90ed447ab 100644 --- a/source/blender/geometry/intern/mesh_boolean_manifold.cc +++ b/source/blender/geometry/intern/mesh_boolean_manifold.cc @@ -1240,6 +1240,9 @@ static void dissolve_valence2_verts(MeshAssembly &ma) for (const int f : ma.new_faces.index_range()) { const OutFace &face = ma.new_faces[f]; const int fsize = face.verts.size(); + if (fsize <= 3) { + continue; + } for (const int i : ma.new_faces[f].verts.index_range()) { const int vprev = face.verts[(i - 1 + fsize) % fsize]; const int v = face.verts[i]; @@ -1319,6 +1322,9 @@ static void dissolve_valence2_verts(MeshAssembly &ma) threading::parallel_for(ma.new_faces.index_range(), 10000, [&](IndexRange range) { for (const int f : range) { OutFace &face = ma.new_faces[f]; + if (face.verts.size() <= 3) { + continue; + } int i_to = 0; for (const int i_from : face.verts.index_range()) { const int mapped_v_from = ma.mapped_vert(face.verts[i_from]); @@ -1327,7 +1333,17 @@ static void dissolve_valence2_verts(MeshAssembly &ma) } } if (i_to < face.verts.size()) { - BLI_assert(i_to >= 3); + if (i_to < 3) { + /* Should be very rare. Means we dissolved two or more vertices from + * a degenerate ngon. Since its too late to really undo that, just make + * a valid triangle with undeleted verts. */ + if (i_to == 0) { + face.verts[i_to++] = 0; + } + while (i_to < 3) { + face.verts[i_to++] = face.verts[0]; + } + } face.verts.resize(i_to); } } From d67b705d1c28e148163607fcd314d907c696aca7 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 27 Jun 2025 08:58:37 +0200 Subject: [PATCH 2/2] Fix: Vulkan: Validation error Wayland+NVIDIA This PR fixes a validation error about the swapchain semaphores. When swapchain maintenance 1 is supported the semaphores can be reused, but requires a fence. We didn't implement the fence. This PR doesn't reuse the semaphores as introducing the fence leads to more changes. Pull Request: https://projects.blender.org/blender/blender/pulls/141066 --- intern/ghost/intern/GHOST_ContextVK.cc | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextVK.cc b/intern/ghost/intern/GHOST_ContextVK.cc index 5455243fb6a..bc3f6dfb452 100644 --- a/intern/ghost/intern/GHOST_ContextVK.cc +++ b/intern/ghost/intern/GHOST_ContextVK.cc @@ -1075,13 +1075,10 @@ GHOST_TSuccess GHOST_ContextVK::recreateSwapchain() GHOST_FrameDiscard &discard_pile = m_frame_data[m_render_frame].discard_pile; for (GHOST_SwapchainImage &swapchain_image : m_swapchain_images) { swapchain_image.vk_image = VK_NULL_HANDLE; - if (!vulkan_device->use_vk_ext_swapchain_maintenance_1 && - swapchain_image.present_semaphore != VK_NULL_HANDLE) - { + if (swapchain_image.present_semaphore != VK_NULL_HANDLE) { discard_pile.semaphores.push_back(swapchain_image.present_semaphore); swapchain_image.present_semaphore = VK_NULL_HANDLE; } - swapchain_image.vk_image = VK_NULL_HANDLE; } m_swapchain_images.resize(actual_image_count); std::vector swapchain_images(actual_image_count); @@ -1106,11 +1103,9 @@ GHOST_TSuccess GHOST_ContextVK::recreateSwapchain() /* Construct new semaphores. It can be that image_count is larger than previously. We only need * to fill in where the handle is `VK_NULL_HANDLE`. */ /* Previous handles from the frame data cannot be used and should be discarded. */ - if (!vulkan_device->use_vk_ext_swapchain_maintenance_1) { - for (GHOST_Frame &frame : m_frame_data) { - discard_pile.semaphores.push_back(frame.acquire_semaphore); - frame.acquire_semaphore = VK_NULL_HANDLE; - } + for (GHOST_Frame &frame : m_frame_data) { + discard_pile.semaphores.push_back(frame.acquire_semaphore); + frame.acquire_semaphore = VK_NULL_HANDLE; } if (old_swapchain) { discard_pile.swapchains.push_back(old_swapchain);