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

François Beaufort
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-холста, как показано в примере с частицами (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) – возвращает суммарное значение сканирования всех активных вызовов values в подгруппе.
  • subgroupInclusiveMul(value): возвращает инклюзивное сканирование всех активных вызовов values в подгруппе.

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

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

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

Если в GPUAdapter доступна нестандартная функция GPU "chromium-experimental-multi-draw-indirect", запросите 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();

Параметр компиляции модуля шейдера strict math

В GPUShaderModuleDescriptor добавлен логический параметр strictMath для разработчиков, позволяющий включить или отключить строгие математические вычисления при компиляции модуля шейдера. Она доступна за флагом "Функции WebGPU для разработчиков" в chrome://flags/#enable-webgpu-developer-features, то есть предназначена только для использования во время разработки. Подробнее об этой проблеме…

Сейчас эта функция поддерживается в 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()

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

Обновления на рассвете

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

Это лишь некоторые из основных изменений. Ознакомьтесь с полным списком коммитов.

Что нового в WebGPU

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

Chrome 155–156

Chrome 153–154

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