feat(viz): graph_force_layout_gpu compute + spatial hash (issue 0049h)

Layout force-directed en GPU usando 5 compute shaders 4.3 + spatial hash
grid 64x64. API simetrica con graph_force_layout (CPU) para que el consumer
pueda swappear sin cambios. atomicCompSwap loop para float-add portable.

- cpp/functions/viz/graph_force_layout_gpu.{h,cpp,md}: nuevo modulo
- cpp/functions/gfx/gl_loader: anade glDispatchCompute, glMemoryBarrier,
  glBindBufferBase, glGetBufferSubData (Windows wgl)
- cpp/tests/test_graph_force_layout_gpu.cpp: smoke + pinned + CPU vs GPU.
  Crea ventana GLFW oculta GL 4.3; SKIP si headless o sin compute.
- demos_graph: checkbox "GPU layout" para swappear CPU/GPU en runtime
- issue movido a dev/issues/completed/
This commit is contained in:
2026-04-29 23:29:16 +02:00
parent 982a9f9a2b
commit 35312ea66e
11 changed files with 1096 additions and 2 deletions
+16
View File
@@ -80,6 +80,22 @@ add_fn_test(test_graph_sources test_graph_sources.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../functions/viz/graph_types.cpp)
target_link_libraries(test_graph_sources PRIVATE SQLite::SQLite3)
# --- Issue 0049h — graph_force_layout_gpu (compute + spatial hash) ----------
# El test crea una ventana GLFW oculta a 4.3 core; si glfwInit/window/context
# fallan (CI sin DISPLAY, Mesa sin compute), el test SKIPea. Linkamos contra
# glfw + OpenGL para que se resuelvan los simbolos en cualquier caso.
add_fn_test(test_graph_force_layout_gpu test_graph_force_layout_gpu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../functions/viz/graph_force_layout_gpu.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../functions/viz/graph_force_layout.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../functions/viz/graph_types.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../functions/gfx/gl_loader.cpp)
if(WIN32)
target_link_libraries(test_graph_force_layout_gpu PRIVATE glfw opengl32)
else()
find_package(OpenGL REQUIRED)
target_link_libraries(test_graph_force_layout_gpu PRIVATE glfw OpenGL::GL)
endif()
# --- Issue 0049f — atlas de iconos Tabler para graph_renderer ---------------
# graph_icons.cpp incluye gl_loader.h y referencia gl* — el atlas se puede
# construir sin contexto via FN_GRAPH_ICONS_SKIP_GL=1 (set por el test), pero