Revert "Remove SubgroupsF16 feature and subgroups_f16 WGSL extension"
This reverts commit 7bb9a04ba94d8f4b40e8dbb2d000199d75cc9453.
Reason for revert: Broke rolls into g3 and Chromium. ML code depends on GPUFeatureName::SubroupsF16
Bug: 380244620, 390632529, 383606929
Original change's description:
> Remove SubgroupsF16 feature and subgroups_f16 WGSL extension
>
> Bug: 380244620, 390632529, 383606929
> Change-Id: Ie93be38eda90fb445c443f37466a01e67b071a0e
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/235454
> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
> Reviewed-by: David Neto <dneto@google.com>
> Commit-Queue: Fr <beaufort.francois@gmail.com>
Bug: 380244620, 390632529, 383606929
Change-Id: I4e4e98ce2f756c9593184d0ae041c1aae83b53d9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/236834
Commit-Queue: David Neto <dneto@google.com>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: David Neto <dneto@google.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index fed5999..7d59db0 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -2270,58 +2270,59 @@
{"value": 5, "name": "chromium experimental immediate data", "tags": ["dawn"]},
{"value": 6, "name": "transient attachments", "tags": ["dawn"]},
{"value": 7, "name": "MSAA render to single sampled", "tags": ["dawn"]},
- {"value": 8, "name": "D3D11 multithread protected", "tags": ["dawn", "native"]},
- {"value": 9, "name": "ANGLE texture sharing", "tags": ["dawn", "native"]},
- {"value": 10, "name": "pixel local storage coherent", "tags": ["dawn"]},
- {"value": 11, "name": "pixel local storage non coherent", "tags": ["dawn"]},
- {"value": 12, "name": "unorm16 texture formats", "tags": ["dawn", "emscripten"], "jsrepr": "'chromium-experimental-unorm16-texture-formats'"},
- {"value": 13, "name": "snorm16 texture formats", "tags": ["dawn", "emscripten"], "jsrepr": "'chromium-experimental-snorm16-texture-formats'"},
- {"value": 14, "name": "multi planar format extended usages", "tags": ["dawn"]},
- {"value": 15, "name": "multi planar format p010", "tags": ["dawn"]},
- {"value": 16, "name": "host mapped pointer", "tags": ["dawn"]},
- {"value": 17, "name": "multi planar render targets", "tags": ["dawn"]},
- {"value": 18, "name": "multi planar format nv12a", "tags": ["dawn"]},
- {"value": 19, "name": "framebuffer fetch", "tags": ["dawn"]},
- {"value": 20, "name": "buffer map extended usages", "tags": ["dawn"]},
- {"value": 21, "name": "adapter properties memory heaps", "tags": ["dawn"]},
- {"value": 22, "name": "adapter properties D3D", "tags": ["dawn"]},
- {"value": 23, "name": "adapter properties vk", "tags": ["dawn"]},
- {"value": 24, "name": "r8 unorm storage", "tags": ["dawn"]},
- {"value": 25, "name": "dawn format capabilities", "tags": ["dawn"]},
- {"value": 26, "name": "dawn drm format capabilities", "tags": ["dawn"]},
- {"value": 27, "name": "norm16 texture formats", "tags": ["dawn"]},
- {"value": 28, "name": "multi planar format nv16", "tags": ["dawn"]},
- {"value": 29, "name": "multi planar format nv24", "tags": ["dawn"]},
- {"value": 30, "name": "multi planar format p210", "tags": ["dawn"]},
- {"value": 31, "name": "multi planar format p410", "tags": ["dawn"]},
+ {"value": 8, "name": "subgroups f16", "tags": ["dawn", "emscripten", "deprecated"]},
+ {"value": 9, "name": "D3D11 multithread protected", "tags": ["dawn", "native"]},
+ {"value": 10, "name": "ANGLE texture sharing", "tags": ["dawn", "native"]},
+ {"value": 11, "name": "pixel local storage coherent", "tags": ["dawn"]},
+ {"value": 12, "name": "pixel local storage non coherent", "tags": ["dawn"]},
+ {"value": 13, "name": "unorm16 texture formats", "tags": ["dawn", "emscripten"], "jsrepr": "'chromium-experimental-unorm16-texture-formats'"},
+ {"value": 14, "name": "snorm16 texture formats", "tags": ["dawn", "emscripten"], "jsrepr": "'chromium-experimental-snorm16-texture-formats'"},
+ {"value": 15, "name": "multi planar format extended usages", "tags": ["dawn"]},
+ {"value": 16, "name": "multi planar format p010", "tags": ["dawn"]},
+ {"value": 17, "name": "host mapped pointer", "tags": ["dawn"]},
+ {"value": 18, "name": "multi planar render targets", "tags": ["dawn"]},
+ {"value": 19, "name": "multi planar format nv12a", "tags": ["dawn"]},
+ {"value": 20, "name": "framebuffer fetch", "tags": ["dawn"]},
+ {"value": 21, "name": "buffer map extended usages", "tags": ["dawn"]},
+ {"value": 22, "name": "adapter properties memory heaps", "tags": ["dawn"]},
+ {"value": 23, "name": "adapter properties D3D", "tags": ["dawn"]},
+ {"value": 24, "name": "adapter properties vk", "tags": ["dawn"]},
+ {"value": 25, "name": "r8 unorm storage", "tags": ["dawn"]},
+ {"value": 26, "name": "dawn format capabilities", "tags": ["dawn"]},
+ {"value": 27, "name": "dawn drm format capabilities", "tags": ["dawn"]},
+ {"value": 28, "name": "norm16 texture formats", "tags": ["dawn"]},
+ {"value": 29, "name": "multi planar format nv16", "tags": ["dawn"]},
+ {"value": 30, "name": "multi planar format nv24", "tags": ["dawn"]},
+ {"value": 31, "name": "multi planar format p210", "tags": ["dawn"]},
+ {"value": 32, "name": "multi planar format p410", "tags": ["dawn"]},
- {"value": 32, "name": "shared texture memory vk dedicated allocation", "tags": ["dawn", "native"]},
- {"value": 33, "name": "shared texture memory a hardware buffer", "tags": ["dawn", "native"]},
- {"value": 34, "name": "shared texture memory dma buf", "tags": ["dawn", "native"]},
- {"value": 35, "name": "shared texture memory opaque FD", "tags": ["dawn", "native"]},
- {"value": 36, "name": "shared texture memory zircon handle", "tags": ["dawn", "native"]},
- {"value": 37, "name": "shared texture memory DXGI shared handle", "tags": ["dawn", "native"]},
- {"value": 38, "name": "shared texture memory D3D11 texture 2D", "tags": ["dawn", "native"]},
- {"value": 39, "name": "shared texture memory IO surface", "tags": ["dawn", "native"]},
- {"value": 40, "name": "shared texture memory EGL image", "tags": ["dawn", "native"]},
- {"value": 41, "name": "shared fence vk semaphore opaque FD", "tags": ["dawn", "native"]},
- {"value": 42, "name": "shared fence sync FD", "tags": ["dawn", "native"]},
- {"value": 43, "name": "shared fence vk semaphore zircon handle", "tags": ["dawn", "native"]},
- {"value": 44, "name": "shared fence DXGI shared handle", "tags": ["dawn", "native"]},
- {"value": 45, "name": "shared fence MTL shared event", "tags": ["dawn", "native"]},
- {"value": 46, "name": "shared buffer memory D3D12 resource", "tags": ["dawn", "native"]},
- {"value": 47, "name": "static samplers", "tags": ["dawn"]},
- {"value": 48, "name": "y cb cr vulkan samplers", "tags": ["dawn"]},
- {"value": 49, "name": "shader module compilation options", "tags": ["dawn"]},
+ {"value": 33, "name": "shared texture memory vk dedicated allocation", "tags": ["dawn", "native"]},
+ {"value": 34, "name": "shared texture memory a hardware buffer", "tags": ["dawn", "native"]},
+ {"value": 35, "name": "shared texture memory dma buf", "tags": ["dawn", "native"]},
+ {"value": 36, "name": "shared texture memory opaque FD", "tags": ["dawn", "native"]},
+ {"value": 37, "name": "shared texture memory zircon handle", "tags": ["dawn", "native"]},
+ {"value": 38, "name": "shared texture memory DXGI shared handle", "tags": ["dawn", "native"]},
+ {"value": 39, "name": "shared texture memory D3D11 texture 2D", "tags": ["dawn", "native"]},
+ {"value": 40, "name": "shared texture memory IO surface", "tags": ["dawn", "native"]},
+ {"value": 41, "name": "shared texture memory EGL image", "tags": ["dawn", "native"]},
+ {"value": 42, "name": "shared fence vk semaphore opaque FD", "tags": ["dawn", "native"]},
+ {"value": 43, "name": "shared fence sync FD", "tags": ["dawn", "native"]},
+ {"value": 44, "name": "shared fence vk semaphore zircon handle", "tags": ["dawn", "native"]},
+ {"value": 45, "name": "shared fence DXGI shared handle", "tags": ["dawn", "native"]},
+ {"value": 46, "name": "shared fence MTL shared event", "tags": ["dawn", "native"]},
+ {"value": 47, "name": "shared buffer memory D3D12 resource", "tags": ["dawn", "native"]},
+ {"value": 48, "name": "static samplers", "tags": ["dawn"]},
+ {"value": 49, "name": "y cb cr vulkan samplers", "tags": ["dawn"]},
+ {"value": 50, "name": "shader module compilation options", "tags": ["dawn"]},
- {"value": 50, "name": "dawn load resolve texture", "tags": ["dawn"]},
- {"value": 51, "name": "dawn partial load resolve texture", "tags": ["dawn"]},
- {"value": 52, "name": "multi draw indirect", "tags": ["dawn", "emscripten"], "jsrepr": "'chromium-experimental-multi-draw-indirect'"},
- {"value": 53, "name": "dawn texel copy buffer row alignment", "tags": ["dawn"]},
- {"value": 54, "name": "flexible texture views", "tags": ["dawn"]},
- {"value": 55, "name": "chromium experimental subgroup matrix", "tags": ["dawn"]},
- {"value": 56, "name": "shared fence EGL sync", "tags": ["dawn", "native"]},
- {"value": 57, "name": "dawn device allocator control", "tags": ["dawn"]}
+ {"value": 51, "name": "dawn load resolve texture", "tags": ["dawn"]},
+ {"value": 52, "name": "dawn partial load resolve texture", "tags": ["dawn"]},
+ {"value": 53, "name": "multi draw indirect", "tags": ["dawn", "emscripten"], "jsrepr": "'chromium-experimental-multi-draw-indirect'"},
+ {"value": 54, "name": "dawn texel copy buffer row alignment", "tags": ["dawn"]},
+ {"value": 55, "name": "flexible texture views", "tags": ["dawn"]},
+ {"value": 56, "name": "chromium experimental subgroup matrix", "tags": ["dawn"]},
+ {"value": 57, "name": "shared fence EGL sync", "tags": ["dawn", "native"]},
+ {"value": 58, "name": "dawn device allocator control", "tags": ["dawn"]}
]
},
"filter mode": {
diff --git a/src/dawn/native/Adapter.cpp b/src/dawn/native/Adapter.cpp
index 6be0557..58b245b 100644
--- a/src/dawn/native/Adapter.cpp
+++ b/src/dawn/native/Adapter.cpp
@@ -337,6 +337,17 @@
DAWN_INVALID_IF(!result.success, "Invalid feature required: %s",
result.errorMessage.c_str());
}
+ // Validate features dependency.
+ // TODO(349125474): Decide if this validation is needed, see
+ // https://github.com/gpuweb/gpuweb/issues/4734 for detail.
+ if (requiredFeatureSet.count(wgpu::FeatureName::SubgroupsF16) > 0) {
+ DAWN_INVALID_IF((requiredFeatureSet.count(wgpu::FeatureName::Subgroups) == 0),
+ "Feature %s must be required together with feature %s.",
+ wgpu::FeatureName::SubgroupsF16, wgpu::FeatureName::Subgroups);
+ DAWN_INVALID_IF(requiredFeatureSet.count(wgpu::FeatureName::ShaderF16) == 0,
+ "Feature %s must be required together with feature %s.",
+ wgpu::FeatureName::SubgroupsF16, wgpu::FeatureName::ShaderF16);
+ }
if (descriptor->requiredLimits != nullptr) {
CombinedLimits requiredLimits;
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index 6c264ac..e6f0c63 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -1649,6 +1649,9 @@
if (mEnabledFeatures.IsEnabled(Feature::Subgroups)) {
mWGSLAllowedFeatures.extensions.insert(tint::wgsl::Extension::kSubgroups);
}
+ if (mEnabledFeatures.IsEnabled(Feature::SubgroupsF16)) {
+ mWGSLAllowedFeatures.extensions.insert(tint::wgsl::Extension::kSubgroupsF16);
+ }
if (IsToggleEnabled(Toggle::AllowUnsafeAPIs)) {
mWGSLAllowedFeatures.extensions.insert(
tint::wgsl::Extension::kChromiumDisableUniformityAnalysis);
diff --git a/src/dawn/native/Features.cpp b/src/dawn/native/Features.cpp
index 469f201..0698eb5 100644
--- a/src/dawn/native/Features.cpp
+++ b/src/dawn/native/Features.cpp
@@ -372,6 +372,10 @@
{"Supports the \"enable subgroups;\" directive in WGSL.",
"https://github.com/gpuweb/gpuweb/blob/main/proposals/subgroups.md",
FeatureInfo::FeatureState::Stable}},
+ {Feature::SubgroupsF16,
+ {"Supports the \"enable subgroups_f16;\" directive in WGSL (deprecated).",
+ "https://github.com/gpuweb/gpuweb/blob/main/proposals/subgroups.md",
+ FeatureInfo::FeatureState::Stable}},
{Feature::CoreFeaturesAndLimits,
{"Lifts all compatibility mode restrictions (features and limits) to core when enabled on a "
"device.",
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index 700c125..5058d86 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -175,9 +175,11 @@
// ShaderF16 features require DXC version being 1.4 or higher, shader model supporting 6.2 or
// higher, and native supporting F16 shader ops.
+ bool shaderF16Enabled = false;
if (GetBackend()->IsDXCAvailableAndVersionAtLeast(1, 4, 1, 4) &&
mDeviceInfo.highestSupportedShaderModel >= 62 && mDeviceInfo.supportsNative16BitShaderOps) {
EnableFeature(Feature::ShaderF16);
+ shaderF16Enabled = true;
}
// The function subgroupBroadcast(f16) fails for some edge cases on intel gen-9 devices.
@@ -186,6 +188,11 @@
// Subgroups feature requires SM >= 6.0 and capabilities flags.
if (!kForceDisableSubgroups && GetBackend()->IsDXCAvailable() && mDeviceInfo.supportsWaveOps) {
EnableFeature(Feature::Subgroups);
+ // D3D12 devices that support both native f16 and wave ops can support subgroups-f16.
+ // TODO(crbug.com/380244620): Remove when 'subgroups_f16' has been fully deprecated.
+ if (shaderF16Enabled) {
+ EnableFeature(Feature::SubgroupsF16);
+ }
}
D3D12_FEATURE_DATA_FORMAT_SUPPORT bgra8unormFormatInfo = {};
@@ -411,6 +418,7 @@
switch (feature) {
case wgpu::FeatureName::ShaderF16:
case wgpu::FeatureName::Subgroups:
+ case wgpu::FeatureName::SubgroupsF16:
return FeatureValidationResult(
absl::StrFormat("Feature %s requires DXC for D3D12.", feature));
default:
@@ -419,8 +427,9 @@
}
// Validate applied shader version.
switch (feature) {
- // The feature `shader-f16` requires using shader model 6.2 or higher.
- case wgpu::FeatureName::ShaderF16: {
+ // The feature `shader-f16` and `subgroups-f16` requires using shader model 6.2 or higher.
+ case wgpu::FeatureName::ShaderF16:
+ case wgpu::FeatureName::SubgroupsF16: {
if (!(GetAppliedShaderModelUnderToggles(toggles) >= 62)) {
return FeatureValidationResult(absl::StrFormat(
"Feature %s requires shader model 6.2 or higher for D3D12.", feature));
diff --git a/src/dawn/native/metal/PhysicalDeviceMTL.mm b/src/dawn/native/metal/PhysicalDeviceMTL.mm
index 8281b36..98f4525 100644
--- a/src/dawn/native/metal/PhysicalDeviceMTL.mm
+++ b/src/dawn/native/metal/PhysicalDeviceMTL.mm
@@ -676,6 +676,8 @@
if (!kForceDisableSubgroups && ([*mDevice supportsFamily:MTLGPUFamilyApple6] ||
[*mDevice supportsFamily:MTLGPUFamilyMac2])) {
EnableFeature(Feature::Subgroups);
+ // TODO(crbug.com/380244620) remove SubgroupsF16
+ EnableFeature(Feature::SubgroupsF16);
}
if ([*mDevice supportsFamily:MTLGPUFamilyApple7]) {
diff --git a/src/dawn/native/vulkan/DeviceVk.cpp b/src/dawn/native/vulkan/DeviceVk.cpp
index 9719550..34d2db2 100644
--- a/src/dawn/native/vulkan/DeviceVk.cpp
+++ b/src/dawn/native/vulkan/DeviceVk.cpp
@@ -532,9 +532,12 @@
}
// Set device feature for subgroups with f16 types.
- if (HasFeature(Feature::ShaderF16) && HasFeature(Feature::Subgroups)) {
+ if (HasFeature(Feature::SubgroupsF16) ||
+ (HasFeature(Feature::ShaderF16) && HasFeature(Feature::Subgroups))) {
DAWN_ASSERT(usedKnobs.HasExt(DeviceExt::ShaderSubgroupExtendedTypes) &&
- mDeviceInfo.shaderSubgroupExtendedTypes.shaderSubgroupExtendedTypes == VK_TRUE);
+ mDeviceInfo.shaderSubgroupExtendedTypes.shaderSubgroupExtendedTypes ==
+ VK_TRUE &&
+ HasFeature(Feature::ShaderF16) && HasFeature(Feature::Subgroups));
usedKnobs.shaderSubgroupExtendedTypes = mDeviceInfo.shaderSubgroupExtendedTypes;
featuresChain.Add(&usedKnobs.shaderSubgroupExtendedTypes);
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index 62e8bbc..a10620b 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -409,8 +409,7 @@
// and quad bits, and
// 4. VK_EXT_subgroup_size_control extension is valid, and both subgroupSizeControl
// and computeFullSubgroups is TRUE in VkPhysicalDeviceSubgroupSizeControlFeaturesEXT.
- const bool hasBaseSubgroupSupport =
- (mDeviceInfo.properties.apiVersion >= VK_API_VERSION_1_1) &&
+ if (!kForceDisableSubgroups && (mDeviceInfo.properties.apiVersion >= VK_API_VERSION_1_1) &&
(mDeviceInfo.subgroupProperties.supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) &&
(mDeviceInfo.subgroupProperties.supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) &&
(mDeviceInfo.subgroupProperties.supportedOperations & VK_SUBGROUP_FEATURE_BASIC_BIT) &&
@@ -422,18 +421,26 @@
(mDeviceInfo.subgroupProperties.supportedOperations & VK_SUBGROUP_FEATURE_QUAD_BIT) &&
(mDeviceInfo.HasExt(DeviceExt::SubgroupSizeControl)) &&
(mDeviceInfo.subgroupSizeControlFeatures.subgroupSizeControl == VK_TRUE) &&
- (mDeviceInfo.subgroupSizeControlFeatures.computeFullSubgroups == VK_TRUE);
-
- // If shader f16 is enabled we only enable subgroups if we extended subgroup support.
- // This means there is a vary narrow number of devices (~4%) will not get subgroup
- // support due to the fact that they support shader f16 but not actually f16
- // operations in subgroups.
- const bool hasRequiredF16Support =
- !shaderF16Enabled ||
- (mDeviceInfo.shaderSubgroupExtendedTypes.shaderSubgroupExtendedTypes == VK_TRUE);
-
- if (!kForceDisableSubgroups && hasBaseSubgroupSupport && hasRequiredF16Support) {
- EnableFeature(Feature::Subgroups);
+ (mDeviceInfo.subgroupSizeControlFeatures.computeFullSubgroups == VK_TRUE)) {
+ if (shaderF16Enabled) {
+ if (mDeviceInfo.shaderSubgroupExtendedTypes.shaderSubgroupExtendedTypes == VK_TRUE) {
+ // Enable SubgroupsF16 feature if:
+ // 1. Subgroups feature is enabled, and
+ // 2. ShaderF16 feature is enabled, and
+ // 3. shaderSubgroupExtendedTypes is TRUE in
+ // VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR.
+ // TODO(crbug.com/380244620): Remove when 'subgroups_f16' has been fully deprecated.
+ EnableFeature(Feature::SubgroupsF16);
+ // If shader f16 is enable we only enable subgroups if we extended subgroup support.
+ // This means there is a vary narrow number of devices (~4%) will not get subgroup
+ // support due to the fact that they support shader f16 but not actually f16
+ // operations in subgroups.
+ EnableFeature(Feature::Subgroups);
+ }
+ } else {
+ // Subgroups without extended type support (f16).
+ EnableFeature(Feature::Subgroups);
+ }
}
// Enable subgroup matrix if all of the following are true:
diff --git a/src/dawn/node/binding/Converter.cpp b/src/dawn/node/binding/Converter.cpp
index 3b5e852..23e5463 100644
--- a/src/dawn/node/binding/Converter.cpp
+++ b/src/dawn/node/binding/Converter.cpp
@@ -1621,6 +1621,7 @@
case wgpu::FeatureName::SharedTextureMemoryVkDedicatedAllocation:
case wgpu::FeatureName::SharedTextureMemoryZirconHandle:
case wgpu::FeatureName::StaticSamplers:
+ case wgpu::FeatureName::SubgroupsF16:
case wgpu::FeatureName::TextureCompressionBCSliced3D:
case wgpu::FeatureName::TextureCompressionASTCSliced3D:
case wgpu::FeatureName::TransientAttachments:
diff --git a/src/dawn/tests/end2end/SubgroupsTests.cpp b/src/dawn/tests/end2end/SubgroupsTests.cpp
index e8b0423..620f320 100644
--- a/src/dawn/tests/end2end/SubgroupsTests.cpp
+++ b/src/dawn/tests/end2end/SubgroupsTests.cpp
@@ -196,6 +196,16 @@
mRequiredSubgroupsFeature = true;
requiredFeatures.push_back(wgpu::FeatureName::Subgroups);
}
+ if (SupportsFeatures({wgpu::FeatureName::SubgroupsF16})) {
+ // SubgroupsF16 feature could be supported only if ShaderF16 and Subgroups features
+ // are also supported.
+ DAWN_ASSERT(mRequiredShaderF16Feature && mRequiredSubgroupsFeature);
+ mRequiredSubgroupsF16Feature = true;
+ requiredFeatures.push_back(wgpu::FeatureName::SubgroupsF16);
+ }
+
+ mSubgroupsF16SupportedByBackend = SupportsFeatures({wgpu::FeatureName::SubgroupsF16});
+
return requiredFeatures;
}
@@ -207,15 +217,23 @@
if (mRequiredSubgroupsFeature) {
code << "enable subgroups;";
}
+ if (mRequiredSubgroupsF16Feature) {
+ code << "enable subgroups_f16;";
+ }
return code;
}
bool IsShaderF16EnabledInWGSL() const { return mRequiredShaderF16Feature; }
bool IsSubgroupsEnabledInWGSL() const { return mRequiredSubgroupsFeature; }
+ bool IsSubgroupsF16EnabledInWGSL() const { return mRequiredSubgroupsF16Feature; }
+ bool IsSubgroupsF16SupportedByBackend() const { return mSubgroupsF16SupportedByBackend; }
private:
bool mRequiredShaderF16Feature = false;
bool mRequiredSubgroupsFeature = false;
+ bool mRequiredSubgroupsF16Feature = false;
+ // Indicates that backend actually supports using subgroups functions with f16 types.
+ bool mSubgroupsF16SupportedByBackend = false;
};
class SubgroupsShaderTests : public SubgroupsTestsBase<AdapterTestParam> {
@@ -696,9 +714,12 @@
// and 256. Note that although we assume invocation 0 of the workgroup has a subgroup_id of 0 in its
// subgroup, we don't assume any other particular subgroups layout property.
TEST_P(SubgroupsBroadcastTests, SubgroupBroadcast) {
- DAWN_TEST_UNSUPPORTED_IF(!IsSubgroupsEnabledInWGSL());
if (GetParam().mBroadcastType == BroadcastType::F16) {
- DAWN_TEST_UNSUPPORTED_IF(!IsShaderF16EnabledInWGSL());
+ DAWN_TEST_UNSUPPORTED_IF(!IsSubgroupsF16SupportedByBackend());
+ DAWN_ASSERT(IsShaderF16EnabledInWGSL() && IsSubgroupsEnabledInWGSL() &&
+ IsSubgroupsF16EnabledInWGSL());
+ } else {
+ DAWN_TEST_UNSUPPORTED_IF(!IsSubgroupsEnabledInWGSL());
}
for (uint32_t workgroupSize : {1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128, 255, 256}) {
@@ -886,9 +907,8 @@
};
TEST_P(SubgroupsShaderInclusiveTest, InclusiveExecution) {
- DAWN_TEST_UNSUPPORTED_IF(!IsSubgroupsEnabledInWGSL());
if (GetParam().mSubgroupOpDataType == SubgroupOpDataType::F16) {
- DAWN_TEST_UNSUPPORTED_IF(!IsShaderF16EnabledInWGSL());
+ DAWN_TEST_UNSUPPORTED_IF(!IsSubgroupsF16SupportedByBackend());
// TODO(361330160): The f16 implementation does not seem produce correct values in
// execution. It is not clear if this is due to something wrong with the polyfill or the
@@ -899,6 +919,11 @@
// TODO(361330160): Also fails on MacBookPro16,1 with AMD Radeon Pro 5300M
DAWN_SUPPRESS_TEST_IF(gpu_info::IsAMDRDNA1(GetParam().adapterProperties.vendorID,
GetParam().adapterProperties.deviceID));
+
+ DAWN_ASSERT(IsShaderF16EnabledInWGSL() && IsSubgroupsEnabledInWGSL() &&
+ IsSubgroupsF16EnabledInWGSL());
+ } else {
+ DAWN_TEST_UNSUPPORTED_IF(!IsSubgroupsEnabledInWGSL());
}
for (uint32_t workgroupSize : {1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 127, 128, 255, 256}) {
diff --git a/src/dawn/tests/perf_tests/MatrixVectorMultiplyPerf.cpp b/src/dawn/tests/perf_tests/MatrixVectorMultiplyPerf.cpp
index 3d18958..dfba797 100644
--- a/src/dawn/tests/perf_tests/MatrixVectorMultiplyPerf.cpp
+++ b/src/dawn/tests/perf_tests/MatrixVectorMultiplyPerf.cpp
@@ -98,6 +98,7 @@
std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
mUsingF16 = false;
mUsingSubgroups = false;
+ mUsingSubgroupsF16 = false;
mAllFeaturesSupported = true;
auto requirements =
@@ -116,6 +117,10 @@
if (GetParam().mImpl == KernelImplementation::Subgroup) {
mUsingSubgroups = true;
requireFeature(wgpu::FeatureName::Subgroups);
+ if (mUsingF16) {
+ mUsingSubgroupsF16 = true;
+ requireFeature(wgpu::FeatureName::SubgroupsF16);
+ }
}
return requirements;
}
@@ -148,6 +153,7 @@
bool mUsingF16;
bool mUsingSubgroups;
+ bool mUsingSubgroupsF16;
bool mAllFeaturesSupported;
};
@@ -171,7 +177,7 @@
DAWN_TEST_UNSUPPORTED_IF(!mAllFeaturesSupported);
// D3D12 device must be using DXC to support subgroups feature.
- DAWN_ASSERT(!mUsingSubgroups || !IsD3D12() || IsDXC());
+ DAWN_ASSERT(!(mUsingSubgroups || mUsingSubgroupsF16) || !IsD3D12() || IsDXC());
wgpu::BufferDescriptor bufferDesc;
bufferDesc.usage = wgpu::BufferUsage::Storage;
diff --git a/src/dawn/tests/unittests/FeatureTests.cpp b/src/dawn/tests/unittests/FeatureTests.cpp
index 3770ca5..293fcab 100644
--- a/src/dawn/tests/unittests/FeatureTests.cpp
+++ b/src/dawn/tests/unittests/FeatureTests.cpp
@@ -123,7 +123,13 @@
// For a given feature, returns a set containing the feature and its depending features if any to
// ensure creating device with these features can success
std::unordered_set<wgpu::FeatureName> FeatureAndDependenciesSet(wgpu::FeatureName feature) {
- return {feature};
+ switch (feature) {
+ case wgpu::FeatureName::SubgroupsF16:
+ return {wgpu::FeatureName::SubgroupsF16, wgpu::FeatureName::ShaderF16,
+ wgpu::FeatureName::Subgroups};
+ default:
+ return {feature};
+ }
}
bool IsExperimental(wgpu::FeatureName feature) {
diff --git a/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp b/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp
index a3f34bd..83114fb 100644
--- a/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/DeviceValidationTests.cpp
@@ -224,6 +224,62 @@
mRequestDeviceCallback.Callback());
}
+// Test that it is an error to request limits with an invalid chained struct
+TEST_F(RequestDeviceValidationTest, InvalidChainedStruct) {
+ wgpu::ChainedStructOut chain = {};
+ wgpu::Limits limits = {};
+ limits.nextInChain = &chain;
+
+ wgpu::DeviceDescriptor descriptor;
+ descriptor.requiredLimits = &limits;
+ EXPECT_CALL(mRequestDeviceCallback,
+ Call(wgpu::RequestDeviceStatus::Error, IsNull(), NonEmptySizedString()))
+ .Times(1);
+ adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
+ mRequestDeviceCallback.Callback());
+}
+
+// Test that requiring subroups-f16 feature requires subgroups and shader-f16 features as well
+// TODO(349125474): Decide if this validation is needed, see
+// https://github.com/gpuweb/gpuweb/issues/4734 for detail.
+TEST_F(RequestDeviceValidationTest, SubgroupsF16FeatureDependency) {
+ for (bool requireShaderF16 : {false, true}) {
+ for (bool requireSubgroups : {false, true}) {
+ std::vector<wgpu::FeatureName> features;
+ if (requireShaderF16) {
+ features.push_back(wgpu::FeatureName::ShaderF16);
+ }
+ if (requireSubgroups) {
+ features.push_back(wgpu::FeatureName::Subgroups);
+ }
+ features.push_back(wgpu::FeatureName::SubgroupsF16);
+
+ wgpu::DeviceDescriptor descriptor;
+ descriptor.requiredFeatureCount = features.size();
+ descriptor.requiredFeatures = features.data();
+
+ // Device request with subgroups-f16 feature can only success if shader-f16 feature
+ // and subgroups features are required as well.
+ const bool isSuccess = requireSubgroups && requireShaderF16;
+
+ if (isSuccess) {
+ EXPECT_CALL(mRequestDeviceCallback,
+ Call(wgpu::RequestDeviceStatus::Success, NotNull(), EmptySizedString()))
+ .Times(1);
+ } else {
+ EXPECT_CALL(mRequestDeviceCallback,
+ Call(wgpu::RequestDeviceStatus::Error, IsNull(), NonEmptySizedString()))
+ .Times(1);
+ }
+
+ EXPECT_DEPRECATION_WARNINGS(
+ adapter.RequestDevice(&descriptor, wgpu::CallbackMode::AllowSpontaneous,
+ mRequestDeviceCallback.Callback()),
+ GetDeviceCreationDeprecationWarningExpectation(descriptor));
+ }
+ }
+}
+
class DeviceTickValidationTest : public ValidationTest {};
// Device destroy before API-level Tick should always result in no-op and false.
diff --git a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
index 1962f85..8f8658b 100644
--- a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
@@ -822,6 +822,7 @@
{"clip_distances", false, {"clip-distances"}, {}},
{"dual_source_blending", false, {"dual-source-blending"}, {}},
{"subgroups", false, {"subgroups"}, {}},
+ {"subgroups_f16", false, {"shader-f16", "subgroups", "subgroups-f16"}, {"f16", "subgroups"}},
{"chromium_experimental_pixel_local", true, {"pixel-local-storage-coherent"}, {}},
{"chromium_disable_uniformity_analysis", true, {}, {}},
{"chromium_internal_graphite", true, {}, {}},
diff --git a/src/dawn/wire/SupportedFeatures.cpp b/src/dawn/wire/SupportedFeatures.cpp
index 3786b3e..19da897 100644
--- a/src/dawn/wire/SupportedFeatures.cpp
+++ b/src/dawn/wire/SupportedFeatures.cpp
@@ -112,6 +112,7 @@
case WGPUFeatureName_DawnLoadResolveTexture:
case WGPUFeatureName_DawnPartialLoadResolveTexture:
case WGPUFeatureName_Subgroups:
+ case WGPUFeatureName_SubgroupsF16:
case WGPUFeatureName_ClipDistances:
case WGPUFeatureName_ChromiumExperimentalImmediateData:
case WGPUFeatureName_DawnTexelCopyBufferRowAlignment:
diff --git a/src/tint/cmd/bench/BUILD.bazel b/src/tint/cmd/bench/BUILD.bazel
index 816c8a6..358ae92 100644
--- a/src/tint/cmd/bench/BUILD.bazel
+++ b/src/tint/cmd/bench/BUILD.bazel
@@ -99,6 +99,7 @@
"//src/tint/lang/wgsl/ast",
"//src/tint/lang/wgsl/program",
"//src/tint/lang/wgsl/sem",
+ "//src/tint/lang/wgsl:bench",
"//src/tint/utils",
"//src/tint/utils/containers",
"//src/tint/utils/diagnostic",
diff --git a/src/tint/cmd/bench/BUILD.cmake b/src/tint/cmd/bench/BUILD.cmake
index 4dc16d6..470a020 100644
--- a/src/tint/cmd/bench/BUILD.cmake
+++ b/src/tint/cmd/bench/BUILD.cmake
@@ -58,6 +58,7 @@
tint_lang_wgsl_ast
tint_lang_wgsl_program
tint_lang_wgsl_sem
+ tint_lang_wgsl_bench
tint_utils
tint_utils_containers
tint_utils_diagnostic
diff --git a/src/tint/cmd/bench/BUILD.gn b/src/tint/cmd/bench/BUILD.gn
index 35ca535..0594f4a 100644
--- a/src/tint/cmd/bench/BUILD.gn
+++ b/src/tint/cmd/bench/BUILD.gn
@@ -104,6 +104,7 @@
"${tint_src_dir}/lang/core/constant",
"${tint_src_dir}/lang/core/type",
"${tint_src_dir}/lang/wgsl",
+ "${tint_src_dir}/lang/wgsl:bench",
"${tint_src_dir}/lang/wgsl/ast",
"${tint_src_dir}/lang/wgsl/program",
"${tint_src_dir}/lang/wgsl/sem",
diff --git a/src/tint/cmd/bench/extension_bench.cc b/src/tint/cmd/bench/extension_bench.cc
index ed317c7..f56cff5 100644
--- a/src/tint/cmd/bench/extension_bench.cc
+++ b/src/tint/cmd/bench/extension_bench.cc
@@ -122,6 +122,13 @@
"subgr6u33O",
"s96grQttupoo",
"sugro66ps",
+ "ubgrxupszzO166",
+ "suyygroups_f16",
+ "sHHbgroups_Z",
+ "subgroups_f16",
+ "ubgWWou44q_f16",
+ "sOObgroup_f16",
+ "suboruph_Y16",
};
for (auto _ : state) {
for (auto* str : kStrings) {
diff --git a/src/tint/cmd/fuzz/wgsl/dictionary.txt b/src/tint/cmd/fuzz/wgsl/dictionary.txt
index 85d3eef..39ff80a 100644
--- a/src/tint/cmd/fuzz/wgsl/dictionary.txt
+++ b/src/tint/cmd/fuzz/wgsl/dictionary.txt
@@ -421,6 +421,7 @@
"subgroup_size"
"subgroup_uniformity"
"subgroups"
+"subgroups_f16"
"switch"
"tan"
"tanh"
diff --git a/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
index d9caefe..fb7b7df 100644
--- a/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
@@ -554,6 +554,7 @@
wgsl::Extension::kF16,
wgsl::Extension::kDualSourceBlending,
wgsl::Extension::kSubgroups,
+ wgsl::Extension::kSubgroupsF16,
})) {
return false;
}
diff --git a/src/tint/lang/wgsl/BUILD.bazel b/src/tint/lang/wgsl/BUILD.bazel
index ab45c5d..bf28d37 100644
--- a/src/tint/lang/wgsl/BUILD.bazel
+++ b/src/tint/lang/wgsl/BUILD.bazel
@@ -133,6 +133,26 @@
copts = COPTS,
visibility = ["//visibility:public"],
)
+cc_library(
+ name = "bench",
+ alwayslink = True,
+ srcs = [
+ "extension_bench.cc",
+ ],
+ deps = [
+ "//src/tint/lang/wgsl",
+ "//src/tint/utils/containers",
+ "//src/tint/utils/ice",
+ "//src/tint/utils/macros",
+ "//src/tint/utils/math",
+ "//src/tint/utils/memory",
+ "//src/tint/utils/rtti",
+ "@benchmark",
+ "//src/utils",
+ ],
+ copts = COPTS,
+ visibility = ["//visibility:public"],
+)
alias(
name = "tint_build_wgsl_reader",
diff --git a/src/tint/lang/wgsl/BUILD.cmake b/src/tint/lang/wgsl/BUILD.cmake
index c4baf01..cfa73cc 100644
--- a/src/tint/lang/wgsl/BUILD.cmake
+++ b/src/tint/lang/wgsl/BUILD.cmake
@@ -143,3 +143,26 @@
tint_lang_wgsl_writer
)
endif(TINT_BUILD_WGSL_WRITER)
+
+################################################################################
+# Target: tint_lang_wgsl_bench
+# Kind: bench
+################################################################################
+tint_add_target(tint_lang_wgsl_bench bench
+ lang/wgsl/extension_bench.cc
+)
+
+tint_target_add_dependencies(tint_lang_wgsl_bench bench
+ tint_lang_wgsl
+ tint_utils_containers
+ tint_utils_ice
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_rtti
+)
+
+tint_target_add_external_dependencies(tint_lang_wgsl_bench bench
+ "google-benchmark"
+ "src_utils"
+)
diff --git a/src/tint/lang/wgsl/BUILD.gn b/src/tint/lang/wgsl/BUILD.gn
index 3e27659..d993a9d 100644
--- a/src/tint/lang/wgsl/BUILD.gn
+++ b/src/tint/lang/wgsl/BUILD.gn
@@ -126,3 +126,19 @@
}
}
}
+if (tint_build_benchmarks) {
+ tint_benchmarks_source_set("bench") {
+ sources = [ "extension_bench.cc" ]
+ deps = [
+ "${dawn_root}/src/utils:utils",
+ "${tint_src_dir}:google_benchmark",
+ "${tint_src_dir}/lang/wgsl",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/ice",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/math",
+ "${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/rtti",
+ ]
+ }
+}
diff --git a/src/tint/lang/wgsl/extension.cc b/src/tint/lang/wgsl/extension.cc
index 06c9696..c3cd9ca 100644
--- a/src/tint/lang/wgsl/extension.cc
+++ b/src/tint/lang/wgsl/extension.cc
@@ -75,6 +75,9 @@
if (str == "subgroups") {
return Extension::kSubgroups;
}
+ if (str == "subgroups_f16") {
+ return Extension::kSubgroupsF16;
+ }
return Extension::kUndefined;
}
@@ -104,6 +107,8 @@
return "f16";
case Extension::kSubgroups:
return "subgroups";
+ case Extension::kSubgroupsF16:
+ return "subgroups_f16";
}
return "<unknown>";
}
diff --git a/src/tint/lang/wgsl/extension.h b/src/tint/lang/wgsl/extension.h
index 46f6d3c..771bfc5 100644
--- a/src/tint/lang/wgsl/extension.h
+++ b/src/tint/lang/wgsl/extension.h
@@ -57,6 +57,7 @@
kDualSourceBlending,
kF16,
kSubgroups,
+ kSubgroupsF16,
};
/// @param value the enum value
@@ -88,6 +89,7 @@
"dual_source_blending",
"f16",
"subgroups",
+ "subgroups_f16",
};
/// All extensions
@@ -103,6 +105,7 @@
Extension::kDualSourceBlending,
Extension::kF16,
Extension::kSubgroups,
+ Extension::kSubgroupsF16,
};
/// A unique vector of extensions
diff --git a/src/tint/lang/wgsl/extension_bench.cc b/src/tint/lang/wgsl/extension_bench.cc
new file mode 100644
index 0000000..2f8861d
--- /dev/null
+++ b/src/tint/lang/wgsl/extension_bench.cc
@@ -0,0 +1,151 @@
+// Copyright 2022 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by 'tools/src/cmd/gen' using the template:
+// src/tint/lang/wgsl/extension_bench.cc.tmpl
+//
+// To regenerate run: './tools/run gen'
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/lang/wgsl/extension.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::wgsl {
+namespace {
+
+void ExtensionParser(::benchmark::State& state) {
+ const char* kStrings[] = {
+ "chromium_disableuniformiccy_analysis",
+ "chromil3_disable_unifority_analss",
+ "chromium_disable_Vniformity_analysis",
+ "chromium_disable_uniformity_analysis",
+ "chromium_dis1ble_uniformity_analysis",
+ "chromium_qqisable_unifomity_anaJysis",
+ "chrollium_disable_uniformity_analysi77",
+ "cqqromium_eppperimental_framebuffe_fetcHH",
+ "chrmium_experimvntal_frcmebufer_ftch",
+ "chromium_expebimental_framGbufer_fetch",
+ "chromium_experimental_framebuffer_fetch",
+ "chromium_experimental_vramebuffeii_fetch",
+ "chro8WWum_experimental_framebuffer_fetch",
+ "chromium_eperimenxxMl_framebuffer_fetch",
+ "chromum_experimental_pixeX_loggal",
+ "chromium_expVrXmntal_ixel_local",
+ "3hromium_experimental_pixel_local",
+ "chromium_experimental_pixel_local",
+ "chromium_eEperimental_pixel_local",
+ "chTTomiu_experimentaPP_pixel_local",
+ "cxxromium_expddrimenal_pixel_local",
+ "c44romium_experimental_push_constant",
+ "chromium_experimental_pSSsVV_constant",
+ "chrom22Rm_experimental_pushRonstant",
+ "chromium_experimental_push_constant",
+ "chromium_exp9rimFntal_ush_constant",
+ "chrmium_experimental_push_constant",
+ "cOOromium_experiVeHtal_puh_conRRtant",
+ "chromium_eyperimental_subgoup_matrix",
+ "Ghromium_experrim77nllal_subgnnoup_matrix",
+ "ch4omium_experimental00subgroup_matrix",
+ "chromium_experimental_subgroup_matrix",
+ "chromium_exeimoontal_subgroup_atrix",
+ "chromium_experimnal_subgroup_mazzrix",
+ "chro11ium_experienial_subgrppup_matrix",
+ "chXXomium_internal_graphite",
+ "chromi55m_internnal_gra99hiIIe",
+ "chSSomiuY_internal_aarHHphrrte",
+ "chromium_internal_graphite",
+ "kkhromium_nternal_rahHte",
+ "chromium_nRegnaj_graphite",
+ "chromium_ntebnal_gaphite",
+ "chromium_internal_input_atjachments",
+ "chromium_internal_inpt_attachments",
+ "chromium_nteral_iqput_attachments",
+ "chromium_internal_input_attachments",
+ "chromium_internal_input_aNNtachents",
+ "chromium_internalinpt_attavvhments",
+ "chromium_internal_inut_attacQQments",
+ "chromirm_intenal_rfflaxed_unifrm_layout",
+ "chromium_internal_jelaxed_uniform_layout",
+ "chromium_interna_relNNxed_uwwiform_lay82t",
+ "chromium_internal_relaxed_uniform_layout",
+ "chromium_internal_relaxed_uniform_layut",
+ "chromium_internal_relaxed_rrniform_layout",
+ "chromium_internal_relaxedGuniform_layout",
+ "clip_distanceFF",
+ "cEipdtances",
+ "cli_rristances",
+ "clip_distances",
+ "lip_distanes",
+ "DXp_diJJtances",
+ "cl8pdistane",
+ "dul_okrc_blen11ing",
+ "dua_source_blending",
+ "duJl_source_blendig",
+ "dual_source_blending",
+ "dual_source_clending",
+ "dual_sOurce_blending",
+ "dualKKs__urce_blttvnding",
+ "xx8",
+ "__F",
+ "f1q",
+ "f16",
+ "331O",
+ "ftt6QQ",
+ "666",
+ "zzxbO6rops",
+ "subgyyoups",
+ "HHugroZs",
+ "subgroups",
+ "sWW44roupq",
+ "sOObgoups",
+ "sbgroYps",
+ "subroups_f",
+ "suFgoups_f16",
+ "subgowps_f16",
+ "subgroups_f16",
+ "suffgKups_f6",
+ "KKubgroqps_f16",
+ "subFroup3mmf16",
+ };
+ for (auto _ : state) {
+ for (auto* str : kStrings) {
+ auto result = ParseExtension(str);
+ benchmark::DoNotOptimize(result);
+ }
+ }
+} // NOLINT(readability/fn_size)
+
+BENCHMARK(ExtensionParser);
+
+} // namespace
+} // namespace tint::wgsl
diff --git a/src/tint/lang/wgsl/extension_test.cc b/src/tint/lang/wgsl/extension_test.cc
index 9434d4f..7bc4fa3 100644
--- a/src/tint/lang/wgsl/extension_test.cc
+++ b/src/tint/lang/wgsl/extension_test.cc
@@ -68,6 +68,7 @@
{"dual_source_blending", Extension::kDualSourceBlending},
{"f16", Extension::kF16},
{"subgroups", Extension::kSubgroups},
+ {"subgroups_f16", Extension::kSubgroupsF16},
};
static constexpr Case kInvalidCases[] = {
@@ -104,6 +105,9 @@
{"skkkgroups", Extension::kUndefined},
{"siibgrop", Extension::kUndefined},
{"subgroupXX", Extension::kUndefined},
+ {"subII9rnn55ps_f16", Extension::kUndefined},
+ {"YubHHrouaas_SSr16", Extension::kUndefined},
+ {"subgupkkHf1", Extension::kUndefined},
};
using ExtensionParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc b/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
index 5c72205..8080b15 100644
--- a/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
@@ -175,7 +175,7 @@
// Error when unknown extension found
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups')");
+Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups', 'subgroups_f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -189,7 +189,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
Did you mean 'f16'?
-Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups')");
+Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups', 'subgroups_f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -203,7 +203,7 @@
// Error when unknown extension found
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_framebuffer_fetch', 'chromium_experimental_pixel_local', 'chromium_experimental_push_constant', 'chromium_experimental_subgroup_matrix', 'chromium_internal_graphite', 'chromium_internal_input_attachments', 'clip_distances', 'dual_source_blending', 'f16', 'subgroups')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_framebuffer_fetch', 'chromium_experimental_pixel_local', 'chromium_experimental_push_constant', 'chromium_experimental_subgroup_matrix', 'chromium_internal_graphite', 'chromium_internal_input_attachments', 'clip_distances', 'dual_source_blending', 'f16', 'subgroups', 'subgroups_f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -251,7 +251,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups')");
+Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups', 'subgroups_f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -262,7 +262,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups')");
+Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups', 'subgroups_f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -274,7 +274,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
Did you mean 'f16'?
-Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups')");
+Possible values: 'clip_distances', 'dual_source_blending', 'f16', 'subgroups', 'subgroups_f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
diff --git a/src/tint/lang/wgsl/resolver/builtin_validation_test.cc b/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
index 9b82b58..0b603a0 100644
--- a/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/builtin_validation_test.cc
@@ -987,7 +987,7 @@
EXPECT_TRUE(r()->Resolve());
}
-TEST_F(ResolverBuiltinValidationTest, SubgroupBroadcastWithExtension_F16) {
+TEST_F(ResolverBuiltinValidationTest, SubgroupBroadcastWithoutSubgroupsF16Extension_F16) {
// enable f16;
// enable subgroups;
// fn func -> f16 { return subgroupBroadcast(1.h,0); }
@@ -1016,6 +1016,7 @@
}
TEST_F(ResolverBuiltinValidationTest, SubgroupBroadcastWithoutShaderF16Extension_F16) {
+ // enable f16;
// fn func -> f16 { return subgroupBroadcast(1.h,0); }
Enable(wgsl::Extension::kSubgroups);
Func("func", tint::Empty, ty.f16(),
@@ -1026,6 +1027,39 @@
EXPECT_EQ(r()->error(), R"(error: 'f16' type used without 'f16' extension enabled)");
}
+TEST_F(ResolverBuiltinValidationTest, SubgroupBroadcastWithSubgroupsF16WithoutShaderF16Extension) {
+ // enable f16;
+ // fn func -> f16 { return subgroupBroadcast(1.h,0); }
+ Enable(wgsl::Extension::kSubgroups);
+ Enable(wgsl::Extension::kSubgroupsF16);
+ Func("func", tint::Empty, ty.f16(),
+ Vector{
+ Return(Call(Source{{12, 34}}, "subgroupBroadcast", 1_h, 0_u)),
+ });
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(error: 'f16' type used without 'f16' extension enabled
+error: extension 'subgroups_f16' cannot be used without extension 'f16')");
+}
+
+TEST_F(ResolverBuiltinValidationTest, SubgroupBroadcastWithExtensions_F16) {
+ // enable f16;
+ // enable subgroups;
+ // enable subgroups_f16;
+ // fn func -> f16 { return subgroupBroadcast(1.h,0); }
+ Enable(wgsl::Extension::kF16);
+ Enable(wgsl::Extension::kSubgroups);
+ // TODO(crbug.com/380244620): Remove when 'subgroups_f16' has been fully deprecated.
+ Enable(wgsl::Extension::kSubgroupsF16);
+
+ Func("func", tint::Empty, ty.f16(),
+ Vector{
+ Return(Call("subgroupBroadcast", 1_h, 0_u)),
+ });
+
+ EXPECT_TRUE(r()->Resolve());
+}
+
TEST_F(ResolverBuiltinValidationTest, SubgroupBroadcastWithoutExtension_VecF16) {
// enable f16;
// enable subgroups;
@@ -1040,12 +1074,15 @@
EXPECT_TRUE(r()->Resolve());
}
-TEST_F(ResolverBuiltinValidationTest, SubgroupBroadcastWithExtension_VecF16) {
+TEST_F(ResolverBuiltinValidationTest, SubgroupBroadcastWithExtensions_VecF16) {
// enable f16;
// enable subgroups;
+ // enable subgroups_f16;
// fn func -> vec4<f16> { return subgroupBroadcast(vec4(1.h),0); }
Enable(wgsl::Extension::kF16);
Enable(wgsl::Extension::kSubgroups);
+ // TODO(crbug.com/380244620): Remove when 'subgroups_f16' has been fully deprecated.
+ Enable(wgsl::Extension::kSubgroupsF16);
Func("func", tint::Empty, ty.vec4<f16>(),
Vector{
diff --git a/src/tint/lang/wgsl/resolver/subgroups_extension_test.cc b/src/tint/lang/wgsl/resolver/subgroups_extension_test.cc
index 440633f..3fa8e4d 100644
--- a/src/tint/lang/wgsl/resolver/subgroups_extension_test.cc
+++ b/src/tint/lang/wgsl/resolver/subgroups_extension_test.cc
@@ -38,6 +38,26 @@
using ResolverSubgroupsExtensionTest = ResolverTest;
+// Enabling subgroups_f16 without enabling subgroups should fail.
+TEST_F(ResolverSubgroupsExtensionTest, UseSubgroupsF16WithoutSubgroups) {
+ Enable(wgsl::Extension::kF16);
+ Enable(wgsl::Extension::kSubgroupsF16);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(error: extension 'subgroups_f16' cannot be used without extension 'subgroups')");
+}
+
+// Enabling subgroups_f16 without enabling f16 should fail.
+TEST_F(ResolverSubgroupsExtensionTest, UseSubgroupsF16WithoutF16) {
+ Enable(wgsl::Extension::kSubgroups);
+ Enable(wgsl::Extension::kSubgroupsF16);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ R"(error: extension 'subgroups_f16' cannot be used without extension 'f16')");
+}
+
// Using a subgroup_size builtin attribute without subgroups enabled should fail.
TEST_F(ResolverSubgroupsExtensionTest, UseSubgroupSizeAttribWithoutExtensionError) {
Structure("Inputs",
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index eaa3576..8a05a68 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -286,6 +286,21 @@
}
}
+ if (enabled_extensions_.Contains(wgsl::Extension::kSubgroupsF16)) {
+ if (!enabled_extensions_.Contains(wgsl::Extension::kSubgroups)) {
+ AddError(source_of(wgsl::Extension::kSubgroupsF16))
+ << "extension " << style::Code("subgroups_f16")
+ << " cannot be used without extension " << style::Code("subgroups");
+ return false;
+ }
+ if (!enabled_extensions_.Contains(wgsl::Extension::kF16)) {
+ AddError(source_of(wgsl::Extension::kSubgroupsF16))
+ << "extension " << style::Code("subgroups_f16")
+ << " cannot be used without extension " << style::Code("f16");
+ return false;
+ }
+ }
+
return true;
}
diff --git a/src/tint/lang/wgsl/wgsl.def b/src/tint/lang/wgsl/wgsl.def
index 2bd1e29..257c4b0 100644
--- a/src/tint/lang/wgsl/wgsl.def
+++ b/src/tint/lang/wgsl/wgsl.def
@@ -79,6 +79,8 @@
dual_source_blending
// WGSL Extension "subgroups"
subgroups
+ // WGSL Extension "subgroups_f16"
+ subgroups_f16
// A Chromium-specific extension for disabling uniformity analysis.
chromium_disable_uniformity_analysis
diff --git a/test/tint/builtins/gen/gen.wgsl.tmpl b/test/tint/builtins/gen/gen.wgsl.tmpl
index 798f45d..34ff24a 100644
--- a/test/tint/builtins/gen/gen.wgsl.tmpl
+++ b/test/tint/builtins/gen/gen.wgsl.tmpl
@@ -297,7 +297,7 @@
{{- /* Emit 'enable chromium_experimental_subgroup_matrix' if required */ -}}
{{- if (HasPrefix $builtin_name "subgroupMatrix")}}
enable chromium_experimental_subgroup_matrix;
-{{/* Emit 'enable subgroups' if required */ -}}
+{{/* Emit 'enable subgroups' and 'enable subgroups_f16' if required */ -}}
{{- else if or (HasPrefix $builtin_name "subgroup") (HasPrefix $builtin_name "quad")}}
enable subgroups;
{{ end -}}