wandres.dev
NIVEL DIOS · Síntesis de WebGPU

Los cuarenta y seis niveles en un mapa

El recorrido completo del track de WebGPU nivel por nivel, las cinco ideas que lo atraviesan de principio a fin, y dónde volver cuando algo no encaje.

⏱ 20 min

Un track de cuarenta y siete niveles no se recuerda como una lista: se recuerda como un mapa, con regiones, fronteras y unas pocas carreteras que lo cruzan entero. Esta lección es ese mapa. Sirve para dos cosas: para ver de golpe la estructura de lo que has aprendido, y para saber a qué región volver cuando dentro de seis meses algo no encaje y no sepas por dónde empezar a mirar.

🎯 Al terminar esta lección sabrás
  • Reconstruir la estructura del track completo y las fronteras entre sus cuatro regiones.
  • Identificar las cinco ideas que reaparecen en niveles muy separados entre sí.
  • Localizar el nivel al que volver ante un síntoma concreto.
  • Distinguir lo que es conocimiento de WebGPU de lo que es conocimiento de gráficos en general.

Las cinco ideas que lo atraviesan

Antes del mapa, las carreteras. Hay cinco ideas que aparecen en el nivel 3 y siguen apareciendo en el 45, y quien las tiene claras puede reconstruir casi todo lo demás.

La validación es previa, no por llamada. WebGPU comprueba en la creación de los objetos, no en cada dibujado. De ahí sale casi todo lo que distingue a la API: los descriptores largos, los layouts explícitos, los pipelines inmutables, los bind groups agrupados, y el hecho de que dibujar sea barato. Cuando algo de la API te parezca innecesariamente ceremonioso, la respuesta casi siempre es que esa ceremonia compra una comprobación que no se repetirá sesenta veces por segundo.

Grabar no es ejecutar. El encoder graba, la cola ejecuta, y entre las dos cosas hay uno o dos fotogramas de distancia. Esa separación explica por qué medir con el reloj de la CPU no mide nada, por qué leer de la GPU es caro, por qué mapAsync es asíncrono, y por qué los resultados de una occlusion query llegan tarde. Media docena de comportamientos aparentemente inconexos son el mismo hecho visto desde ángulos distintos.

La memoria es el recurso escaso, no la aritmética. Una lectura de memoria global cuesta lo que cientos de multiplicaciones. Esa relación gobierna el tamaño del G-buffer, el diseño de las estructuras de datos, el uso de la memoria compartida, la elección de formatos, y la mayor parte de lo que hay que hacer cuando algo va lento.

El paralelismo tiene grano y el grano se nota. Las invocaciones se ejecutan en grupos que comparten el contador de programa, así que la divergencia cuesta, las barreras solo funcionan dentro de un workgroup, y el patrón de acceso importa más que el número de accesos. Es la misma idea detrás de la ocupación, de la coherencia de los rayos y del tamaño de workgroup.

La portabilidad es una propiedad del diseño, no una fase. Los límites por defecto, las features opcionales y la posibilidad de que no haya adaptador no son casos límite: son el contrato. Un motor que se diseña contra el contrato es portable; uno que se diseña contra tu tarjeta gráfica se arregla reescribiéndolo.

Del adaptador al triángulo, y del triángulo al lenguaje

Los cimientos, niveles 0 a 8

Aquí se construye el modelo mental. Qué es WebGPU y en qué se parece y en qué no a Vulkan, Metal y Direct3D 12; por qué la máquina de estados de WebGL tenía un techo; cómo es una GPU por dentro y por qué eso condiciona todo lo demás.

Nivel Qué fija
0 El mapa: qué es WebGPU, qué reemplaza, cómo se relaciona con las APIs nativas
1 Por qué existe: los límites del modelo de estados de WebGL y qué gana WebGPU
2 La GPU por dentro: ejecución en grupos, divergencia, latencia de memoria
3 Adaptador y dispositivo, features, límites, pérdida de dispositivo
4 El canvas: contexto, formato preferido, el ciclo de la textura del fotograma
5 Buffers: flags de uso, mappedAtCreation, writeBuffer, el modelo de memoria
6 El primer triángulo: módulo, pipeline, encoder, pass y envío
7 Command encoding: por qué se graba en vez de ejecutar
8 Sincronización: mapAsync, leer desde la GPU y por qué es caro

La frontera de esta región es el nivel 8, y la marca una pregunta: si entiendes por qué leer un buffer de la GPU no puede ser síncrono, has cruzado. Si no, todo lo demás se aprenderá de memoria.

El lenguaje y la rasterización, niveles 9 a 30

La región más grande. Cinco niveles de WGSL, dos de las etapas programables, ocho de recursos y estado, y seis de la maquinaria de render.

Nivel Qué fija
9 a 13 WGSL: sintaxis, tipos, espacios de dirección, atributos y builtins, funciones y control de flujo uniforme, librería estándar
14 y 15 Vertex y fragment: layouts de atributos, instancing, interpolación, múltiples targets, discard
16 override y la especialización de pipelines sin duplicar fuentes
17 y 18 Bind groups: el modelo de recursos y la organización por frecuencia de cambio
19 y 20 Uniform y storage buffers: alineación, padding, offsets dinámicos, arrays de tamaño variable
21 a 23 Texturas: creación y muestreo, mipmaps, arrays y cubemaps, storage textures
24 y 25 El descriptor de pipeline completo, profundidad, reversed-Z y estarcido
26 a 28 Mezcla y transparencia, render targets, multisampling
29 y 30 Instancing e indirect, y los render bundles

Si tuviera que señalar los dos niveles de esta región que más veces se vuelven a necesitar, serían el 19 por las reglas de alineación, que producen los bugs más silenciosos de todos, y el 18 por la organización de los bind groups, que es una decisión de arquitectura disfrazada de detalle.

La GPU como procesador general

Los niveles 31 a 37 cambian de disciplina. Ya no se dibuja: se calcula. Y el vocabulario nuevo (workgroups, barreras, reducciones, escaneos) es el que hace posible casi todo lo que viene después.

Nivel Qué fija
31 El modelo de ejecución: workgroups, jerarquía de identificadores, dimensionar el despacho
32 Memoria compartida, workgroupBarrier, storageBarrier, las carreras
33 Los dos patrones fundamentales: reducción en árbol y prefix sum
34 Ordenación en GPU: la red bitónica y el radix paralelo
35 Partículas: el sistema completo en GPU, estado y render desde el mismo buffer
36 Estructuras espaciales: hash grid, ordenar por celda, búsqueda de vecinos
37 GEMM con tiling, convoluciones, y el estado de WebNN

El nivel 33 es la pieza que más se reutiliza sin que lo parezca: la reducción aparece en cada métrica que calcules en GPU, y el scan es exactamente lo que hace falta para compactar la lista de objetos visibles en el culling dirigido por GPU. Cuando en el nivel 40 se compacta un array de banderas, no es una técnica nueva: es el nivel 33 aplicado.

Lo que solo se aprende produciendo

Los últimos nueve niveles son los que separan saber WebGPU de poder publicar algo hecho con WebGPU.

Nivel Qué fija
38 Trazado de rayos por software: generación de rayos, intersecciones, la BVH, su recorrido sin pila y el path tracing progresivo
39 Arquitecturas de render: el coste cuadrático del forward, el G-buffer, los precios del deferred, el clustered y el árbol de decisión
40 Renderizado dirigido por GPU: el coste de la CPU, el frustum en compute, la oclusión con la jerarquía de profundidad, la compactación y el buffer indirecto
41 Precisión: cómo se distribuyen los floats, GPU frente a CPU, las escalas grandes, las coordenadas relativas a cámara y depurar un NaN
42 Medir: las timestamp queries, el perfil por pass, las occlusion queries, los dos relojes y cómputo o memoria
43 Optimizar: el coste real de la memoria, la coalescencia, la reutilización, la ocupación y el ratio aritmético-memoria
44 Depurar: los error scopes, la pérdida de dispositivo, las etiquetas, qué comprueba la validación y las herramientas externas
45 Portabilidad: los límites, las features, la degradación, el soporte real y qué asumir
46 La síntesis: la arquitectura de un motor, el mapa de decisiones, este mapa, los errores y el futuro

Y esta es la tabla que de verdad vas a usar dentro de seis meses: el síntoma y el sitio al que volver.

Síntoma Región a la que volver
Los datos del uniform llegan desplazados o con basura Alineación de WGSL, nivel 19
Un objeto no aparece y no hay error Validación y etiquetas, nivel 44
Todo se ve pero el fotograma va a 20 por segundo Medir primero, nivel 42; optimizar después, nivel 43
Franjas que parpadean al mover la cámara Profundidad, nivel 25; y si es lejos del origen, nivel 41
La geometría tiembla a mucha distancia del origen Escalas grandes, nivel 41
Un buffer entero se pone en negro y ya no vuelve Propagación de NaN, nivel 41
El navegador dice que no hay adaptador Portabilidad, nivel 45
La CPU está al cien por cien y la GPU ociosa Coste por objeto, nivel 40; bundles, nivel 30
El resultado de un compute cambia entre ejecuciones Carreras y barreras, nivel 32
Va bien en tu máquina y mal en un portátil Límites y ancho de banda, niveles 45 y 43
La mitad de este track no es WebGPU, y esa mitad es la que no caduca

Merece la pena separar, ahora que están todos los niveles a la vista, qué has aprendido de WebGPU y qué has aprendido de gráficos. Lo específico de la API es sorprendentemente poco: los descriptores, los bind groups, los error scopes, los nombres de las features, el modelo de encoder y cola. Eso son quizá diez de los cuarenta y siete niveles, y es lo único que caduca; el día que trabajes con Vulkan, con Metal o con lo que venga después, tendrás que reaprenderlo, y te costará dos semanas porque los conceptos son los mismos con otros nombres. Todo lo demás es transferible sin cambiar una coma: la distribución de los floats es IEEE 754 y no WebGPU; la BVH y Möller-Trumbore tienen cuarenta años; el clustered lighting se inventó para consolas; la coalescencia, la ocupación y el modelo roofline son de arquitectura de computadores; las coordenadas relativas a cámara se usan en simuladores desde los años noventa. Eso tiene una consecuencia práctica que conviene tener presente al decidir en qué profundizar a partir de aquí: el rendimiento marginal de estudiar más API es muy bajo y el de estudiar más gráficos es muy alto. Nadie ha construido nunca algo memorable por conocer al dedillo el descriptor de createRenderPipeline. Y hay un segundo corolario, más sutil: como la parte transferible es la mayoría, la mejor forma de aprender la siguiente API gráfica que aparezca no será leer su documentación, sino escribir en ella algo que ya sabes hacer. La primera vez cuesta cuarenta y siete niveles; la segunda, un fin de semana.

⚔️ Reconstruye el mapa sin mirarlo
  1. Escribe de memoria las cuatro regiones del track y qué separa a cada una de la siguiente.
  2. Toma las cinco ideas transversales y busca, para cada una, tres niveles muy separados donde aparezca.
  3. Coge los tres últimos bugs gráficos que hayas tenido y clasifícalos con la tabla de síntomas. Comprueba si el sitio al que fuiste a mirar era el correcto.
  4. Haz tu propia lista de qué parte de lo aprendido es de WebGPU y qué parte es de gráficos. Ordénala por cuánto crees que te va a durar.