diff --git a/deno_webgpu/lib.rs b/deno_webgpu/lib.rs index 11cab12b47..c10c175ba2 100644 --- a/deno_webgpu/lib.rs +++ b/deno_webgpu/lib.rs @@ -281,10 +281,8 @@ fn deserialize_features(features: &wgpu_types::Features) -> Vec<&'static str> { ) { return_features.push("sampled-texture-and-storage-buffer-array-non-uniform-indexing"); } - if features.contains( - wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - ) { - return_features.push("uniform-buffer-and-storage-texture-array-non-uniform-indexing"); + if features.contains(wgpu_types::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) { + return_features.push("storage-texture-array-non-uniform-indexing"); } if features.contains(wgpu_types::Features::PARTIALLY_BOUND_BINDING_ARRAY) { return_features.push("partially-bound-binding-array"); @@ -553,10 +551,10 @@ impl From for wgpu_types::Features { .contains("sampled-texture-and-storage-buffer-array-non-uniform-indexing"), ); features.set( - wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + wgpu_types::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, required_features .0 - .contains("uniform-buffer-and-storage-texture-array-non-uniform-indexing"), + .contains("storage-texture-array-non-uniform-indexing"), ); features.set( wgpu_types::Features::PARTIALLY_BOUND_BINDING_ARRAY, diff --git a/naga/src/valid/analyzer.rs b/naga/src/valid/analyzer.rs index 8417bf77be..0cf0757778 100644 --- a/naga/src/valid/analyzer.rs +++ b/naga/src/valid/analyzer.rs @@ -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!(), } diff --git a/naga/src/valid/mod.rs b/naga/src/valid/mod.rs index 906d449362..9a1f1e6d7a 100644 --- a/naga/src/valid/mod.rs +++ b/naga/src/valid/mod.rs @@ -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; } } diff --git a/tests/tests/binding_array/buffers.rs b/tests/tests/binding_array/buffers.rs index 1ef9818302..6a2ba4bab5 100644 --- a/tests/tests/binding_array/buffers.rs +++ b/tests/tests/binding_array/buffers.rs @@ -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_INDEXING) .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_INDEXING, ) .limits(Limits { max_uniform_buffers_per_shader_stage: 32, diff --git a/tests/tests/binding_array/storage_textures.rs b/tests/tests/binding_array/storage_textures.rs index ed8e6b4edb..bee8db9b77 100644 --- a/tests/tests/binding_array/storage_textures.rs +++ b/tests/tests/binding_array/storage_textures.rs @@ -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 { diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index e9600f72d6..9cd46f262f 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -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_INDEXING), ); // TODO: This needs a proper wgpu feature caps.set( diff --git a/wgpu-hal/src/dx12/adapter.rs b/wgpu-hal/src/dx12/adapter.rs index e71e2fce3a..65d52a630a 100644 --- a/wgpu-hal/src/dx12/adapter.rs +++ b/wgpu-hal/src/dx12/adapter.rs @@ -339,7 +339,8 @@ impl super::Adapter { features.set( wgt::Features::TEXTURE_BINDING_ARRAY - | wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING + | wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING + | wgt::Features::UNIFORM_BUFFER_INDEXING | wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, shader_model >= naga::back::hlsl::ShaderModel::V5_1, ); diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index ecff2b7a6a..bf45ccdcfc 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -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 diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index 61020c2a34..91b8b71f46 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -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_INDEXING | 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_INDEXING); 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,27 +581,7 @@ 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); @@ -645,29 +623,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 +1822,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_INDEXING, ) { capabilities.push(spv::Capability::ShaderNonUniform); } diff --git a/wgpu-hal/src/vulkan/device.rs b/wgpu-hal/src/vulkan/device.rs index 03fa9c0c59..45df3c8fdb 100644 --- a/wgpu-hal/src/vulkan/device.rs +++ b/wgpu-hal/src/vulkan/device.rs @@ -1611,11 +1611,19 @@ impl crate::Device for super::Device { super::AccelerationStructure, >, ) -> Result { + 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, )? diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 6a19c6147d..d168d76839 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -486,6 +486,31 @@ bitflags::bitflags! { // Native Features: // + /// Allows shaders to index uniform buffer binding arrays: + /// + /// ex. `uniform_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. `uniform_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 feature) + /// + /// This is a native only feature. + const UNIFORM_BUFFER_INDEXING = 1 << 17; /// Enables R64Uint image atomic min and max. /// /// Supported platforms: @@ -703,7 +728,7 @@ bitflags::bitflags! { /// /// This is a native only feature. const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 30; - /// 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]` /// @@ -724,10 +749,10 @@ bitflags::bitflags! { /// 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 << 31; + const STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 31; /// Allows the user to create bind groups containing arrays with less bindings than the BindGroupLayout. /// /// Supported platforms: