Skip to content

Commit 10bf620

Browse files
mvaligurskyMartin Valigursky
andauthored
feat: add WebGPU subgroup operations support (#8528)
Request the `subgroups` device feature, add `supportsSubgroups` property, auto-inject `enable subgroups;` and `requires subgroup_id;` into WGSL shaders, and expose `CAPS_SUBGROUPS` / `CAPS_SUBGROUP_ID` shader defines. Made-with: Cursor Co-authored-by: Martin Valigursky <mvaligursky@snapchat.com>
1 parent 0422b32 commit 10bf620

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

src/platform/graphics/graphics-device.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -258,13 +258,22 @@ class GraphicsDevice extends EventHandler {
258258
*/
259259
supportsStorageTextureRead = false;
260260

261+
/**
262+
* True if the device supports subgroup operations in shaders (WebGPU only). When supported,
263+
* compute and fragment shaders can use WGSL subgroup builtins such as `subgroupBroadcast`,
264+
* `subgroupAll`, `subgroupAny`, `subgroupAdd`, `subgroupShuffle`, etc. The `enable subgroups;`
265+
* directive is automatically injected into WGSL shaders when this feature is available.
266+
*
267+
* @type {boolean}
268+
* @readonly
269+
*/
270+
supportsSubgroups = false;
271+
261272
/**
262273
* True if the device supports the WGSL subgroup_uniformity extension, which allows
263274
* subgroup functionality to be considered uniform in more cases during shader compilation.
264-
* When a shader uses this feature, use an `enable` directive at the top of the WGSL shader:
265-
* ```wgsl
266-
* enable subgroups;
267-
* ```
275+
* This is automatically enabled via the `enable subgroups;` directive when
276+
* {@link GraphicsDevice#supportsSubgroups} is true.
268277
*
269278
* @readonly
270279
* @type {boolean}
@@ -273,14 +282,11 @@ class GraphicsDevice extends EventHandler {
273282

274283
/**
275284
* True if the device supports the WGSL subgroup_id extension, which provides access to
276-
* `subgroup_id` and `num_subgroups` built-in values in workgroups.
277-
* When a shader uses this feature, use a `requires` directive at the top of the WGSL shader:
278-
* ```wgsl
279-
* requires subgroup_id;
280-
* ```
285+
* `subgroup_id` and `num_subgroups` built-in values in workgroups. The `requires subgroup_id;`
286+
* directive is automatically injected into WGSL shaders when this feature is available.
281287
*
282-
* @readonly
283288
* @type {boolean}
289+
* @readonly
284290
*/
285291
supportsSubgroupId = false;
286292

@@ -655,6 +661,8 @@ class GraphicsDevice extends EventHandler {
655661
if (this.supportsMultiDraw) capsDefines.set('CAPS_MULTI_DRAW', '');
656662
if (this.supportsPrimitiveIndex) capsDefines.set('CAPS_PRIMITIVE_INDEX', '');
657663
if (this.supportsShaderF16) capsDefines.set('CAPS_SHADER_F16', '');
664+
if (this.supportsSubgroups) capsDefines.set('CAPS_SUBGROUPS', '');
665+
if (this.supportsSubgroupId) capsDefines.set('CAPS_SUBGROUP_ID', '');
658666

659667
// Platform defines
660668
if (platform.desktop) capsDefines.set('PLATFORM_DESKTOP', '');

src/platform/graphics/shader-definition-utils.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ class ShaderDefinitionUtils {
221221
if (shaderType === 'fragment' && device.supportsPrimitiveIndex) {
222222
code += 'enable primitive_index;\n';
223223
}
224+
if (device.supportsSubgroups) {
225+
code += 'enable subgroups;\n';
226+
}
227+
if (device.supportsSubgroupId) {
228+
code += 'requires subgroup_id;\n';
229+
}
224230
return code;
225231
}
226232

src/platform/graphics/webgpu/webgpu-graphics-device.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ class WebgpuGraphicsDevice extends GraphicsDevice {
327327
this.supportsTextureFormatTier2 = requireFeature('texture-format-tier2');
328328
this.supportsTextureFormatTier1 ||= this.supportsTextureFormatTier2;
329329
this.supportsPrimitiveIndex = requireFeature('primitive-index');
330+
this.supportsSubgroups = requireFeature('subgroups');
330331
Debug.log(`WEBGPU features: ${requiredFeatures.join(', ')}`);
331332

332333
// copy all adapter limits to the requiredLimits object - to created a device with the best feature sets available

0 commit comments

Comments
 (0)