perf(viz): graph_renderer edges via TBO + vertex pulling (issue 0049d)
El buffer de aristas pasa a estatico (16B/arista: source, target, color, flags) y solo se reupload cuando cambia el grafo. Las posiciones de los nodos viven en un Texture Buffer Object (RG32F) actualizado por frame; el vertex shader hace texelFetch con gl_VertexID & 1 para elegir endpoint. Draw call: glDrawArraysInstanced(GL_LINES, 0, 2, edge_count) con divisor=1. Para 100k aristas: el upload de 4.8 MB/frame baja a 0 en regimen estable. edge_alpha pasa a uniform; la pre-multiplicacion en CPU desaparece. GLSL sigue en 330 core (samplerBuffer/texelFetch estan en 1.40+). gl_loader gana glBufferSubData, glVertexAttribIPointer y glTexBuffer (en Linux ya estaban via GL_GLEXT_PROTOTYPES; ahora estan disponibles tambien en MinGW/Windows). Tests: nuevo test_graph_edge_static valida el layout de 16B y el packing RGBA8 del fallback. test_visual sigue verde — render visualmente identico. Bump graph_renderer 1.2.0 -> 1.3.0.
This commit is contained in:
@@ -66,6 +66,10 @@ add_fn_test(test_graph_should_pause test_graph_should_pause.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../functions/viz/graph_force_layout.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../functions/viz/graph_types.cpp)
|
||||
|
||||
# --- Issue 0049d — vertex pulling edge buffer (logica solo, sin GL) --------
|
||||
add_fn_test(test_graph_edge_static test_graph_edge_static.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../functions/viz/graph_types.cpp)
|
||||
|
||||
# --- Visual golden-image diff (issue 0048) ---------------------------------
|
||||
# El binario primitives_gallery se compila con --capture; el test compara los
|
||||
# PNGs generados con los goldens en cpp/tests/golden/. Si no hay goldens o el
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Smoke test for graph_renderer's vertex-pulling edge buffer layout (issue
|
||||
// 0049d). El test no toca GL — solo verifica las garantias estructurales que
|
||||
// el renderer asume:
|
||||
// 1. EdgeStatic mide 16 bytes (alineacion natural sin padding sorpresa).
|
||||
// 2. Los offsets de source/target/color/flags son 0/4/8/12.
|
||||
// 3. La paleta de colores por defecto del fallback (gris 0x88) tiene la
|
||||
// forma RGBA8 esperada por el shader (R en byte 0).
|
||||
//
|
||||
// Render-a-FBO-y-readback queda fuera porque exigirseria un contexto GL en
|
||||
// el runner de tests; ya hay un golden image gate via test_visual + capture
|
||||
// en primitives_gallery.
|
||||
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch_amalgamated.hpp"
|
||||
|
||||
#include "viz/graph_renderer.h"
|
||||
#include "viz/graph_types.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
// Re-declaramos la struct local a graph_renderer.cpp para chequear su layout
|
||||
// "en espejo". Si cambia el layout en el .cpp, este test debe actualizarse —
|
||||
// es intencional: el shader y el VAO setup dependen de estos offsets.
|
||||
namespace test_layout {
|
||||
struct EdgeStatic {
|
||||
uint32_t source;
|
||||
uint32_t target;
|
||||
uint32_t color;
|
||||
uint32_t flags;
|
||||
};
|
||||
} // namespace test_layout
|
||||
|
||||
TEST_CASE("EdgeStatic mide 16 bytes y tiene offsets contiguos", "[viz][edge_static]") {
|
||||
using test_layout::EdgeStatic;
|
||||
REQUIRE(sizeof(EdgeStatic) == 16);
|
||||
REQUIRE(offsetof(EdgeStatic, source) == 0);
|
||||
REQUIRE(offsetof(EdgeStatic, target) == 4);
|
||||
REQUIRE(offsetof(EdgeStatic, color) == 8);
|
||||
REQUIRE(offsetof(EdgeStatic, flags) == 12);
|
||||
}
|
||||
|
||||
TEST_CASE("Fallback gris 0x88 tiene R en el byte LSB", "[viz][edge_static]") {
|
||||
// El renderer construye `pack_rgba8(0x88, 0x88, 0x88, 0xFF)` cuando
|
||||
// `e.color == 0`. El shader hace unpack manual asumiendo R en LSB.
|
||||
uint32_t gray = pack_rgba8(0x88, 0x88, 0x88, 0xFF);
|
||||
REQUIRE((gray & 0xFFu) == 0x88u); // R
|
||||
REQUIRE(((gray >> 8) & 0xFFu) == 0x88u); // G
|
||||
REQUIRE(((gray >> 16) & 0xFFu) == 0x88u); // B
|
||||
REQUIRE(((gray >> 24) & 0xFFu) == 0xFFu); // A
|
||||
}
|
||||
|
||||
TEST_CASE("GraphEdge.color = 0 indica fallback al gris por defecto",
|
||||
"[viz][edge_static]") {
|
||||
GraphEdge e = graph_edge(0, 1, 1.0f);
|
||||
REQUIRE(e.color == 0u);
|
||||
// El renderer interpreta esto como "usa el gris 0x88,0x88,0x88,0xFF".
|
||||
// Un agente que precarga colores debe usar `pack_rgba8` para evitar
|
||||
// colisionar con el sentinel 0.
|
||||
}
|
||||
Reference in New Issue
Block a user