Skip to content

Commit

Permalink
Separate subgroup feature into one flag per shader stage
Browse files Browse the repository at this point in the history
  • Loading branch information
exrook committed Oct 24, 2023
1 parent 24926f2 commit 184522d
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 38 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ By @teoxoy in [#4185](https://github.com/gfx-rs/wgpu/pull/4185)

- Re-export Naga. By @exrook in [#4172](https://github.com/gfx-rs/wgpu/pull/4172)
- Add WinUI 3 SwapChainPanel support. By @ddrboxman in [#4191](https://github.com/gfx-rs/wgpu/pull/4191)
- Add `SUBGROUP_OPERATIONS` feature. By @exrook and @lichtso in [#4240](https://github.com/gfx-rs/wgpu/pull/4240)
- Add `SUBGROUP_COMPUTE, SUBGROUP_FRAGMENT, SUBGROUP_VERTEX` features. By @exrook and @lichtso in [#4240](https://github.com/gfx-rs/wgpu/pull/4240)

### Changes

Expand Down
2 changes: 1 addition & 1 deletion tests/tests/subgroup_operations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const THREAD_COUNT: u64 = 128;
static SUBGROUP_OPERATIONS: GpuTestConfiguration = GpuTestConfiguration::new()
.parameters(
TestParameters::default()
.features(wgpu::Features::SUBGROUP_OPERATIONS)
.features(wgpu::Features::SUBGROUP_COMPUTE)
.limits(wgpu::Limits::downlevel_defaults()),
)
.run_sync(|ctx| {
Expand Down
29 changes: 28 additions & 1 deletion wgpu-core/src/device/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,11 @@ impl<A: HalApi> Device<A> {
);
caps.set(
Caps::SUBGROUP,
self.features.contains(wgt::Features::SUBGROUP_OPERATIONS),
self.features.intersects(
wgt::Features::SUBGROUP_COMPUTE
| wgt::Features::SUBGROUP_FRAGMENT
| wgt::Features::SUBGROUP_VERTEX,
),
);

let debug_source = if self.instance_flags.contains(wgt::InstanceFlags::DEBUG) {
Expand All @@ -1334,7 +1338,30 @@ impl<A: HalApi> Device<A> {
None
};

let mut subgroup_stages = naga::valid::ShaderStages::empty();
subgroup_stages.set(
naga::valid::ShaderStages::COMPUTE,
self.features.contains(wgt::Features::SUBGROUP_COMPUTE),
);
subgroup_stages.set(
naga::valid::ShaderStages::FRAGMENT,
self.features.contains(wgt::Features::SUBGROUP_FRAGMENT),
);
subgroup_stages.set(
naga::valid::ShaderStages::VERTEX,
self.features.contains(wgt::Features::SUBGROUP_VERTEX),
);

let subgroup_operations = if caps.contains(Caps::SUBGROUP) {
use naga::valid::SubgroupOperationSet as S;
S::BASIC | S::VOTE | S::ARITHMETIC | S::BALLOT | S::SHUFFLE | S::SHUFFLE_RELATIVE
} else {
naga::valid::SubgroupOperationSet::empty()
};

let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), caps)
.subgroup_stages(subgroup_stages)
.subgroup_operations(subgroup_operations)
.validate(&module)
.map_err(|inner| {
pipeline::CreateShaderModuleError::Validation(pipeline::ShaderError {
Expand Down
4 changes: 3 additions & 1 deletion wgpu-hal/src/dx12/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ impl super::Adapter {
);

features.set(
wgt::Features::SUBGROUP_OPERATIONS,
wgt::Features::SUBGROUP_COMPUTE
| wgt::Features::SUBGROUP_FRAGMENT
| wgt::Features::SUBGROUP_VERTEX,
shader_model_support.HighestShaderModel >= d3d12_ty::D3D_SHADER_MODEL_6_0
&& matches!(dx12_shader_compiler, &wgt::Dx12Compiler::Dxc { .. }),
);
Expand Down
2 changes: 1 addition & 1 deletion wgpu-hal/src/metal/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ impl super::PrivateCapabilities {
features.set(F::SHADER_UNUSED_VERTEX_OUTPUT, true);

if self.supports_simd_scoped_operations {
features.insert(F::SUBGROUP_OPERATIONS);
features.insert(F::SUBGROUP_COMPUTE | F::SUBGROUP_FRAGMENT | F::SUBGROUP_VERTEX);
}

features
Expand Down
58 changes: 37 additions & 21 deletions wgpu-hal/src/vulkan/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,21 +490,33 @@ impl PhysicalDeviceFeatures {
}

if let Some(ref subgroup) = caps.subgroup {
features.set(
F::SUBGROUP_OPERATIONS,
subgroup.supported_operations.contains(
vk::SubgroupFeatureFlags::BASIC
| vk::SubgroupFeatureFlags::VOTE
| vk::SubgroupFeatureFlags::ARITHMETIC
| vk::SubgroupFeatureFlags::BALLOT
| vk::SubgroupFeatureFlags::SHUFFLE
| vk::SubgroupFeatureFlags::SHUFFLE_RELATIVE
| vk::SubgroupFeatureFlags::CLUSTERED
| vk::SubgroupFeatureFlags::QUAD,
) && subgroup
.supported_stages
.contains(vk::ShaderStageFlags::COMPUTE | vk::ShaderStageFlags::FRAGMENT),
);
if subgroup.supported_operations.contains(
vk::SubgroupFeatureFlags::BASIC
| vk::SubgroupFeatureFlags::VOTE
| vk::SubgroupFeatureFlags::ARITHMETIC
| vk::SubgroupFeatureFlags::BALLOT
| vk::SubgroupFeatureFlags::SHUFFLE
| vk::SubgroupFeatureFlags::SHUFFLE_RELATIVE,
) {
features.set(
F::SUBGROUP_COMPUTE,
subgroup
.supported_stages
.contains(vk::ShaderStageFlags::COMPUTE),
);
features.set(
F::SUBGROUP_FRAGMENT,
subgroup
.supported_stages
.contains(vk::ShaderStageFlags::FRAGMENT),
);
features.set(
F::SUBGROUP_VERTEX,
subgroup
.supported_stages
.contains(vk::ShaderStageFlags::VERTEX),
);
}
}

let supports_depth_format = |format| {
Expand Down Expand Up @@ -1279,17 +1291,17 @@ impl super::Adapter {
capabilities.push(spv::Capability::Geometry);
}

if features.contains(wgt::Features::SUBGROUP_OPERATIONS) {
if features.intersects(
wgt::Features::SUBGROUP_COMPUTE
| wgt::Features::SUBGROUP_FRAGMENT
| wgt::Features::SUBGROUP_VERTEX,
) {
capabilities.push(spv::Capability::GroupNonUniform);
capabilities.push(spv::Capability::GroupNonUniformVote);
capabilities.push(spv::Capability::GroupNonUniformArithmetic);
capabilities.push(spv::Capability::GroupNonUniformBallot);
capabilities.push(spv::Capability::GroupNonUniformShuffle);
capabilities.push(spv::Capability::GroupNonUniformShuffleRelative);
capabilities.push(spv::Capability::GroupNonUniformClustered);
capabilities.push(spv::Capability::GroupNonUniformQuad);
capabilities.push(spv::Capability::SubgroupBallotKHR);
capabilities.push(spv::Capability::SubgroupVoteKHR);
}

if features.intersects(
Expand Down Expand Up @@ -1319,7 +1331,11 @@ impl super::Adapter {
true, // could check `super::Workarounds::SEPARATE_ENTRY_POINTS`
);
spv::Options {
lang_version: if features.contains(wgt::Features::SUBGROUP_OPERATIONS) {
lang_version: if features.intersects(
wgt::Features::SUBGROUP_COMPUTE
| wgt::Features::SUBGROUP_FRAGMENT
| wgt::Features::SUBGROUP_VERTEX,
) {
(1, 3)
} else {
(1, 0)
Expand Down
42 changes: 30 additions & 12 deletions wgpu-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,17 +299,7 @@ bitflags::bitflags! {
/// This is a web and native feature.
const SHADER_F16 = 1 << 8;

/// Allows shaders to use the subgroup operation built-ins
///
/// Supported Platforms:
/// - Vulkan
/// - DX12
/// - Metal
///
/// This is a web and native feature.
const SUBGROUP_OPERATIONS = 1 << 9;

// 10..14 available
// 9..14 available

// Texture Formats:

Expand Down Expand Up @@ -766,10 +756,38 @@ bitflags::bitflags! {
/// - OpenGL
const SHADER_UNUSED_VERTEX_OUTPUT = 1 << 54;

// 54..59 available
// 55 available

// Shader:

/// Allows compute shaders to use the subgroup operation built-ins
///
/// Supported Platforms:
/// - Vulkan
/// - DX12
/// - Metal
///
/// This is a native only feature.
const SUBGROUP_COMPUTE = 1 << 56;
/// Allows fragment shaders to use the subgroup operation built-ins
///
/// Supported Platforms:
/// - Vulkan
/// - DX12
/// - Metal
///
/// This is a native only feature.
const SUBGROUP_FRAGMENT = 1 << 57;
/// Allows vertx shaders to use the subgroup operation built-ins
///
/// Supported Platforms:
/// - Vulkan
/// - DX12
/// - Metal
///
/// This is a native only feature.
const SUBGROUP_VERTEX = 1 << 58;

/// Enables 64-bit floating point types in SPIR-V shaders.
///
/// Note: even when supported by GPU hardware, 64-bit floating point operations are
Expand Down

0 comments on commit 184522d

Please sign in to comment.