Novedades de WebGPU (Chrome 133)

François Beaufort
François Beaufort

Publicado el 29 de enero de 2025

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

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értice "unorm8x4-bgra" facilita un poco más la carga de colores de vértice codificados en BGRA y, al mismo tiempo, mantiene el mismo sombreador. Además, el formato de vértice de 1 componente te permite solicitar solo los datos necesarios, mientras que 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 solicitas un dispositivo de GPU. Esto es útil en el siguiente código de la aplicación, por ejemplo, en el que 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 struct, ya que ahora se requiere que @align(n) divida RequiredAlignOf para todos los structs. Este cambio radical 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 de Tint, Naga y WebKit en la PR de especificaciones.

Aumento del rendimiento de WGSL con descarte

Debido a una disminución significativa del rendimiento que se observó al renderizar un efecto complejo de reflejos en el espacio de la pantalla (SSR), la implementación de la instrucción 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 se deben usar como el tamaño aparente de GPUExternalTexture cuando se importa un VideoFrame según la especificación de WebGPU. Sin embargo, el tamaño visible se usó de forma incorrecta, lo que causó problemas cuando se intentó usar textureLoad() en un GPUExternalTexture. Ya se corrigió ese error. Consulta el problema 377574981.

Cómo controlar imágenes con orientaciones no 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 sucedía 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 alcances los límites de forma inesperada más adelante.

Para ayudarte, los mensajes de error se ampliaron con sugerencias que te indican que solicites explícitamente un límite más alto cuando no se especificó ningún límite en requiredLimits al llamar a requestDevice(). Consulta el problema 42240683.

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

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 es experimental, por el momento, debes ejecutar Chrome con la marca "Unsafe WebGPU Support" en chrome://flags/#enable-unsafe-webgpu. Visita webgpureport.org para probarlo.

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 pronto se quitará. Puedes usar valores de f16 con subgrupos cuando tu aplicación solicite las funciones "shader-f16" y "subgroups". Consulta el problema 380244620.

Se dio de baja el límite maxInterStageShaderComponents

El límite de maxInterStageShaderComponents quedó obsoleto debido a una combinación de factores:

  • Redundancia con maxInterStageShaderVariables: Este límite ya cumple un propósito similar, ya que controla la cantidad de datos que se pasan entre las etapas del sombreador.
  • Discrepancias menores: Si bien existen pequeñas diferencias en la forma en que se calculan los dos límites, estas diferencias 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, que tiene un nombre más adecuado y es más integral.

El objetivo es quitarlo por completo en Chrome 135. Consulta la intención 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 struct WGPUProgrammableStageDescriptor a WGPUComputeState para que el estado de procesamiento sea coherente con los estados de vértice y fragmento. Consulta el problema 379059434.

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

Esto solo abarca algunos de los aspectos destacados clave. Consulta la lista exhaustiva de confirmaciones.

Novedades de WebGPU

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

Chrome 140

Chrome 139

Chrome 138

Chrome 137

Chrome 136

Chrome 135

Chrome 134

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