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

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

Расстояние между клипами в WGSL

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

Если в GPUAdapter доступна функция "clip-distances" , запросите 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()

После вызова configure() класса GPUCanvasContext с заданным словарем конфигурации, метод getConfiguration() класса GPUCanvasContext позволяет проверить конфигурацию контекста холста. Он включает в себя члены 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 .

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

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

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

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

Утренние обновления

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

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

Что нового в WebGPU?

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

Хром 144

Хром 143

Хром 142

Хром 141

Хром 140

Хром 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