[tint] Add subgroup builtin inputs
Adds parsing and SPIR-V codegen for subgroup_invocation_id and
subgroup_size.
Bug: tint:2000
Change-Id: Idcb9e2011c8c6129c5a0e5f0564048c14f8625a6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/143835
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index 05ecb45..0774687 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -37,6 +37,8 @@
num_workgroups
sample_index
sample_mask
+ subgroup_invocation_id
+ subgroup_size
__point_size
}
diff --git a/src/tint/lang/core/builtin/builtin_value.cc b/src/tint/lang/core/builtin/builtin_value.cc
index 644a217..f11b797 100644
--- a/src/tint/lang/core/builtin/builtin_value.cc
+++ b/src/tint/lang/core/builtin/builtin_value.cc
@@ -61,6 +61,12 @@
if (str == "sample_mask") {
return BuiltinValue::kSampleMask;
}
+ if (str == "subgroup_invocation_id") {
+ return BuiltinValue::kSubgroupInvocationId;
+ }
+ if (str == "subgroup_size") {
+ return BuiltinValue::kSubgroupSize;
+ }
if (str == "vertex_index") {
return BuiltinValue::kVertexIndex;
}
@@ -96,6 +102,10 @@
return "sample_index";
case BuiltinValue::kSampleMask:
return "sample_mask";
+ case BuiltinValue::kSubgroupInvocationId:
+ return "subgroup_invocation_id";
+ case BuiltinValue::kSubgroupSize:
+ return "subgroup_size";
case BuiltinValue::kVertexIndex:
return "vertex_index";
case BuiltinValue::kWorkgroupId:
diff --git a/src/tint/lang/core/builtin/builtin_value.h b/src/tint/lang/core/builtin/builtin_value.h
index ef527f3..96c91b0 100644
--- a/src/tint/lang/core/builtin/builtin_value.h
+++ b/src/tint/lang/core/builtin/builtin_value.h
@@ -41,6 +41,8 @@
kPosition,
kSampleIndex,
kSampleMask,
+ kSubgroupInvocationId,
+ kSubgroupSize,
kVertexIndex,
kWorkgroupId,
};
@@ -66,8 +68,8 @@
"__point_size", "frag_depth", "front_facing",
"global_invocation_id", "instance_index", "local_invocation_id",
"local_invocation_index", "num_workgroups", "position",
- "sample_index", "sample_mask", "vertex_index",
- "workgroup_id",
+ "sample_index", "sample_mask", "subgroup_invocation_id",
+ "subgroup_size", "vertex_index", "workgroup_id",
};
} // namespace tint::builtin
diff --git a/src/tint/lang/core/builtin/builtin_value_bench.cc b/src/tint/lang/core/builtin/builtin_value_bench.cc
index 35f68fd..f7b8d3f 100644
--- a/src/tint/lang/core/builtin/builtin_value_bench.cc
+++ b/src/tint/lang/core/builtin/builtin_value_bench.cc
@@ -108,20 +108,34 @@
"33amOe_mas66",
"samoott6QQmask",
"66mple_mask",
- "verzzx_in6Oxx",
- "vertex_yyndex",
- "vetxHHZnZex",
+ "subroup_invoOaxion_i6zz",
+ "subgroup_inyyocation_id",
+ "subgrup_invcatiZHH_id",
+ "subgroup_invocation_id",
+ "subgroqp_inWWoat44on_id",
+ "subgrou_inOOocation_id",
+ "suhgrup_invoYation_id",
+ "subroup_si",
+ "suFgoup_size",
+ "subgowp_size",
+ "subgroup_size",
+ "suffgKup_sie",
+ "KKubgroqp_size",
+ "subFroup3mmize",
+ "ertex_index",
+ "verteq_inex",
+ "verbx_indbbx",
"vertex_index",
- "vWWteq_in44ex",
- "vrtex_OOndex",
- "hrteYooindx",
- "wogroup_i",
- "wokgrouF_id",
- "worgrwup_id",
+ "iertex_indx",
+ "veOOtexqidex",
+ "vertexvvindTTx",
+ "workFFroup_id",
+ "workgPfpQ00d",
+ "woPkgroup_id",
"workgroup_id",
- "workGKou_if",
- "worKKgrouq_id",
- "w3rkgrommp_id",
+ "wosskgrup_i77",
+ "workgroup_bbRC",
+ "workgroup_iXX",
};
for (auto _ : state) {
for (auto* str : kStrings) {
diff --git a/src/tint/lang/core/builtin/builtin_value_test.cc b/src/tint/lang/core/builtin/builtin_value_test.cc
index dc2c26f..ca74e72 100644
--- a/src/tint/lang/core/builtin/builtin_value_test.cc
+++ b/src/tint/lang/core/builtin/builtin_value_test.cc
@@ -54,6 +54,8 @@
{"position", BuiltinValue::kPosition},
{"sample_index", BuiltinValue::kSampleIndex},
{"sample_mask", BuiltinValue::kSampleMask},
+ {"subgroup_invocation_id", BuiltinValue::kSubgroupInvocationId},
+ {"subgroup_size", BuiltinValue::kSubgroupSize},
{"vertex_index", BuiltinValue::kVertexIndex},
{"workgroup_id", BuiltinValue::kWorkgroupId},
};
@@ -92,12 +94,18 @@
{"sample_XXask", BuiltinValue::kUndefined},
{"samII99l55_mask", BuiltinValue::kUndefined},
{"samaale_SSrHHYk", BuiltinValue::kUndefined},
- {"verkkeH_de", BuiltinValue::kUndefined},
- {"verRg_injex", BuiltinValue::kUndefined},
- {"vrtexinbex", BuiltinValue::kUndefined},
- {"workjroup_id", BuiltinValue::kUndefined},
- {"wrkgroup_id", BuiltinValue::kUndefined},
- {"qorkgro_id", BuiltinValue::kUndefined},
+ {"skkgroup_Hnvocatio_d", BuiltinValue::kUndefined},
+ {"gRbgroup_invocajionid", BuiltinValue::kUndefined},
+ {"sbgroup_nbocation_id", BuiltinValue::kUndefined},
+ {"subgroupjsize", BuiltinValue::kUndefined},
+ {"subgroup_sie", BuiltinValue::kUndefined},
+ {"sgroupqsize", BuiltinValue::kUndefined},
+ {"vertx_NNndex", BuiltinValue::kUndefined},
+ {"vvertex_dex", BuiltinValue::kUndefined},
+ {"ertex_inQQex", BuiltinValue::kUndefined},
+ {"wrkgrup_irf", BuiltinValue::kUndefined},
+ {"workgroup_jd", BuiltinValue::kUndefined},
+ {"w82wNNgrou_id", BuiltinValue::kUndefined},
};
using BuiltinValueParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/lang/spirv/writer/ast_printer/builder.cc b/src/tint/lang/spirv/writer/ast_printer/builder.cc
index 1457e51..a147279 100644
--- a/src/tint/lang/spirv/writer/ast_printer/builder.cc
+++ b/src/tint/lang/spirv/writer/ast_printer/builder.cc
@@ -4005,6 +4005,12 @@
return SpvBuiltInSampleId;
case builtin::BuiltinValue::kSampleMask:
return SpvBuiltInSampleMask;
+ case builtin::BuiltinValue::kSubgroupInvocationId:
+ module_.PushCapability(SpvCapabilityGroupNonUniform);
+ return SpvBuiltInSubgroupLocalInvocationId;
+ case builtin::BuiltinValue::kSubgroupSize:
+ module_.PushCapability(SpvCapabilityGroupNonUniform);
+ return SpvBuiltInSubgroupSize;
case builtin::BuiltinValue::kUndefined:
break;
}
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index f500bae..ea54789 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -232,6 +232,12 @@
return SpvBuiltInSampleId;
case builtin::BuiltinValue::kSampleMask:
return SpvBuiltInSampleMask;
+ case builtin::BuiltinValue::kSubgroupInvocationId:
+ module_.PushCapability(SpvCapabilityGroupNonUniform);
+ return SpvBuiltInSubgroupLocalInvocationId;
+ case builtin::BuiltinValue::kSubgroupSize:
+ module_.PushCapability(SpvCapabilityGroupNonUniform);
+ return SpvBuiltInSubgroupSize;
case builtin::BuiltinValue::kVertexIndex:
return SpvBuiltInVertexIndex;
case builtin::BuiltinValue::kWorkgroupId:
diff --git a/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc b/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
index 4564d4b..e3036e5 100644
--- a/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
+++ b/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
@@ -46,7 +46,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(), R"(12:34 error: unresolved builtin value 'positon'
12:34 note: Did you mean 'position'?
-Possible values: 'frag_depth', 'front_facing', 'global_invocation_id', 'instance_index', 'local_invocation_id', 'local_invocation_index', 'num_workgroups', 'position', 'sample_index', 'sample_mask', 'vertex_index', 'workgroup_id')");
+Possible values: 'frag_depth', 'front_facing', 'global_invocation_id', 'instance_index', 'local_invocation_id', 'local_invocation_index', 'num_workgroups', 'position', 'sample_index', 'sample_mask', 'subgroup_invocation_id', 'subgroup_size', 'vertex_index', 'workgroup_id')");
}
TEST_F(ResolverUnresolvedIdentifierSuggestions, TexelFormat) {
diff --git a/test/tint/shader_io/compute_subgroup_builtins.wgsl b/test/tint/shader_io/compute_subgroup_builtins.wgsl
new file mode 100644
index 0000000..8b85ca2
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins.wgsl
@@ -0,0 +1,10 @@
+@group(0) @binding(0)
+var<storage, read_write> output: array<u32>;
+
+@compute @workgroup_size(1)
+fn main(
+ @builtin(subgroup_invocation_id) subgroup_invocation_id : u32,
+ @builtin(subgroup_size) subgroup_size : u32,
+) {
+ output[subgroup_invocation_id] = subgroup_size;
+}
diff --git a/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.dxc.hlsl b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..24241e6
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.dxc.hlsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> output : array<u32>;
+
+@compute @workgroup_size(1)
+fn main(@builtin(subgroup_invocation_id) subgroup_invocation_id : u32, @builtin(subgroup_size) subgroup_size : u32) {
+ output[subgroup_invocation_id] = subgroup_size;
+}
+
+Failed to generate: error: unsupported builtin
diff --git a/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.fxc.hlsl b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..24241e6
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.fxc.hlsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> output : array<u32>;
+
+@compute @workgroup_size(1)
+fn main(@builtin(subgroup_invocation_id) subgroup_invocation_id : u32, @builtin(subgroup_size) subgroup_size : u32) {
+ output[subgroup_invocation_id] = subgroup_size;
+}
+
+Failed to generate: error: unsupported builtin
diff --git a/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.glsl b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.glsl
new file mode 100644
index 0000000..f88e037
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.glsl
@@ -0,0 +1,24 @@
+SKIP: FAILED
+
+#version 310 es
+
+layout(binding = 0, std430) buffer tint_symbol_block_ssbo {
+ uint inner[];
+} tint_symbol;
+
+void tint_symbol_1(uint subgroup_invocation_id, uint subgroup_size) {
+ tint_symbol.inner[subgroup_invocation_id] = subgroup_size;
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ tint_symbol_1(tint_symbol_2, tint_symbol_3);
+ return;
+}
+Error parsing GLSL shader:
+ERROR: 0:13: 'tint_symbol_2' : undeclared identifier
+ERROR: 0:13: '' : compilation terminated
+ERROR: 2 compilation errors. No code generated.
+
+
+
diff --git a/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.msl b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.msl
new file mode 100644
index 0000000..c87173c
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.msl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> output : array<u32>;
+
+@compute @workgroup_size(1)
+fn tint_symbol(@builtin(subgroup_invocation_id) subgroup_invocation_id : u32, @builtin(subgroup_size) subgroup_size : u32) {
+ output[subgroup_invocation_id] = subgroup_size;
+}
+
+Failed to generate: error: unknown builtin
diff --git a/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.spvasm b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.spvasm
new file mode 100644
index 0000000..1190c73
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.spvasm
@@ -0,0 +1,2 @@
+error: line 2: Invalid capability operand: 61
+
diff --git a/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.wgsl b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.wgsl
new file mode 100644
index 0000000..91d8bff
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> output : array<u32>;
+
+@compute @workgroup_size(1)
+fn main(@builtin(subgroup_invocation_id) subgroup_invocation_id : u32, @builtin(subgroup_size) subgroup_size : u32) {
+ output[subgroup_invocation_id] = subgroup_size;
+}
diff --git a/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl
new file mode 100644
index 0000000..fac4f13
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl
@@ -0,0 +1,12 @@
+@group(0) @binding(0)
+var<storage, read_write> output: array<u32>;
+
+struct ComputeInputs {
+ @builtin(subgroup_invocation_id) subgroup_invocation_id : u32,
+ @builtin(subgroup_size) subgroup_size : u32,
+};
+
+@compute @workgroup_size(1)
+fn main(inputs : ComputeInputs) {
+ output[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+}
diff --git a/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.dxc.hlsl b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.dxc.hlsl
new file mode 100644
index 0000000..cab4b43
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.dxc.hlsl
@@ -0,0 +1,18 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> output : array<u32>;
+
+struct ComputeInputs {
+ @builtin(subgroup_invocation_id)
+ subgroup_invocation_id : u32,
+ @builtin(subgroup_size)
+ subgroup_size : u32,
+}
+
+@compute @workgroup_size(1)
+fn main(inputs : ComputeInputs) {
+ output[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+}
+
+Failed to generate: error: unsupported builtin
diff --git a/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.fxc.hlsl b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.fxc.hlsl
new file mode 100644
index 0000000..cab4b43
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.fxc.hlsl
@@ -0,0 +1,18 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> output : array<u32>;
+
+struct ComputeInputs {
+ @builtin(subgroup_invocation_id)
+ subgroup_invocation_id : u32,
+ @builtin(subgroup_size)
+ subgroup_size : u32,
+}
+
+@compute @workgroup_size(1)
+fn main(inputs : ComputeInputs) {
+ output[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+}
+
+Failed to generate: error: unsupported builtin
diff --git a/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.glsl b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.glsl
new file mode 100644
index 0000000..224650c
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.glsl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+#version 310 es
+
+layout(binding = 0, std430) buffer tint_symbol_block_ssbo {
+ uint inner[];
+} tint_symbol;
+
+struct ComputeInputs {
+ uint subgroup_invocation_id;
+ uint subgroup_size;
+};
+
+void tint_symbol_1(ComputeInputs inputs) {
+ tint_symbol.inner[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+}
+
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ ComputeInputs tint_symbol_4 = ComputeInputs(tint_symbol_2, tint_symbol_3);
+ tint_symbol_1(tint_symbol_4);
+ return;
+}
+Error parsing GLSL shader:
+ERROR: 0:18: 'tint_symbol_2' : undeclared identifier
+ERROR: 0:18: '' : compilation terminated
+ERROR: 2 compilation errors. No code generated.
+
+
+
diff --git a/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.msl b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.msl
new file mode 100644
index 0000000..feae4f3
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.msl
@@ -0,0 +1,18 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> output : array<u32>;
+
+struct ComputeInputs {
+ @builtin(subgroup_invocation_id)
+ subgroup_invocation_id : u32,
+ @builtin(subgroup_size)
+ subgroup_size : u32,
+}
+
+@compute @workgroup_size(1)
+fn tint_symbol(inputs : ComputeInputs) {
+ output[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+}
+
+Failed to generate: error: unknown builtin
diff --git a/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.spvasm b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.spvasm
new file mode 100644
index 0000000..1190c73
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.spvasm
@@ -0,0 +1,2 @@
+error: line 2: Invalid capability operand: 61
+
diff --git a/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.wgsl b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.wgsl
new file mode 100644
index 0000000..0191fdb
--- /dev/null
+++ b/test/tint/shader_io/compute_subgroup_builtins_struct.wgsl.expected.wgsl
@@ -0,0 +1,13 @@
+@group(0) @binding(0) var<storage, read_write> output : array<u32>;
+
+struct ComputeInputs {
+ @builtin(subgroup_invocation_id)
+ subgroup_invocation_id : u32,
+ @builtin(subgroup_size)
+ subgroup_size : u32,
+}
+
+@compute @workgroup_size(1)
+fn main(inputs : ComputeInputs) {
+ output[inputs.subgroup_invocation_id] = inputs.subgroup_size;
+}