Что нового в WebGPU (Chrome 131)

Франсуа Бофор
François Beaufort

Расстояния клипов в WGSL

Расстояния отсечения позволяют ограничить объём отсечения примитивов с помощью определяемых пользователем полупространств на выходе этапа вершин. Определение собственных плоскостей отсечения обеспечивает больший контроль над видимым содержимым сцен WebGPU. Этот метод особенно полезен для таких приложений, как САПР, где точный контроль над визуализацией критически важен.

Если функция "clip-distances" доступна в GPUAdapter, запросите GPUDevice с этой функцией, чтобы получить поддержку расстояний отсечения в WGSL, и явно включите это расширение в коде WGSL с помощью enable clip_distances; После включения вы сможете использовать встроенный массив clip_distances в вершинном шейдере. Этот массив хранит расстояния до пользовательской плоскости отсечения:

  • Расстояние отсечения, равное 0, означает, что вершина лежит на плоскости.
  • Положительное расстояние означает, что вершина находится внутри отсекаемого полупространства (стороны, которую вы хотите сохранить).
  • Отрицательное расстояние означает, что вершина находится вне отсекаемого полупространства (стороны, которую вы хотите отбросить).

См. следующий фрагмент, запись chromestatus и проблему 358408571 .

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("clip-distances")) {
  throw new Error("Clip distances support is not available");
}
// Explicitly request clip distances support.
const device = await adapter.requestDevice({
  requiredFeatures: ["clip-distances"],
});

const vertexShaderModule = device.createShaderModule({ code: `
  enable clip_distances;

  struct VertexOut {
    @builtin(clip_distances) my_clip_distances : array<f32, 1>,
    @builtin(position) my_position : vec4f,
  }
  @vertex fn main() -> VertexOut {
    var output : VertexOut;
    output.my_clip_distances[0] = 1;
    output.my_position = vec4f(0, 0, 0, 1);
    return output;
  }
`,
});

// Send the appropriate commands to the GPU...

GPUCanvasContext getConfiguration()

После вызова метода GPUCanvasContext configure() со словарём конфигурации метод GPUCanvasContext getConfiguration() позволяет проверить конфигурацию контекста холста. Он включает в себя элементы device , format , usage , viewFormats , colorSpace , toneMapping и alphaMode . Это полезно для таких задач, как проверка поддержки HDR-холста браузером, как показано в примере Particles (HDR) . См. следующий фрагмент кода, запись chromestatus и номер проблемы 370109829 .

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

const canvas = document.querySelector("canvas");
const context = canvas.getContext("webgpu");

// Configure the canvas for HDR.
context.configure({
  device,
  format: "rgba16float",
  toneMapping: { mode: "extended" },
});

const configuration = context.getConfiguration();
if (configuration.toneMapping.mode === "extended") {
  // The browser supports HDR canvas.
  // Warning! The user still needs a HDR display to enjoy HDR content.
}

Точечные и линейные примитивы не должны иметь смещения глубины.

Как было объявлено ранее , спецификация WebGPU теперь делает ошибкой валидации установку ненулевых значений для параметров depthBias , depthBiasSlopeScale и depthBiasClamp , если топология конвейера рендеринга представляет собой линию или точку. См. проблему 352567424 .

Встроенные функции сканирования для подгрупп

В рамках экспериментов с подгруппами в выпуске 361330160 были добавлены следующие встроенные функции подгрупп:

  • subgroupInclusiveAdd(value) : возвращает инклюзивную сумму сканирования всех активных вызовов value s в подгруппе.
  • subgroupInclusiveMul(value) : возвращает инклюзивное сканирование умножения всех активных вызовов value s в подгруппе.

Экспериментальная поддержка многоразового косвенного вывода

Функция многомерной непрямой отрисовки GPU позволяет выполнять несколько вызовов отрисовки одной командой GPU. Это особенно полезно в ситуациях, когда требуется отрисовка большого количества объектов, например, систем частиц, инстансинга и больших сцен. Методы drawIndirect() и drawIndexedIndirect() класса GPURenderPassEncoder могут выполнять только один вызов отрисовки за раз из определённой области буфера GPU.

Пока эта экспериментальная функция не стандартизирована , включите флаг «Поддержка небезопасного WebGPU» на chrome://flags/#enable-unsafe-webgpu , чтобы она стала доступна в Chrome.

Используя нестандартную функцию графического процессора "chromium-experimental-multi-draw-indirect" доступную в GPUAdapter, запросите GPUDevice с этой функцией. Затем создайте GPUBuffer с использованием GPUBufferUsage.INDIRECT для хранения вызовов отрисовки. Вы сможете использовать его позже в новых методах multiDrawIndirect() и multiDrawIndexedIndirect() GPURenderPassEncoder для выполнения вызовов отрисовки внутри прохода рендеринга. См. следующий фрагмент кода и ошибку 356461286 .

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("chromium-experimental-multi-draw-indirect")) {
  throw new Error("Experimental multi-draw indirect support is not available");
}
// Explicitly request experimental multi-draw indirect support.
const device = await adapter.requestDevice({
  requiredFeatures: ["chromium-experimental-multi-draw-indirect"],
});

// Draw call have vertexCount, instanceCount, firstVertex, and firstInstance parameters.
const drawData = new Uint32Array([
  3, 1, 0, 0, // First draw call
  3, 1, 3, 0, // Second draw call
]);
// Create a buffer to store the draw calls.
const drawBuffer = device.createBuffer({
  size: drawData.byteLength,
  usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(drawBuffer, 0, drawData);

// Create a render pipeline, a vertex buffer, and a render pass encoder...

// Inside a render pass, issue the draw calls.
myPassEncoder.setPipeline(myPipeline);
myPassEncoder.setVertexBuffer(0, myVertexBuffer);
myPassEncoder.multiDrawIndirect(drawBuffer, /*offset=*/ 0, /*maxDrawCount=*/ 2);
myPassEncoder.end();

Опция компиляции модуля шейдера строгая математика

В GPUShaderModuleDescriptor добавлен логический параметр разработчика strictMath , позволяющий включать и отключать строгую математику во время компиляции модуля шейдера. Он доступен с помощью флага «WebGPU Developer Features» по адресу chrome://flags/#enable-webgpu-developer-features , что означает, что эта функция предназначена только для использования во время разработки. См. issue 42241455 .

Эта опция в настоящее время поддерживается в Metal и Direct3D. При отключении строгой математики компилятор может оптимизировать ваши шейдеры следующим образом:

  • Игнорирование возможности значений NaN и Infinity.
  • Рассматриваем -0 как +0.
  • Замена деления более быстрым умножением на обратную величину.
  • Перестановочные операции, основанные на ассоциативных и распределительных свойствах.
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const code = `
  // Examines the bit pattern of the floating-point number to
  // determine if it represents a NaN according to the IEEE 754 standard.
  fn isNan(x : f32) -> bool {
    bool ones_exp = (bitcast<u32>(x) & 0x7f8) == 0x7f8;
    bool non_zero_sig = (bitcast<u32>(x) & 0x7ffff) != 0;
    return ones_exp && non_zero_sig;
  }
  // ...
`;

// Enable strict math during shader compilation.
const shaderModule = device.createShaderModule({ code, strictMath: true });

Удалить GPUAdapter requestAdapterInfo()

Асинхронный метод requestAdapterInfo() класса GPUAdapter избыточен, поскольку GPUAdapterInfo уже можно получить синхронно с помощью атрибута info класса GPUAdapter. Поэтому нестандартный метод requestAdapterInfo() класса GPUAdapter теперь удалён. См. намерение удалить .

Обновления Dawn

Исполняемый файл tint_benchmark измеряет стоимость перевода шейдеров из WGSL на каждый язык бэкенда. Подробнее об этом читайте в новой документации .

Здесь рассматриваются лишь некоторые из ключевых моментов. Ознакомьтесь с полным списком коммитов .

Что нового в WebGPU

Список всего, что было рассмотрено в серии « Что нового в WebGPU» .

Хром 139

Хром 138

Хром 137

Хром 136

Хром 135

Хром 134

Хром 133

Хром 132

Хром 131

Хром 130

Хром 129

Хром 128

Хром 127

Хром 126

Хром 125

Хром 124

Хром 123

Хром 122

Хром 121

Хром 120

Хром 119

Хром 118

Хром 117

Хром 116

Хром 115

Хром 114

Хром 113