#pragma once namespace fn::gfx { // Despacha un compute con num_invocations hilos totales (1D), agrupados en // workgroups de tamano local_size_x. Calcula ceil(num/local). El programa // debe estar activo (glUseProgram llamado antes) y los SSBOs ya bindeados. // // Ejemplo: dispatch_1d(N, 64) emite glDispatchCompute((N+63)/64, 1, 1). void dispatch_1d(int num_invocations, int local_size_x = 64); // Variante 2D para grids tipo (width, height) — heatmaps, samples_to_grid_2d, // histogram_2d. Local 8x8 = 64 invocaciones por workgroup. void dispatch_2d(int width, int height, int local_size_x = 8, int local_size_y = 8); // Variante 3D (poco usada — expuesta por completitud). void dispatch_3d(int x, int y, int z, int local_size_x = 4, int local_size_y = 4, int local_size_z = 4); // Helpers de glMemoryBarrier para los casos comunes despues de un dispatch. // barrier_storage: el siguiente compute leera SSBOs escritos en este pase. void barrier_storage(); // barrier_uniform: cambios subsiguientes a uniforms se ven correctamente. void barrier_uniform(); // barrier_image: image2D writes -> reads (si se usan imageStore en compute). void barrier_image(); // barrier_buffer_update: glGetBufferSubData / glBufferSubData veran lo escrito // por el compute. Necesario antes de readback a CPU. void barrier_buffer_update(); // barrier_all: GL_ALL_BARRIER_BITS — usar en debug; conservador y caro. void barrier_all(); } // namespace fn::gfx