Use Update After Bind Descriptors for Bind Groups With Binding Arrays (#6815)

* Use Update After Bind Descriptors for Bind Groups With Binding Arrays

Update After Bind

x

* Comments

* Fix URL
This commit is contained in:
Connor Fitzgerald
2025-02-15 12:02:27 -05:00
committed by GitHub
parent a45e2db43a
commit d8833d0798
11 changed files with 119 additions and 112 deletions

View File

@@ -391,8 +391,10 @@ pub enum GPUFeatureName {
StorageResourceBindingArray,
#[webidl(rename = "sampled-texture-and-storage-buffer-array-non-uniform-indexing")]
SampledTextureAndStorageBufferArrayNonUniformIndexing,
#[webidl(rename = "uniform-buffer-and-storage-texture-array-non-uniform-indexing")]
UniformBufferAndStorageTextureArrayNonUniformIndexing,
#[webidl(rename = "storage-texture-array-non-uniform-indexing")]
StorageTextureArrayNonUniformIndexing,
#[webidl(rename = "uniform-buffer-binding-arrays")]
UniformBufferBindingArrays,
#[webidl(rename = "partially-bound-binding-array")]
PartiallyBoundBindingArray,
#[webidl(rename = "multi-draw-indirect")]
@@ -462,7 +464,8 @@ pub fn feature_names_to_features(names: Vec<GPUFeatureName>) -> wgpu_types::Feat
GPUFeatureName::BufferBindingArray => Features::BUFFER_BINDING_ARRAY,
GPUFeatureName::StorageResourceBindingArray => Features::STORAGE_RESOURCE_BINDING_ARRAY,
GPUFeatureName::SampledTextureAndStorageBufferArrayNonUniformIndexing => Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
GPUFeatureName::UniformBufferAndStorageTextureArrayNonUniformIndexing => Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
GPUFeatureName::StorageTextureArrayNonUniformIndexing => Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
GPUFeatureName::UniformBufferBindingArrays => Features::UNIFORM_BUFFER_BINDING_ARRAYS,
GPUFeatureName::PartiallyBoundBindingArray => Features::PARTIALLY_BOUND_BINDING_ARRAY,
GPUFeatureName::MultiDrawIndirect => Features::MULTI_DRAW_INDIRECT,
GPUFeatureName::MultiDrawIndirectCount => Features::MULTI_DRAW_INDIRECT_COUNT,
@@ -575,10 +578,11 @@ pub fn features_to_feature_names(features: wgpu_types::Features) -> HashSet<GPUF
) {
return_features.insert(SampledTextureAndStorageBufferArrayNonUniformIndexing);
}
if features.contains(
wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
) {
return_features.insert(UniformBufferAndStorageTextureArrayNonUniformIndexing);
if features.contains(wgpu_types::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) {
return_features.insert(StorageTextureArrayNonUniformIndexing);
}
if features.contains(wgpu_types::Features::UNIFORM_BUFFER_BINDING_ARRAYS) {
return_features.insert(UniformBufferBindingArrays);
}
if features.contains(wgpu_types::Features::PARTIALLY_BOUND_BINDING_ARRAY) {
return_features.insert(PartiallyBoundBindingArray);

View File

@@ -531,7 +531,8 @@ impl FunctionInfo {
..
} => {
// these are nasty aliases, but these idents are too long and break rustfmt
let ub_st = super::Capabilities::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
let sto = super::Capabilities::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
let uni = super::Capabilities::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING;
let st_sb = super::Capabilities::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING;
let sampler = super::Capabilities::SAMPLER_NON_UNIFORM_INDEXING;
@@ -542,7 +543,7 @@ impl FunctionInfo {
needed_caps |= match *array_element_ty {
// If we're an image, use the appropriate limit.
crate::TypeInner::Image { class, .. } => match class {
crate::ImageClass::Storage { .. } => ub_st,
crate::ImageClass::Storage { .. } => sto,
_ => st_sb,
},
crate::TypeInner::Sampler { .. } => sampler,
@@ -551,7 +552,7 @@ impl FunctionInfo {
if let E::GlobalVariable(global_handle) = expression_arena[base] {
let global = &resolve_context.global_vars[global_handle];
match global.space {
crate::AddressSpace::Uniform => ub_st,
crate::AddressSpace::Uniform => uni,
crate::AddressSpace::Storage { .. } => st_sb,
_ => unreachable!(),
}

View File

@@ -90,47 +90,49 @@ bitflags::bitflags! {
const PRIMITIVE_INDEX = 1 << 2;
/// Support for non-uniform indexing of sampled textures and storage buffer arrays.
const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 3;
/// Support for non-uniform indexing of uniform buffers and storage texture arrays.
const UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 4;
/// Support for non-uniform indexing of storage texture arrays.
const STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 4;
/// Support for non-uniform indexing of uniform buffer arrays.
const UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 5;
/// Support for non-uniform indexing of samplers.
const SAMPLER_NON_UNIFORM_INDEXING = 1 << 5;
const SAMPLER_NON_UNIFORM_INDEXING = 1 << 6;
/// Support for [`BuiltIn::ClipDistance`].
///
/// [`BuiltIn::ClipDistance`]: crate::BuiltIn::ClipDistance
const CLIP_DISTANCE = 1 << 6;
const CLIP_DISTANCE = 1 << 7;
/// Support for [`BuiltIn::CullDistance`].
///
/// [`BuiltIn::CullDistance`]: crate::BuiltIn::CullDistance
const CULL_DISTANCE = 1 << 7;
const CULL_DISTANCE = 1 << 8;
/// Support for 16-bit normalized storage texture formats.
const STORAGE_TEXTURE_16BIT_NORM_FORMATS = 1 << 8;
const STORAGE_TEXTURE_16BIT_NORM_FORMATS = 1 << 9;
/// Support for [`BuiltIn::ViewIndex`].
///
/// [`BuiltIn::ViewIndex`]: crate::BuiltIn::ViewIndex
const MULTIVIEW = 1 << 9;
const MULTIVIEW = 1 << 10;
/// Support for `early_depth_test`.
const EARLY_DEPTH_TEST = 1 << 10;
const EARLY_DEPTH_TEST = 1 << 11;
/// Support for [`BuiltIn::SampleIndex`] and [`Sampling::Sample`].
///
/// [`BuiltIn::SampleIndex`]: crate::BuiltIn::SampleIndex
/// [`Sampling::Sample`]: crate::Sampling::Sample
const MULTISAMPLED_SHADING = 1 << 11;
const MULTISAMPLED_SHADING = 1 << 12;
/// Support for ray queries and acceleration structures.
const RAY_QUERY = 1 << 12;
const RAY_QUERY = 1 << 13;
/// Support for generating two sources for blending from fragment shaders.
const DUAL_SOURCE_BLENDING = 1 << 13;
const DUAL_SOURCE_BLENDING = 1 << 14;
/// Support for arrayed cube textures.
const CUBE_ARRAY_TEXTURES = 1 << 14;
const CUBE_ARRAY_TEXTURES = 1 << 15;
/// Support for 64-bit signed and unsigned integers.
const SHADER_INT64 = 1 << 15;
const SHADER_INT64 = 1 << 16;
/// Support for subgroup operations.
/// Implies support for subgroup operations in both fragment and compute stages,
/// but not necessarily in the vertex stage, which requires [`Capabilities::SUBGROUP_VERTEX_STAGE`].
const SUBGROUP = 1 << 16;
const SUBGROUP = 1 << 17;
/// Support for subgroup barriers.
const SUBGROUP_BARRIER = 1 << 17;
const SUBGROUP_BARRIER = 1 << 18;
/// Support for subgroup operations in the vertex stage.
const SUBGROUP_VERTEX_STAGE = 1 << 18;
const SUBGROUP_VERTEX_STAGE = 1 << 19;
/// Support for [`AtomicFunction::Min`] and [`AtomicFunction::Max`] on
/// 64-bit integers in the [`Storage`] address space, when the return
/// value is not used.
@@ -140,9 +142,9 @@ bitflags::bitflags! {
/// [`AtomicFunction::Min`]: crate::AtomicFunction::Min
/// [`AtomicFunction::Max`]: crate::AtomicFunction::Max
/// [`Storage`]: crate::AddressSpace::Storage
const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 19;
const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 20;
/// Support for all atomic operations on 64-bit integers.
const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 20;
const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 21;
/// Support for [`AtomicFunction::Add`], [`AtomicFunction::Sub`],
/// and [`AtomicFunction::Exchange { compare: None }`] on 32-bit floating-point numbers
/// in the [`Storage`] address space.
@@ -151,11 +153,11 @@ bitflags::bitflags! {
/// [`AtomicFunction::Sub`]: crate::AtomicFunction::Sub
/// [`AtomicFunction::Exchange { compare: None }`]: crate::AtomicFunction::Exchange
/// [`Storage`]: crate::AddressSpace::Storage
const SHADER_FLOAT32_ATOMIC = 1 << 21;
const SHADER_FLOAT32_ATOMIC = 1 << 22;
/// Support for atomic operations on images.
const TEXTURE_ATOMIC = 1 << 22;
const TEXTURE_ATOMIC = 1 << 23;
/// Support for atomic operations on 64-bit images.
const TEXTURE_INT64_ATOMIC = 1 << 23;
const TEXTURE_INT64_ATOMIC = 1 << 24;
}
}

View File

@@ -7,10 +7,7 @@ use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, Tes
static BINDING_ARRAY_UNIFORM_BUFFERS: GpuTestConfiguration = GpuTestConfiguration::new()
.parameters(
TestParameters::default()
.features(
Features::BUFFER_BINDING_ARRAY
| Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
)
.features(Features::BUFFER_BINDING_ARRAY | Features::UNIFORM_BUFFER_BINDING_ARRAYS)
.limits(Limits {
max_uniform_buffers_per_shader_stage: 16,
..Limits::default()
@@ -31,7 +28,7 @@ static PARTIAL_BINDING_ARRAY_UNIFORM_BUFFERS: GpuTestConfiguration = GpuTestConf
.features(
Features::BUFFER_BINDING_ARRAY
| Features::PARTIALLY_BOUND_BINDING_ARRAY
| Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
| Features::UNIFORM_BUFFER_BINDING_ARRAYS,
)
.limits(Limits {
max_uniform_buffers_per_shader_stage: 32,

View File

@@ -13,7 +13,7 @@ static BINDING_ARRAY_STORAGE_TEXTURES: GpuTestConfiguration = GpuTestConfigurati
.features(
Features::TEXTURE_BINDING_ARRAY
| Features::STORAGE_RESOURCE_BINDING_ARRAY
| Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
)
.limits(Limits {
@@ -32,7 +32,7 @@ static PARTIAL_BINDING_ARRAY_STORAGE_TEXTURES: GpuTestConfiguration = GpuTestCon
Features::TEXTURE_BINDING_ARRAY
| Features::PARTIALLY_BOUND_BINDING_ARRAY
| Features::STORAGE_RESOURCE_BINDING_ARRAY
| Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
)
.limits(Limits {

View File

@@ -392,9 +392,12 @@ pub fn create_validator(
.contains(wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING),
);
caps.set(
Caps::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
features
.contains(wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING),
Caps::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
features.contains(wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING),
);
caps.set(
Caps::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
features.contains(wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS),
);
// TODO: This needs a proper wgpu feature
caps.set(

View File

@@ -372,7 +372,7 @@ impl super::Adapter {
features.set(
wgt::Features::TEXTURE_BINDING_ARRAY
| wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
shader_model >= naga::back::hlsl::ShaderModel::V5_1,
);

View File

@@ -925,7 +925,7 @@ impl super::PrivateCapabilities {
features.set(
F::TEXTURE_BINDING_ARRAY
| F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
| F::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| F::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| F::PARTIALLY_BOUND_BINDING_ARRAY,
self.msl_version >= MTLLanguageVersion::V3_0
&& self.supports_arrays_of_textures

View File

@@ -12,7 +12,8 @@ fn depth_stencil_required_flags() -> vk::FormatFeatureFlags {
//TODO: const fn?
fn indexing_features() -> wgt::Features {
wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS
| wgt::Features::PARTIALLY_BOUND_BINDING_ARRAY
}
@@ -217,14 +218,12 @@ impl PhysicalDeviceFeatures {
| wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY
| wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
);
let needs_uniform_buffer_non_uniform = requested_features.contains(
wgt::Features::TEXTURE_BINDING_ARRAY
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
);
let needs_uniform_buffer_non_uniform =
requested_features.contains(wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS);
let needs_storage_image_non_uniform = requested_features.contains(
wgt::Features::TEXTURE_BINDING_ARRAY
| wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
| wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
);
let needs_partially_bound =
requested_features.intersects(wgt::Features::PARTIALLY_BOUND_BINDING_ARRAY);
@@ -498,7 +497,6 @@ impl PhysicalDeviceFeatures {
phd: vk::PhysicalDevice,
caps: &PhysicalDeviceProperties,
) -> (wgt::Features, wgt::DownlevelFlags) {
use crate::auxil::db;
use wgt::{DownlevelFlags as Df, Features as F};
let mut features = F::empty()
| F::SPIRV_SHADER_PASSTHROUGH
@@ -583,31 +581,13 @@ impl PhysicalDeviceFeatures {
F::VERTEX_WRITABLE_STORAGE,
self.core.vertex_pipeline_stores_and_atomics != 0,
);
//if self.core.shader_image_gather_extended != 0 {
//if self.core.shader_storage_image_extended_formats != 0 {
features.set(
F::BUFFER_BINDING_ARRAY,
self.core.shader_uniform_buffer_array_dynamic_indexing != 0,
);
features.set(
F::TEXTURE_BINDING_ARRAY,
self.core.shader_sampled_image_array_dynamic_indexing != 0,
);
features.set(F::SHADER_PRIMITIVE_INDEX, self.core.geometry_shader != 0);
features.set(
F::STORAGE_RESOURCE_BINDING_ARRAY,
(features.contains(F::BUFFER_BINDING_ARRAY)
&& self.core.shader_storage_buffer_array_dynamic_indexing != 0)
|| (features.contains(F::TEXTURE_BINDING_ARRAY)
&& self.core.shader_storage_image_array_dynamic_indexing != 0),
);
//if self.core.shader_storage_image_array_dynamic_indexing != 0 {
//if self.core.shader_clip_distance != 0 {
//if self.core.shader_cull_distance != 0 {
features.set(F::SHADER_F64, self.core.shader_float64 != 0);
features.set(F::SHADER_INT64, self.core.shader_int64 != 0);
features.set(F::SHADER_I16, self.core.shader_int16 != 0);
features.set(F::SHADER_PRIMITIVE_INDEX, self.core.geometry_shader != 0);
if let Some(ref shader_atomic_int64) = self.shader_atomic_int64 {
features.set(
F::SHADER_INT64_ATOMIC_ALL_OPS | F::SHADER_INT64_ATOMIC_MIN_MAX,
@@ -645,29 +625,38 @@ impl PhysicalDeviceFeatures {
caps.supports_extension(ext::conservative_rasterization::NAME),
);
let intel_windows = caps.properties.vendor_id == db::intel::VENDOR && cfg!(windows);
if let Some(ref descriptor_indexing) = self.descriptor_indexing {
const STORAGE: F = F::STORAGE_RESOURCE_BINDING_ARRAY;
features.set(
F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
(features.contains(F::TEXTURE_BINDING_ARRAY)
&& descriptor_indexing.shader_sampled_image_array_non_uniform_indexing != 0)
&& (features.contains(F::BUFFER_BINDING_ARRAY | STORAGE)
&& descriptor_indexing.shader_storage_buffer_array_non_uniform_indexing
!= 0),
);
features.set(
F::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
(features.contains(F::BUFFER_BINDING_ARRAY)
&& descriptor_indexing.shader_uniform_buffer_array_non_uniform_indexing != 0)
&& (features.contains(F::TEXTURE_BINDING_ARRAY | STORAGE)
&& descriptor_indexing.shader_storage_image_array_non_uniform_indexing
!= 0),
);
if descriptor_indexing.descriptor_binding_partially_bound != 0 && !intel_windows {
features |= F::PARTIALLY_BOUND_BINDING_ARRAY;
}
// We use update-after-bind descriptors for all bind groups containing binding arrays.
//
// In those bind groups, we allow all binding types except uniform buffers to be present.
//
// As we can only switch between update-after-bind and not on a per bind group basis,
// all supported binding types need to be able to be marked update after bind.
//
// As such, we enable all features as a whole, rather individually.
let supports_descriptor_indexing =
// Sampled Images
descriptor_indexing.shader_sampled_image_array_non_uniform_indexing != 0
&& descriptor_indexing.descriptor_binding_sampled_image_update_after_bind != 0
// Storage Images
&& descriptor_indexing.shader_storage_image_array_non_uniform_indexing != 0
&& descriptor_indexing.descriptor_binding_storage_image_update_after_bind != 0
// Storage Buffers
&& descriptor_indexing.shader_storage_buffer_array_non_uniform_indexing != 0
&& descriptor_indexing.descriptor_binding_storage_buffer_update_after_bind != 0;
let descriptor_indexing_features = F::BUFFER_BINDING_ARRAY
| F::TEXTURE_BINDING_ARRAY
| F::STORAGE_RESOURCE_BINDING_ARRAY
| F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
| F::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
features.set(descriptor_indexing_features, supports_descriptor_indexing);
let supports_partially_bound =
descriptor_indexing.descriptor_binding_partially_bound != 0;
features.set(F::PARTIALLY_BOUND_BINDING_ARRAY, supports_partially_bound);
}
features.set(F::DEPTH_CLIP_CONTROL, self.core.depth_clamp != 0);
@@ -1835,7 +1824,8 @@ impl super::Adapter {
if features.intersects(
wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
| wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
| wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS,
) {
capabilities.push(spv::Capability::ShaderNonUniform);
}

View File

@@ -1611,11 +1611,19 @@ impl crate::Device for super::Device {
super::AccelerationStructure,
>,
) -> Result<super::BindGroup, crate::DeviceError> {
let contains_binding_arrays = !desc.layout.binding_arrays.is_empty();
let desc_set_layout_flags = if contains_binding_arrays {
gpu_descriptor::DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND
} else {
gpu_descriptor::DescriptorSetLayoutCreateFlags::empty()
};
let mut vk_sets = unsafe {
self.desc_allocator.lock().allocate(
&*self.shared,
&desc.layout.raw,
gpu_descriptor::DescriptorSetLayoutCreateFlags::empty(),
desc_set_layout_flags,
&desc.layout.desc_count,
1,
)?

View File

@@ -756,31 +756,17 @@ bitflags_array! {
///
/// This is a native only feature.
const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 11;
/// Allows shaders to index uniform buffer and storage texture resource arrays with dynamically non-uniform values:
/// Allows shaders to index storage texture resource arrays with dynamically non-uniform values:
///
/// ex. `texture_array[vertex_data]`
///
/// In order to use this capability, the corresponding GLSL extension must be enabled like so:
///
/// `#extension GL_EXT_nonuniform_qualifier : require`
///
/// and then used either as `nonuniformEXT` qualifier in variable declaration:
///
/// ex. `layout(location = 0) nonuniformEXT flat in int vertex_data;`
///
/// or as `nonuniformEXT` constructor:
///
/// ex. `texture_array[nonuniformEXT(vertex_data)]`
///
/// WGSL and HLSL do not need any extension.
///
/// Supported platforms:
/// - DX12
/// - Metal (with MSL 2.0+ on macOS 10.13+)
/// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderUniformBufferArrayNonUniformIndexing & shaderStorageTextureArrayNonUniformIndexing feature)
/// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderStorageTextureArrayNonUniformIndexing feature)
///
/// This is a native only feature.
const UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 12;
const STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 12;
/// Allows the user to create bind groups containing arrays with less bindings than the BindGroupLayout.
///
/// Supported platforms:
@@ -1151,6 +1137,22 @@ bitflags_array! {
/// This is a native only feature.
const TEXTURE_INT64_ATOMIC = 1 << 45;
/// Allows uniform buffers to be bound as binding arrays.
///
/// This allows:
/// - Shaders to contain `var<uniform> buffer: binding_array<UniformBuffer>;`
/// - The `count` field of `BindGroupLayoutEntry`s with `Uniform` buffers, to be set to `Some`.
///
/// Supported platforms:
/// - None (<https://github.com/gfx-rs/wgpu/issues/7149>)
///
/// Potential Platforms:
/// - DX12
/// - Metal
/// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s `shaderUniformBufferArrayNonUniformIndexing` feature)
///
/// This is a native only feature.
const UNIFORM_BUFFER_BINDING_ARRAYS = 1 << 46;
}
/// Features that are not guaranteed to be supported.