Novedades de WebGPU (Chrome 133)

François Beaufort
François Beaufort

Fecha de publicación: 29 de enero de 2025

Formatos de vértices adicionales de unorm8x4-bgra y de 1 componente

Se agregaron el formato de vértice "unorm8x4-bgra" y los siguientes formatos de vértice de 1 componente: "uint8", "sint8", "unorm8", "snorm8", "uint16", "sint16", "unorm16", "snorm16" y "float16". El formato de vértices "unorm8x4-bgra" facilita un poco la carga de colores de vértices codificados en BGRA y, al mismo tiempo, mantiene el mismo sombreador. Además, el formato de vértices de 1 componente te permite solicitar solo los datos necesarios cuando antes se requería al menos el doble para los tipos de datos de 8 y 16 bits. Consulta la entrada de chromestatus y el problema 376924407.

Permite que se soliciten límites desconocidos con un valor indefinido

Para que la API de WebGPU sea menos frágil a medida que evoluciona, ahora puedes solicitar límites desconocidos con el valor undefined cuando solicites un dispositivo de GPU. Esto es útil en el siguiente código de la aplicación, por ejemplo, donde adapter.limits.someLimit puede ser undefined si someLimit ya no existe. Consulta la solicitud de extracción de especificaciones 4781.

const adapter = await navigator.gpu.requestAdapter();

const device = await adapter.requestDevice({
  requiredLimits: { someLimit: adapter.limits.someLimit }, // someLimit can be undefined
});

Cambios en las reglas de alineación de WGSL

Ya no es posible proporcionar un valor de alineación demasiado pequeño para un miembro de una struct, ya que ahora se requiere que @align(n) divida RequiredAlignOf para todas las structs. Este cambio drástico simplifica el uso del lenguaje WGSL y lo hace más compatible con Firefox y Safari. Puedes encontrar código de muestra que muestra las diferencias entre los compiladores Tint, Naga y WebKit en la PR de especificaciones.

Ganancias de rendimiento de WGSL con descarte

Debido a una disminución significativa del rendimiento observada cuando se renderiza un efecto complejo de reflexiones en el espacio de la pantalla (SSR), la implementación de la sentencia de descarte usa la semántica proporcionada por la plataforma para degradar a una invocación de ayuda cuando está disponible. Esto mejora el rendimiento de los sombreadores que usan descarte. Consulta el problema 372714384.

Usa displaySize de VideoFrame para texturas externas

Las dimensiones displayWidth y displayHeight deben usarse como el tamaño aparente de GPUExternalTexture cuando se importa un VideoFrame según las especificaciones de WebGPU. Sin embargo, el tamaño visible se usó de forma incorrecta, lo que causaba problemas cuando se intentaba usar textureLoad() en un GPUExternalTexture. Ya se corrigió ese error. Consulta el problema 377574981.

Controla las imágenes con orientaciones que no son predeterminadas con copyExternalImageToTexture

El método copyExternalImageToTexture() GPUQueue se usa para copiar el contenido de una imagen o un lienzo en una textura. Ahora controla correctamente las imágenes con orientaciones no predeterminadas. Esto no era así antes, cuando la fuente era un ImageBitmap con imageOrientation "from-image" o una imagen con una orientación no predeterminada. Consulta el problema 384858956.

Mejora la experiencia de los desarrolladores

Puede ser sorprendente cuando adapter.limits muestra valores altos, pero no te das cuenta de que debes solicitar explícitamente un límite más alto cuando solicitas un dispositivo de GPU. De lo contrario, es posible que se alcancen límites de forma inesperada más adelante.

Para ayudarte, los mensajes de error se expandieron con sugerencias que te indican que solicites explícitamente un límite más alto cuando no se especifique un límite en requiredLimits cuando llames a requestDevice(). Consulta el problema 42240683.

En el siguiente ejemplo, se muestra un mensaje de error mejorado registrado en la consola de DevTools cuando se crea un búfer de GPU con un tamaño que supera el límite de tamaño máximo de búfer predeterminado del dispositivo.

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

// Create a GPU buffer with a size exceeding the default max buffer size device limit.
const size = device.limits.maxBufferSize + 1;
const buffer = device.createBuffer({ size, usage: GPUBufferUsage.MAP_READ });

device.queue.submit([]);
⚠️ Buffer size (268435457) exceeds the max buffer size limit (268435456). This adapter supports a higher maxBufferSize of 4294967296, which can be specified in requiredLimits when calling requestDevice(). Limits differ by hardware, so always check the adapter limits prior to requesting a higher limit.
- While calling [Device].CreateBuffer([BufferDescriptor]).

Habilita el modo de compatibilidad con featureLevel

Ahora es posible solicitar un adaptador de GPU en el modo de compatibilidad experimental configurando la opción estandarizada featureLevel en "compatibility". Las cadenas "core" (predeterminada) y "compatibility" son los únicos valores permitidos. Consulta el siguiente ejemplo y la PR de especificación 4897.

// Request a GPU adapter in compatibility mode
const adapter = await navigator.gpu.requestAdapter({ featureLevel: "compatibility" });

if (adapter?.featureLevel === "compatibility") {
  // Any devices created from this adapter will support only compatibility mode.
}

La opción featureLevel reemplaza la opción compatibilityMode no estandarizada, mientras que el atributo featureLevel no estandarizado reemplaza el atributo isCompatibilityMode.

Como aún está en etapa experimental, por ahora debes ejecutar Chrome con la marca "Compatibilidad no segura con WebGPU" en chrome://flags/#enable-unsafe-webgpu. Consulta webgpureport.org para jugar con él.

Limpieza de funciones de subgrupos experimentales

Se quitaron las funciones experimentales de subgrupos "chromium-experimental-subgroups" y "chromium-experimental-subgroup-uniform-control-flow" que quedaron obsoletas. Consulta el problema 377868468.

La función experimental "subgroups" es todo lo que necesitas ahora cuando experimentas con subgrupos. La función experimental "subgroups-f16" dejó de estar disponible y se quitará pronto. Puedes usar valores f16 con subgrupos cuando tu aplicación solicite funciones "shader-f16" y "subgroups". Consulta el problema 380244620.

Se da de baja el límite de maxInterStageShaderComponents

El límite de maxInterStageShaderComponents dejó de estar disponible debido a una combinación de factores:

  • Redundancia con maxInterStageShaderVariables: Este límite ya tiene un propósito similar, que es controlar la cantidad de datos que se pasan entre las etapas del sombreador.
  • Discrepancias menores: Si bien existen ligeras diferencias en la forma en que se calculan los dos límites, estas son menores y se pueden administrar de manera eficaz dentro del límite de maxInterStageShaderVariables.
  • Simplificación: Quitar maxInterStageShaderComponents optimiza la interfaz del sombreador y reduce la complejidad para los desarrolladores. En lugar de administrar dos límites separados con diferencias sutiles, pueden enfocarse en el maxInterStageShaderVariables más apropiado y con un nombre más adecuado.

El objetivo es quitarlo por completo en Chrome 135. Consulta el intento de dar de baja y el problema 364338810.

Actualizaciones de Dawn

wgpu::Device::GetAdapterInfo(adapterInfo) te permite obtener información del adaptador directamente desde un wgpu::Device. Consulta el problema 376600838.

Se cambió el nombre de la estructura WGPUProgrammableStageDescriptor a WGPUComputeState para que el estado de procesamiento sea coherente con los estados de vértices y fragmentos. Consulta el problema 379059434.

Se quitó el valor de enum wgpu::VertexStepMode::VertexBufferNotUsed. Un diseño de búfer de vértices que no se usa ahora se puede expresar con {.stepMode=wgpu::VertexStepMode::Undefined, .attributeCount=0}. Consulta el problema 383147017.

Esto solo abarca algunos de los aspectos más destacados. Consulta la lista exhaustiva de confirmaciones.

Novedades de WebGPU

Una lista de todo lo que se analizó en la serie Novedades de WebGPU.

Chrome 133

Chrome 132

Chrome 131

Chrome 130

Chrome 129

Chrome 128

Chrome 127

Chrome 126

Chrome 125

Chrome 124

Chrome 123

Chrome 122

Chrome 121

Chrome 120

Chrome 119

Chrome 118

Chrome 117

Chrome 116

Chrome 115

Chrome 114

Chrome 113