#pragma once #include "gfx/gpu_ssbo.h" namespace fn::gfx { enum class ReduceOp : int { Sum = 0, Min = 1, Max = 2 }; // Reductor paralelo sobre SSBO float[N]. Usa workgroup-shared reduction. // El reductor mantiene un SSBO intermedio para guardar los partials por // workgroup (1 partial por workgroup). Tras dispatch, el ultimo paso es // una reduccion CPU-side de los partials (count tipico: N/256 — barato). // // Para distintos N hay que destruir y recrear (el partials_capacity esta // dimensionado al peor N pasado al constructor). struct GpuReduce { unsigned int p_sum = 0; unsigned int p_min = 0; unsigned int p_max = 0; unsigned int loc_count = 0; unsigned int loc_count_min = 0; unsigned int loc_count_max = 0; Ssbo partials; // float[max_groups] int max_groups = 0; }; // max_n_samples: cota maxima del N que se reducira (dimensiona el partials). // El local_size esta fijado a 256 internamente (workgroup tipico para // shared-mem reduction en consumer GPUs). GpuReduce gpu_reduce_create(int max_n_samples); // Ejecuta reduce con la operacion indicada. Devuelve el resultado escalar. // Bloquea (incluye readback de partials). // // samples: SSBO float[count] (binding 0 dentro del shader). // count: cuantos samples efectivos procesar (<= max_n_samples). float gpu_reduce_run(GpuReduce& r, ReduceOp op, const Ssbo& samples, int count); // Mean = sum / count. Helper que llama Sum y divide. float gpu_reduce_mean(GpuReduce& r, const Ssbo& samples, int count); void gpu_reduce_destroy(GpuReduce& r); } // namespace fn::gfx