Wat is er nieuw in WebGPU (Chrome 121)

François Beaufort
François Beaufort

WebGPU-ondersteuning op Android

Het Chrome-team is verheugd aan te kondigen dat WebGPU nu standaard is ingeschakeld in Chrome 121 op apparaten met Android 12 en hoger die worden aangedreven door Qualcomm- en ARM-GPU's.

De ondersteuning zal geleidelijk worden uitgebreid naar een breder scala aan Android-apparaten, waaronder apparaten die binnenkort op Android 11 draaien. Deze uitbreiding is afhankelijk van verdere tests en optimalisatie om een ​​naadloze ervaring op een breder scala aan hardwareconfiguraties te garanderen. Zie issue chromium:1497815 .

Screenshot van een WebGPU-voorbeeld dat draait in Chrome voor Android.
WebGPU-voorbeeld dat draait op Chrome voor Android.

Gebruik DXC in plaats van FXC voor shadercompilatie op Windows.

Chrome maakt nu gebruik van de kracht van DXC (DirectX Compiler) om shaders te compileren op Windows D3D12-machines met SM6+-grafische hardware. Voorheen vertrouwde WebGPU op FXC (FX Compiler) voor shadercompilatie op Windows. Hoewel functioneel, miste FXC de functionaliteit en prestatieoptimalisaties die DXC wel bood.

Uit eerste tests blijkt een gemiddelde toename van 20% in de compilatiesnelheid van compute shaders bij gebruik van DXC in vergelijking met FXC.

Tijdstempelquery's in de reken- en weergavefasen

Met behulp van tijdstempelquery's kunnen WebGPU-applicaties nauwkeurig (tot op de nanoseconde) meten hoeveel tijd hun GPU-opdrachten nodig hebben om reken- en renderingpasses uit te voeren. Ze worden veelvuldig gebruikt om inzicht te krijgen in de prestaties en het gedrag van GPU-workloads.

Wanneer de functie "timestamp-query" beschikbaar is in een GPUAdapter , kunt u nu de volgende dingen doen:

  • Vraag een GPUDevice aan met de functie "timestamp-query" .
  • Maak een GPUQuerySet van het type "timestamp" .
  • Gebruik GPUComputePassDescriptor.timestampWrites en GPURenderPassDescriptor.timestampWrites om te definiëren waar tijdstempelwaarden in GPUQuerySet moeten worden geschreven.
  • Zet tijdstempelwaarden om in een GPUBuffer met behulp van resolveQuerySet() .
  • Lees de tijdstempelwaarden terug door de resultaten van de GPUBuffer naar de CPU te kopiëren.
  • Decodeer tijdstempelwaarden als een BigInt64Array .

Zie het volgende voorbeeld en geef het probleem op : dawn:1800 .

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("timestamp-query")) {
  throw new Error("Timestamp query feature is not available");
}
// Explicitly request timestamp query feature.
const device = await adapter.requestDevice({
  requiredFeatures: ["timestamp-query"],
});
const commandEncoder = device.createCommandEncoder();

// Create a GPUQuerySet which holds 2 timestamp query results: one for the
// beginning and one for the end of compute pass execution.
const querySet = device.createQuerySet({ type: "timestamp", count: 2 });
const timestampWrites = {
  querySet,
  beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins.
  endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends.
};
const passEncoder = commandEncoder.beginComputePass({ timestampWrites });
// TODO: Set pipeline, bind group, and dispatch work to be performed.
passEncoder.end();

// Resolve timestamps in nanoseconds as a 64-bit unsigned integer into a GPUBuffer.
const size = 2 * BigInt64Array.BYTES_PER_ELEMENT;
const resolveBuffer = device.createBuffer({
  size,
  usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
});
commandEncoder.resolveQuerySet(querySet, 0, 2, resolveBuffer, 0);

// Read GPUBuffer memory.
const resultBuffer = device.createBuffer({
  size,
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});
commandEncoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size);

// Submit commands to the GPU.
device.queue.submit([commandEncoder.finish()]);

// Log compute pass duration in nanoseconds.
await resultBuffer.mapAsync(GPUMapMode.READ);
const times = new BigInt64Array(resultBuffer.getMappedRange());
console.log(`Compute pass duration: ${Number(times[1] - times[0])}ns`);
resultBuffer.unmap();

Vanwege de bezorgdheid over timing-aanvallen worden tijdstempelquery's gekwantiseerd met een resolutie van 100 microseconden. Dit biedt een goed compromis tussen precisie en beveiliging. In de Chrome-browser kunt u tijdstempelkwantisering uitschakelen door de vlag "WebGPU Developer Features" in te schakelen via chrome://flags/#enable-webgpu-developer-features tijdens de ontwikkeling van uw app. Zie Tijdstempelquerykwantisering voor meer informatie.

Omdat GPU's de tijdstempelteller soms kunnen resetten, wat kan leiden tot onverwachte waarden zoals negatieve verschillen tussen tijdstempels, raad ik je aan de wijzigingen in de git diff te bekijken die ondersteuning voor tijdstempelquery's toevoegen aan het volgende Compute Boids -voorbeeld.

Screenshot van een Compute Boids-voorbeeld met een tijdstempelquery.
Bereken Boids-voorbeeld met tijdstempelquery.

Standaard toegangspunten tot shadermodules

Om de ontwikkelaarservaring te verbeteren, kunt u nu het entryPoint van uw shadermodule weglaten bij het maken van een compute- of renderpipeline. Als er geen uniek entrypoint voor de shaderfase in de shadercode wordt gevonden, wordt een GPUValidationError geactiveerd. Zie het volgende voorbeeld en issue dawn:2254 .

const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
const module = myDevice.createShaderModule({ code });
const format = navigator.gpu.getPreferredCanvasFormat();
const pipeline = await myDevice.createRenderPipelineAsync({
  layout: "auto",
  vertex: { module, entryPoint: "vertexMain" },
  fragment: { module, entryPoint: "fragmentMain", targets: [{ format }] },
  vertex: { module },
  fragment: { module, targets: [{ format }] },
});

Ondersteuning voor display-p3 als GPUExternalTexture-kleurruimte

Je kunt nu de kleurruimte "display-p3" instellen bij het importeren van een GPUExternalTexture uit HDR-video's met importExternalTexture() . Bekijk hoe WebGPU kleurruimtes afhandelt. Zie het volgende voorbeeld en issue chromium:1330250 .

// Create texture from HDR video.
const video = document.querySelector("video");
const texture = myDevice.importExternalTexture({
  source: video,
  colorSpace: "display-p3",
});

Informatie over geheugenhops

Om u te helpen anticiperen op geheugenbeperkingen bij het toewijzen van grote hoeveelheden geheugen tijdens de ontwikkeling van uw app, geeft requestAdapterInfo() nu informatie memoryHeaps weer, zoals de grootte en het type van de geheugenheaps die beschikbaar zijn op de adapter. Deze experimentele functie is alleen toegankelijk wanneer de vlag "WebGPU Developer Features" op chrome://flags/#enable-webgpu-developer-features is ingeschakeld. Zie het volgende voorbeeld en issue dawn:2249 .

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

for (const { size, properties } of adapterInfo.memoryHeaps) {
  console.log(size); // memory heap size in bytes
  if (properties & GPUHeapProperty.DEVICE_LOCAL)  { /* ... */ }
  if (properties & GPUHeapProperty.HOST_VISIBLE)  { /* ... */ }
  if (properties & GPUHeapProperty.HOST_COHERENT) { /* ... */ }
  if (properties & GPUHeapProperty.HOST_UNCACHED) { /* ... */ }
  if (properties & GPUHeapProperty.HOST_CACHED)   { /* ... */ }
}
Screenshot van https://webgpureport.org met geheugenheaps in de adapterinfo.
Adapterinformatie over geheugenheaps wordt weergegeven op https://webgpureport.org .

Dawn-updates

De methoden HasWGSLLanguageFeature en EnumerateWGSLLanguageFeatures op wgpu::Instance zijn toegevoegd om WGSL-taalfeatures te ondersteunen. Zie issue dawn:2260 .

De niet-standaard wgpu::Feature::BufferMapExtendedUsages stelt u in staat een GPU-buffer te creëren met wgpu::BufferUsage::MapRead of wgpu::BufferUsage::MapWrite en elke andere wgpu::BufferUsage . Zie het volgende voorbeeld en issue dawn:2204 .

wgpu::BufferDescriptor descriptor = {
  .size = 128,
  .usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::Uniform
};
wgpu::Buffer uniformBuffer = device.CreateBuffer(&descriptor);

uniformBuffer.MapAsync(wgpu::MapMode::Write, 0, 128,
   [](WGPUBufferMapAsyncStatus status, void* userdata)
   {
      wgpu::Buffer* buffer = static_cast<wgpu::Buffer*>(userdata);
      memcpy(buffer->GetMappedRange(), data, sizeof(data));
   },
   &uniformBuffer);

De volgende functies zijn gedocumenteerd: ANGLE Texture Sharing , D3D11 multithread-beveiliging , Impliciete apparaatsynchronisatie , Norm16-textuurformaten , Tijdstempelquery binnen passes , Lokale pixelopslag , Shaderfuncties en Multi-planaire formaten .

Het Chrome-team heeft een officiële GitHub-repository voor Dawn aangemaakt.

Dit is slechts een greep uit de belangrijkste hoogtepunten. Bekijk de volledige lijst met commits .

Wat is er nieuw in WebGPU?

Een lijst van alles wat in de serie ' Wat is nieuw in WebGPU' aan bod is gekomen.

Chrome 151-152

Chrome 149-150

Chrome 147-148

Chrome 146

Chrome 145

Chrome 144

Chrome 143

Chrome 142

Chrome 141

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

,

François Beaufort
François Beaufort

WebGPU-ondersteuning op Android

Het Chrome-team is verheugd aan te kondigen dat WebGPU nu standaard is ingeschakeld in Chrome 121 op apparaten met Android 12 en hoger die worden aangedreven door Qualcomm- en ARM-GPU's.

De ondersteuning zal geleidelijk worden uitgebreid naar een breder scala aan Android-apparaten, waaronder apparaten die binnenkort op Android 11 draaien. Deze uitbreiding is afhankelijk van verdere tests en optimalisatie om een ​​naadloze ervaring op een breder scala aan hardwareconfiguraties te garanderen. Zie issue chromium:1497815 .

Screenshot van een WebGPU-voorbeeld dat draait in Chrome voor Android.
WebGPU-voorbeeld dat draait op Chrome voor Android.

Gebruik DXC in plaats van FXC voor shadercompilatie op Windows.

Chrome maakt nu gebruik van de kracht van DXC (DirectX Compiler) om shaders te compileren op Windows D3D12-machines met SM6+-grafische hardware. Voorheen vertrouwde WebGPU op FXC (FX Compiler) voor shadercompilatie op Windows. Hoewel functioneel, miste FXC de functionaliteit en prestatieoptimalisaties die DXC wel bood.

Uit eerste tests blijkt een gemiddelde toename van 20% in de compilatiesnelheid van compute shaders bij gebruik van DXC in vergelijking met FXC.

Tijdstempelquery's in de reken- en weergavefasen

Met behulp van tijdstempelquery's kunnen WebGPU-applicaties nauwkeurig (tot op de nanoseconde) meten hoeveel tijd hun GPU-opdrachten nodig hebben om reken- en renderingpasses uit te voeren. Ze worden veelvuldig gebruikt om inzicht te krijgen in de prestaties en het gedrag van GPU-workloads.

Wanneer de functie "timestamp-query" beschikbaar is in een GPUAdapter , kunt u nu de volgende dingen doen:

  • Vraag een GPUDevice aan met de functie "timestamp-query" .
  • Maak een GPUQuerySet van het type "timestamp" .
  • Gebruik GPUComputePassDescriptor.timestampWrites en GPURenderPassDescriptor.timestampWrites om te definiëren waar tijdstempelwaarden in GPUQuerySet moeten worden geschreven.
  • Zet tijdstempelwaarden om in een GPUBuffer met behulp van resolveQuerySet() .
  • Lees de tijdstempelwaarden terug door de resultaten van de GPUBuffer naar de CPU te kopiëren.
  • Decodeer tijdstempelwaarden als een BigInt64Array .

Zie het volgende voorbeeld en geef het probleem op : dawn:1800 .

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("timestamp-query")) {
  throw new Error("Timestamp query feature is not available");
}
// Explicitly request timestamp query feature.
const device = await adapter.requestDevice({
  requiredFeatures: ["timestamp-query"],
});
const commandEncoder = device.createCommandEncoder();

// Create a GPUQuerySet which holds 2 timestamp query results: one for the
// beginning and one for the end of compute pass execution.
const querySet = device.createQuerySet({ type: "timestamp", count: 2 });
const timestampWrites = {
  querySet,
  beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins.
  endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends.
};
const passEncoder = commandEncoder.beginComputePass({ timestampWrites });
// TODO: Set pipeline, bind group, and dispatch work to be performed.
passEncoder.end();

// Resolve timestamps in nanoseconds as a 64-bit unsigned integer into a GPUBuffer.
const size = 2 * BigInt64Array.BYTES_PER_ELEMENT;
const resolveBuffer = device.createBuffer({
  size,
  usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
});
commandEncoder.resolveQuerySet(querySet, 0, 2, resolveBuffer, 0);

// Read GPUBuffer memory.
const resultBuffer = device.createBuffer({
  size,
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});
commandEncoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size);

// Submit commands to the GPU.
device.queue.submit([commandEncoder.finish()]);

// Log compute pass duration in nanoseconds.
await resultBuffer.mapAsync(GPUMapMode.READ);
const times = new BigInt64Array(resultBuffer.getMappedRange());
console.log(`Compute pass duration: ${Number(times[1] - times[0])}ns`);
resultBuffer.unmap();

Vanwege de bezorgdheid over timing-aanvallen worden tijdstempelquery's gekwantiseerd met een resolutie van 100 microseconden. Dit biedt een goed compromis tussen precisie en beveiliging. In de Chrome-browser kunt u tijdstempelkwantisering uitschakelen door de vlag "WebGPU Developer Features" in te schakelen via chrome://flags/#enable-webgpu-developer-features tijdens de ontwikkeling van uw app. Zie Tijdstempelquerykwantisering voor meer informatie.

Omdat GPU's de tijdstempelteller soms kunnen resetten, wat kan leiden tot onverwachte waarden zoals negatieve verschillen tussen tijdstempels, raad ik je aan de wijzigingen in de git diff te bekijken die ondersteuning voor tijdstempelquery's toevoegen aan het volgende Compute Boids -voorbeeld.

Screenshot van een Compute Boids-voorbeeld met een tijdstempelquery.
Bereken Boids-voorbeeld met tijdstempelquery.

Standaard toegangspunten tot shadermodules

Om de ontwikkelaarservaring te verbeteren, kunt u nu het entryPoint van uw shadermodule weglaten bij het maken van een compute- of renderpipeline. Als er geen uniek entrypoint voor de shaderfase in de shadercode wordt gevonden, wordt een GPUValidationError geactiveerd. Zie het volgende voorbeeld en issue dawn:2254 .

const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
const module = myDevice.createShaderModule({ code });
const format = navigator.gpu.getPreferredCanvasFormat();
const pipeline = await myDevice.createRenderPipelineAsync({
  layout: "auto",
  vertex: { module, entryPoint: "vertexMain" },
  fragment: { module, entryPoint: "fragmentMain", targets: [{ format }] },
  vertex: { module },
  fragment: { module, targets: [{ format }] },
});

Ondersteuning voor display-p3 als GPUExternalTexture-kleurruimte

Je kunt nu de kleurruimte "display-p3" instellen bij het importeren van een GPUExternalTexture uit HDR-video's met importExternalTexture() . Bekijk hoe WebGPU kleurruimtes afhandelt. Zie het volgende voorbeeld en issue chromium:1330250 .

// Create texture from HDR video.
const video = document.querySelector("video");
const texture = myDevice.importExternalTexture({
  source: video,
  colorSpace: "display-p3",
});

Informatie over geheugenhops

Om u te helpen anticiperen op geheugenbeperkingen bij het toewijzen van grote hoeveelheden geheugen tijdens de ontwikkeling van uw app, geeft requestAdapterInfo() nu informatie memoryHeaps weer, zoals de grootte en het type van de geheugenheaps die beschikbaar zijn op de adapter. Deze experimentele functie is alleen toegankelijk wanneer de vlag "WebGPU Developer Features" op chrome://flags/#enable-webgpu-developer-features is ingeschakeld. Zie het volgende voorbeeld en issue dawn:2249 .

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

for (const { size, properties } of adapterInfo.memoryHeaps) {
  console.log(size); // memory heap size in bytes
  if (properties & GPUHeapProperty.DEVICE_LOCAL)  { /* ... */ }
  if (properties & GPUHeapProperty.HOST_VISIBLE)  { /* ... */ }
  if (properties & GPUHeapProperty.HOST_COHERENT) { /* ... */ }
  if (properties & GPUHeapProperty.HOST_UNCACHED) { /* ... */ }
  if (properties & GPUHeapProperty.HOST_CACHED)   { /* ... */ }
}
Screenshot van https://webgpureport.org met geheugenheaps in de adapterinfo.
Adapterinformatie over geheugenheaps wordt weergegeven op https://webgpureport.org .

Dawn-updates

De methoden HasWGSLLanguageFeature en EnumerateWGSLLanguageFeatures op wgpu::Instance zijn toegevoegd om WGSL-taalfeatures te ondersteunen. Zie issue dawn:2260 .

De niet-standaard wgpu::Feature::BufferMapExtendedUsages stelt u in staat een GPU-buffer te creëren met wgpu::BufferUsage::MapRead of wgpu::BufferUsage::MapWrite en elke andere wgpu::BufferUsage . Zie het volgende voorbeeld en issue dawn:2204 .

wgpu::BufferDescriptor descriptor = {
  .size = 128,
  .usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::Uniform
};
wgpu::Buffer uniformBuffer = device.CreateBuffer(&descriptor);

uniformBuffer.MapAsync(wgpu::MapMode::Write, 0, 128,
   [](WGPUBufferMapAsyncStatus status, void* userdata)
   {
      wgpu::Buffer* buffer = static_cast<wgpu::Buffer*>(userdata);
      memcpy(buffer->GetMappedRange(), data, sizeof(data));
   },
   &uniformBuffer);

De volgende functies zijn gedocumenteerd: ANGLE Texture Sharing , D3D11 multithread-beveiliging , Impliciete apparaatsynchronisatie , Norm16-textuurformaten , Tijdstempelquery binnen passes , Lokale pixelopslag , Shaderfuncties en Multi-planaire formaten .

Het Chrome-team heeft een officiële GitHub-repository voor Dawn aangemaakt.

Dit is slechts een greep uit de belangrijkste hoogtepunten. Bekijk de volledige lijst met commits .

Wat is er nieuw in WebGPU?

Een lijst van alles wat in de serie ' Wat is nieuw in WebGPU' aan bod is gekomen.

Chrome 151-152

Chrome 149-150

Chrome 147-148

Chrome 146

Chrome 145

Chrome 144

Chrome 143

Chrome 142

Chrome 141

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

,

François Beaufort
François Beaufort

WebGPU-ondersteuning op Android

Het Chrome-team is verheugd aan te kondigen dat WebGPU nu standaard is ingeschakeld in Chrome 121 op apparaten met Android 12 en hoger die worden aangedreven door Qualcomm- en ARM-GPU's.

De ondersteuning zal geleidelijk worden uitgebreid naar een breder scala aan Android-apparaten, waaronder apparaten die binnenkort op Android 11 draaien. Deze uitbreiding is afhankelijk van verdere tests en optimalisatie om een ​​naadloze ervaring op een breder scala aan hardwareconfiguraties te garanderen. Zie issue chromium:1497815 .

Screenshot van een WebGPU-voorbeeld dat draait in Chrome voor Android.
WebGPU-voorbeeld dat draait op Chrome voor Android.

Gebruik DXC in plaats van FXC voor shadercompilatie op Windows.

Chrome maakt nu gebruik van de kracht van DXC (DirectX Compiler) om shaders te compileren op Windows D3D12-machines met SM6+-grafische hardware. Voorheen vertrouwde WebGPU op FXC (FX Compiler) voor shadercompilatie op Windows. Hoewel functioneel, miste FXC de functionaliteit en prestatieoptimalisaties die DXC wel bood.

Uit eerste tests blijkt een gemiddelde toename van 20% in de compilatiesnelheid van compute shaders bij gebruik van DXC in vergelijking met FXC.

Tijdstempelquery's in de reken- en weergavefasen

Met behulp van tijdstempelquery's kunnen WebGPU-applicaties nauwkeurig (tot op de nanoseconde) meten hoeveel tijd hun GPU-opdrachten nodig hebben om reken- en renderingpasses uit te voeren. Ze worden veelvuldig gebruikt om inzicht te krijgen in de prestaties en het gedrag van GPU-workloads.

Wanneer de functie "timestamp-query" beschikbaar is in een GPUAdapter , kunt u nu de volgende dingen doen:

  • Vraag een GPUDevice aan met de functie "timestamp-query" .
  • Maak een GPUQuerySet van het type "timestamp" .
  • Gebruik GPUComputePassDescriptor.timestampWrites en GPURenderPassDescriptor.timestampWrites om te definiëren waar tijdstempelwaarden in GPUQuerySet moeten worden geschreven.
  • Zet tijdstempelwaarden om in een GPUBuffer met behulp van resolveQuerySet() .
  • Lees de tijdstempelwaarden terug door de resultaten van de GPUBuffer naar de CPU te kopiëren.
  • Decodeer tijdstempelwaarden als een BigInt64Array .

Zie het volgende voorbeeld en geef het probleem op : dawn:1800 .

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("timestamp-query")) {
  throw new Error("Timestamp query feature is not available");
}
// Explicitly request timestamp query feature.
const device = await adapter.requestDevice({
  requiredFeatures: ["timestamp-query"],
});
const commandEncoder = device.createCommandEncoder();

// Create a GPUQuerySet which holds 2 timestamp query results: one for the
// beginning and one for the end of compute pass execution.
const querySet = device.createQuerySet({ type: "timestamp", count: 2 });
const timestampWrites = {
  querySet,
  beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins.
  endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends.
};
const passEncoder = commandEncoder.beginComputePass({ timestampWrites });
// TODO: Set pipeline, bind group, and dispatch work to be performed.
passEncoder.end();

// Resolve timestamps in nanoseconds as a 64-bit unsigned integer into a GPUBuffer.
const size = 2 * BigInt64Array.BYTES_PER_ELEMENT;
const resolveBuffer = device.createBuffer({
  size,
  usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
});
commandEncoder.resolveQuerySet(querySet, 0, 2, resolveBuffer, 0);

// Read GPUBuffer memory.
const resultBuffer = device.createBuffer({
  size,
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});
commandEncoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size);

// Submit commands to the GPU.
device.queue.submit([commandEncoder.finish()]);

// Log compute pass duration in nanoseconds.
await resultBuffer.mapAsync(GPUMapMode.READ);
const times = new BigInt64Array(resultBuffer.getMappedRange());
console.log(`Compute pass duration: ${Number(times[1] - times[0])}ns`);
resultBuffer.unmap();

Vanwege de bezorgdheid over timing-aanvallen worden tijdstempelquery's gekwantiseerd met een resolutie van 100 microseconden. Dit biedt een goed compromis tussen precisie en beveiliging. In de Chrome-browser kunt u tijdstempelkwantisering uitschakelen door de vlag "WebGPU Developer Features" in te schakelen via chrome://flags/#enable-webgpu-developer-features tijdens de ontwikkeling van uw app. Zie Tijdstempelquerykwantisering voor meer informatie.

Omdat GPU's de tijdstempelteller soms kunnen resetten, wat kan leiden tot onverwachte waarden zoals negatieve verschillen tussen tijdstempels, raad ik je aan de wijzigingen in de git diff te bekijken die ondersteuning voor tijdstempelquery's toevoegen aan het volgende Compute Boids -voorbeeld.

Screenshot van een Compute Boids-voorbeeld met een tijdstempelquery.
Bereken Boids-voorbeeld met tijdstempelquery.

Standaard toegangspunten tot shadermodules

Om de ontwikkelaarservaring te verbeteren, kunt u nu het entryPoint van uw shadermodule weglaten bij het maken van een compute- of renderpipeline. Als er geen uniek entrypoint voor de shaderfase in de shadercode wordt gevonden, wordt een GPUValidationError geactiveerd. Zie het volgende voorbeeld en issue dawn:2254 .

const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
const module = myDevice.createShaderModule({ code });
const format = navigator.gpu.getPreferredCanvasFormat();
const pipeline = await myDevice.createRenderPipelineAsync({
  layout: "auto",
  vertex: { module, entryPoint: "vertexMain" },
  fragment: { module, entryPoint: "fragmentMain", targets: [{ format }] },
  vertex: { module },
  fragment: { module, targets: [{ format }] },
});

Ondersteuning voor display-p3 als GPUExternalTexture-kleurruimte

Je kunt nu de kleurruimte "display-p3" instellen bij het importeren van een GPUExternalTexture uit HDR-video's met importExternalTexture() . Bekijk hoe WebGPU kleurruimtes afhandelt. Zie het volgende voorbeeld en issue chromium:1330250 .

// Create texture from HDR video.
const video = document.querySelector("video");
const texture = myDevice.importExternalTexture({
  source: video,
  colorSpace: "display-p3",
});

Informatie over geheugenhops

Om u te helpen anticiperen op geheugenbeperkingen bij het toewijzen van grote hoeveelheden geheugen tijdens de ontwikkeling van uw app, geeft requestAdapterInfo() nu informatie memoryHeaps weer, zoals de grootte en het type van de geheugenheaps die beschikbaar zijn op de adapter. Deze experimentele functie is alleen toegankelijk wanneer de vlag "WebGPU Developer Features" op chrome://flags/#enable-webgpu-developer-features is ingeschakeld. Zie het volgende voorbeeld en issue dawn:2249 .

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

for (const { size, properties } of adapterInfo.memoryHeaps) {
  console.log(size); // memory heap size in bytes
  if (properties & GPUHeapProperty.DEVICE_LOCAL)  { /* ... */ }
  if (properties & GPUHeapProperty.HOST_VISIBLE)  { /* ... */ }
  if (properties & GPUHeapProperty.HOST_COHERENT) { /* ... */ }
  if (properties & GPUHeapProperty.HOST_UNCACHED) { /* ... */ }
  if (properties & GPUHeapProperty.HOST_CACHED)   { /* ... */ }
}
Screenshot van https://webgpureport.org met geheugenheaps in de adapterinfo.
Adapterinformatie over geheugenheaps wordt weergegeven op https://webgpureport.org .

Dawn-updates

De methoden HasWGSLLanguageFeature en EnumerateWGSLLanguageFeatures op wgpu::Instance zijn toegevoegd om WGSL-taalfeatures te ondersteunen. Zie issue dawn:2260 .

De niet-standaard wgpu::Feature::BufferMapExtendedUsages stelt u in staat een GPU-buffer te creëren met wgpu::BufferUsage::MapRead of wgpu::BufferUsage::MapWrite en elke andere wgpu::BufferUsage . Zie het volgende voorbeeld en issue dawn:2204 .

wgpu::BufferDescriptor descriptor = {
  .size = 128,
  .usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::Uniform
};
wgpu::Buffer uniformBuffer = device.CreateBuffer(&descriptor);

uniformBuffer.MapAsync(wgpu::MapMode::Write, 0, 128,
   [](WGPUBufferMapAsyncStatus status, void* userdata)
   {
      wgpu::Buffer* buffer = static_cast<wgpu::Buffer*>(userdata);
      memcpy(buffer->GetMappedRange(), data, sizeof(data));
   },
   &uniformBuffer);

De volgende functies zijn gedocumenteerd: ANGLE Texture Sharing , D3D11 multithread-beveiliging , Impliciete apparaatsynchronisatie , Norm16-textuurformaten , Tijdstempelquery binnen passes , Lokale pixelopslag , Shaderfuncties en Multi-planaire formaten .

Het Chrome-team heeft een officiële GitHub-repository voor Dawn aangemaakt.

Dit is slechts een greep uit de belangrijkste hoogtepunten. Bekijk de volledige lijst met commits .

Wat is er nieuw in WebGPU?

Een lijst van alles wat in de serie ' Wat is nieuw in WebGPU' aan bod is gekomen.

Chrome 151-152

Chrome 149-150

Chrome 147-148

Chrome 146

Chrome 145

Chrome 144

Chrome 143

Chrome 142

Chrome 141

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

,

François Beaufort
François Beaufort

Support WebGPU on Android

The Chrome team is excited to announce that WebGPU is now enabled by default in Chrome 121 on devices running Android 12 and greater powered by Qualcomm and ARM GPUs.

Support will gradually expand to encompass a wider range of Android devices, including those running on Android 11 in a near future. This expansion will be dependent on further testing and optimization to ensure a seamless experience across a broader range of hardware configurations. See issue chromium:1497815 .

Screenshot of WebGPU sample running on Chrome for Android.
WebGPU sample running on Chrome for Android.

Use DXC instead of FXC for shader compilation on Windows

Chrome now uses the power of DXC (DirectX Compiler) to compile shaders on Windows D3D12 machines equipped with SM6+ graphics hardware. Previously, WebGPU relied on FXC (FX Compiler) for shader compilation on Windows. While functional, FXC lacked the feature set and performance optimizations present in DXC.

Initial testing shows a 20% average increase in compute shader compilation speed when using DXC compared to FXC.

Timestamp queries in compute and render passes

Timestamp queries allow WebGPU applications to measure precisely (down to the nanosecond) how much time their GPU commands take to execute compute and render passes. They are heavily used to gain insights into the performance and behavior of GPU workloads.

When the "timestamp-query" feature is available in a GPUAdapter , you can now do the following things:

See the following example and issue dawn:1800 .

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("timestamp-query")) {
  throw new Error("Timestamp query feature is not available");
}
// Explicitly request timestamp query feature.
const device = await adapter.requestDevice({
  requiredFeatures: ["timestamp-query"],
});
const commandEncoder = device.createCommandEncoder();

// Create a GPUQuerySet which holds 2 timestamp query results: one for the
// beginning and one for the end of compute pass execution.
const querySet = device.createQuerySet({ type: "timestamp", count: 2 });
const timestampWrites = {
  querySet,
  beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins.
  endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends.
};
const passEncoder = commandEncoder.beginComputePass({ timestampWrites });
// TODO: Set pipeline, bind group, and dispatch work to be performed.
passEncoder.end();

// Resolve timestamps in nanoseconds as a 64-bit unsigned integer into a GPUBuffer.
const size = 2 * BigInt64Array.BYTES_PER_ELEMENT;
const resolveBuffer = device.createBuffer({
  size,
  usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
});
commandEncoder.resolveQuerySet(querySet, 0, 2, resolveBuffer, 0);

// Read GPUBuffer memory.
const resultBuffer = device.createBuffer({
  size,
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
});
commandEncoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size);

// Submit commands to the GPU.
device.queue.submit([commandEncoder.finish()]);

// Log compute pass duration in nanoseconds.
await resultBuffer.mapAsync(GPUMapMode.READ);
const times = new BigInt64Array(resultBuffer.getMappedRange());
console.log(`Compute pass duration: ${Number(times[1] - times[0])}ns`);
resultBuffer.unmap();

Due to timing attack concerns, timestamp queries are quantized with a resolution of 100 microseconds, which provides a good compromise between precision and security. In Chrome browser, you can disable timestamp quantization by enabling the "WebGPU Developer Features" flag at chrome://flags/#enable-webgpu-developer-features during the development of your app. See Timestamp queries quantization to learn more.

As GPUs may reset the timestamp counter occasionally, which can result in unexpected values such as negative deltas between timestamps, I recommend you check out the git diff changes that adds timestamp query support to the following Compute Boids sample.

Screenshot of Compute Boids sample featuring timestamp query.
Compute Boids sample featuring timestamp query.

Default entry points to shader modules

To improve the developer experience, you can now omit the entryPoint of your shader module when creating a compute or render pipeline. If no unique entry point for the shader stage is found in the shader code, a GPUValidationError will be triggered. See the following example and issue dawn:2254 .

const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
const module = myDevice.createShaderModule({ code });
const format = navigator.gpu.getPreferredCanvasFormat();
const pipeline = await myDevice.createRenderPipelineAsync({
  layout: "auto",
  vertex: { module, entryPoint: "vertexMain" },
  fragment: { module, entryPoint: "fragmentMain", targets: [{ format }] },
  vertex: { module },
  fragment: { module, targets: [{ format }] },
});

Support display-p3 as GPUExternalTexture color space

You can now set "display-p3" destination color space when importing a GPUExternalTexture from HDR videos with importExternalTexture() . Check out how WebGPU handles color spaces . See the following example and issue chromium:1330250 .

// Create texture from HDR video.
const video = document.querySelector("video");
const texture = myDevice.importExternalTexture({
  source: video,
  colorSpace: "display-p3",
});

Memory heaps info

To help you anticipate memory limitations when allocating large amounts during the development of your app, requestAdapterInfo() now exposes memoryHeaps information such as the size and type of memory heaps available on the adapter. This experimental feature is accessible only when the "WebGPU Developer Features" flag at chrome://flags/#enable-webgpu-developer-features is enabled. See the following example and issue dawn:2249 .

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

for (const { size, properties } of adapterInfo.memoryHeaps) {
  console.log(size); // memory heap size in bytes
  if (properties & GPUHeapProperty.DEVICE_LOCAL)  { /* ... */ }
  if (properties & GPUHeapProperty.HOST_VISIBLE)  { /* ... */ }
  if (properties & GPUHeapProperty.HOST_COHERENT) { /* ... */ }
  if (properties & GPUHeapProperty.HOST_UNCACHED) { /* ... */ }
  if (properties & GPUHeapProperty.HOST_CACHED)   { /* ... */ }
}
Screenshot of https://webgpureport.org featuring memory heaps in adapter info.
Adapter info memory heaps shown on https://webgpureport.org .

Dawn updates

The HasWGSLLanguageFeature and EnumerateWGSLLanguageFeatures methods on wgpu::Instance have been added to handle WGSL language features. See issue dawn:2260 .

The non-standard wgpu::Feature::BufferMapExtendedUsages feature lets you create a GPU buffer with wgpu::BufferUsage::MapRead or wgpu::BufferUsage::MapWrite and any other wgpu::BufferUsage . See the following example and issue dawn:2204 .

wgpu::BufferDescriptor descriptor = {
  .size = 128,
  .usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::Uniform
};
wgpu::Buffer uniformBuffer = device.CreateBuffer(&descriptor);

uniformBuffer.MapAsync(wgpu::MapMode::Write, 0, 128,
   [](WGPUBufferMapAsyncStatus status, void* userdata)
   {
      wgpu::Buffer* buffer = static_cast<wgpu::Buffer*>(userdata);
      memcpy(buffer->GetMappedRange(), data, sizeof(data));
   },
   &uniformBuffer);

The following features have been documented: ANGLE Texture Sharing , D3D11 multithread protected , Implicit Device Synchronization , Norm16 texture formats , Timestamp Query Inside Passes , Pixel Local Storage , Shader Features , and Multi Planar Formats .

The Chrome team has created an official GitHub repository for Dawn .

This covers only some of the key highlights. Check out the exhaustive list of commits .

What's New in WebGPU

A list of everything that has been covered in the What's New in WebGPU series.

Chrome 151-152

Chrome 149-150

Chrome 147-148

Chrome 146

Chrome 145

Chrome 144

Chrome 143

Chrome 142

Chrome 141

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