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.
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.
- 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.
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 |
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.
- Escribe de memoria las cuatro regiones del track y qué separa a cada una de la siguiente.
- Toma las cinco ideas transversales y busca, para cada una, tres niveles muy separados donde aparezca.
- 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.
- 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.