From 28281001439c2f6bf0b35788373616db96fb87b2 Mon Sep 17 00:00:00 2001 From: Alex S Date: Sat, 19 Jun 2021 18:33:57 +0300 Subject: [PATCH] Reduce feature flag surface for descriptor arrays. DYNAMIC_INDEXING is checked by default, since WGPU doesn't allow for any kind of specialization constants and constant indexing is nigh useless. STORAGE_RESOURCE_BINDING_ARRAY is enabled iff the device supports: - both or neither of uniform and buffer arrays with dynamic indexing; - both or neither of sampled and storage images with dynamic indexing. NONUNIFORM_INDEXING is enabled iff for ALL types of descriptor arrays *that are supported for dynamic indexing*, nonuniform indexing is also allowed. These flags have a limitation in that some platforms (eg. https://vulkan.gpuinfo.org/displayreport.php?id=11692#features_core_12) may support a strange subset of those features (example device supporting non-uniform indexing for textures and storage buffers, but NOT for storage textures or uniform buffers). In that case feature will be reported as missing, even though it is partially present. In the author's opinion, this flag set is convenient for the users to query; however, due to aforementioned limitations, it would be desirable to obtain statistics about "edge-case" platforms and what percentage of reports they comprise. --- wgpu-core/src/device/mod.rs | 15 ++- wgpu-hal/src/metal/adapter.rs | 18 ++- wgpu-hal/src/vulkan/adapter.rs | 165 +++++++++++++++++++-------- wgpu-types/src/lib.rs | 165 ++++----------------------- wgpu/examples/texture-arrays/main.rs | 22 ++-- wgpu/src/backend/direct.rs | 5 +- 6 files changed, 164 insertions(+), 226 deletions(-) diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index a1a861bbfc..50d5ae839f 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -988,11 +988,20 @@ impl Device { Bt::Buffer { ty: wgt::BufferBindingType::Storage { read_only }, .. - } => (Some(wgt::Features::BUFFER_BINDING_ARRAY), !read_only), + } => ( + Some( + wgt::Features::BUFFER_BINDING_ARRAY + | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY, + ), + !read_only, + ), Bt::Sampler { .. } => (None, false), - Bt::Texture { .. } => (Some(wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY), false), + Bt::Texture { .. } => (Some(wgt::Features::TEXTURE_BINDING_ARRAY), false), Bt::StorageTexture { access, .. } => ( - Some(wgt::Features::STORAGE_TEXTURE_BINDING_ARRAY), + Some( + wgt::Features::TEXTURE_BINDING_ARRAY + | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY, + ), match access { wgt::StorageTextureAccess::ReadOnly => false, wgt::StorageTextureAccess::WriteOnly => true, diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index b9d55e3a22..936a8423ed 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -848,22 +848,18 @@ impl super::PrivateCapabilities { | F::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES; features.set( - F::SAMPLED_TEXTURE_BINDING_ARRAY - | F::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING - | F::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + F::TEXTURE_BINDING_ARRAY | F::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, self.msl_version >= MTLLanguageVersion::V2_0 && self.supports_arrays_of_textures, ); //// XXX: this is technically not true, as read-only storage images can be used in arrays //// on precisely the same conditions that sampled textures can. But texel fetch from a //// sampled texture is a thing; should we bother introducing another feature flag? - features.set( - F::STORAGE_TEXTURE_BINDING_ARRAY - | F::STORAGE_TEXTURE_ARRAY_DYNAMIC_INDEXING - | F::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - self.msl_version >= MTLLanguageVersion::V2_2 - && self.supports_arrays_of_textures - && self.supports_arrays_of_textures_write, - ); + if self.msl_version >= MTLLanguageVersion::V2_2 + && self.supports_arrays_of_textures + && self.supports_arrays_of_textures_write + { + features.insert(F::STORAGE_RESOURCE_BINDING_ARRAY); + } features.set( F::ADDRESS_MODE_CLAMP_TO_BORDER, self.sampler_clamp_to_border, diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index a886925f5a..dbf0df96e7 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -11,9 +11,7 @@ use std::{ffi::CStr, mem, ptr, sync::Arc}; //TODO: const fn? fn indexing_features() -> wgt::Features { - wgt::Features::UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING - | wgt::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING - | wgt::Features::STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING + wgt::Features::BUFFER_BINDING_ARRAY | wgt::Features::TEXTURE_BINDING_ARRAY } /// Aggregate of the `vk::PhysicalDevice*Features` structs used by `gfx`. @@ -106,17 +104,19 @@ impl PhysicalDeviceFeatures { //.shader_image_gather_extended( //.shader_storage_image_extended_formats( .shader_uniform_buffer_array_dynamic_indexing( - requested_features - .contains(wgt::Features::UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING), + requested_features.contains(wgt::Features::BUFFER_BINDING_ARRAY), ) + .shader_storage_buffer_array_dynamic_indexing(requested_features.contains( + wgt::Features::BUFFER_BINDING_ARRAY + | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY, + )) .shader_sampled_image_array_dynamic_indexing( - requested_features - .contains(wgt::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING), - ) - .shader_storage_buffer_array_dynamic_indexing( - requested_features - .contains(wgt::Features::STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING), + requested_features.contains(wgt::Features::TEXTURE_BINDING_ARRAY), ) + .shader_storage_buffer_array_dynamic_indexing(requested_features.contains( + wgt::Features::TEXTURE_BINDING_ARRAY + | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY, + )) //.shader_storage_image_array_dynamic_indexing( //.shader_clip_distance(requested_features.contains(wgt::Features::SHADER_CLIP_DISTANCE)) //.shader_cull_distance(requested_features.contains(wgt::Features::SHADER_CULL_DISTANCE)) @@ -135,18 +135,30 @@ impl PhysicalDeviceFeatures { .descriptor_indexing(requested_features.intersects(indexing_features())) .shader_sampled_image_array_non_uniform_indexing( requested_features.contains( - wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + wgt::Features::TEXTURE_BINDING_ARRAY + | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, ), ) .shader_storage_image_array_non_uniform_indexing( requested_features.contains( - wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + wgt::Features::TEXTURE_BINDING_ARRAY + | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY + | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, ), ) //.shader_storage_buffer_array_non_uniform_indexing( .shader_uniform_buffer_array_non_uniform_indexing( - requested_features - .contains(wgt::Features::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING), + requested_features.contains( + wgt::Features::BUFFER_BINDING_ARRAY + | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + ), + ) + .shader_storage_buffer_array_non_uniform_indexing( + requested_features.contains( + wgt::Features::BUFFER_BINDING_ARRAY + | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY + | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + ), ) .runtime_descriptor_array( requested_features.contains(wgt::Features::UNSIZED_BINDING_ARRAY), @@ -165,18 +177,30 @@ impl PhysicalDeviceFeatures { vk::PhysicalDeviceDescriptorIndexingFeaturesEXT::builder() .shader_sampled_image_array_non_uniform_indexing( requested_features.contains( - wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + wgt::Features::TEXTURE_BINDING_ARRAY + | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, ), ) .shader_storage_image_array_non_uniform_indexing( requested_features.contains( - wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + wgt::Features::TEXTURE_BINDING_ARRAY + | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY + | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, ), ) //.shader_storage_buffer_array_non_uniform_indexing( .shader_uniform_buffer_array_non_uniform_indexing( - requested_features - .contains(wgt::Features::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING), + requested_features.contains( + wgt::Features::BUFFER_BINDING_ARRAY + | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + ), + ) + .shader_storage_buffer_array_non_uniform_indexing( + requested_features.contains( + wgt::Features::BUFFER_BINDING_ARRAY + | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY + | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + ), ) .runtime_descriptor_array( requested_features.contains(wgt::Features::UNSIZED_BINDING_ARRAY), @@ -207,9 +231,6 @@ impl PhysicalDeviceFeatures { | F::MAPPABLE_PRIMARY_BUFFERS | F::PUSH_CONSTANTS | F::ADDRESS_MODE_CLAMP_TO_BORDER - | F::SAMPLED_TEXTURE_BINDING_ARRAY - | F::STORAGE_TEXTURE_BINDING_ARRAY - | F::BUFFER_BINDING_ARRAY | F::TIMESTAMP_QUERY | F::PIPELINE_STATISTICS_QUERY | F::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES; @@ -250,21 +271,28 @@ impl PhysicalDeviceFeatures { //if self.core.shader_image_gather_extended != 0 { //if self.core.shader_storage_image_extended_formats != 0 { features.set( - F::UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING, + F::BUFFER_BINDING_ARRAY, self.core.shader_uniform_buffer_array_dynamic_indexing != 0, ); features.set( - F::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING, + F::TEXTURE_BINDING_ARRAY, self.core.shader_sampled_image_array_dynamic_indexing != 0, ); - features.set( - F::STORAGE_TEXTURE_ARRAY_DYNAMIC_INDEXING, - self.core.shader_storage_image_array_dynamic_indexing != 0, - ); - features.set( - F::STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING, - self.core.shader_storage_buffer_array_dynamic_indexing != 0, - ); + if Self::all_features_supported( + &features, + &[ + ( + F::BUFFER_BINDING_ARRAY, + self.core.shader_storage_buffer_array_dynamic_indexing, + ), + ( + F::TEXTURE_BINDING_ARRAY, + self.core.shader_storage_image_array_dynamic_indexing, + ), + ], + ) { + features.insert(F::STORAGE_RESOURCE_BINDING_ARRAY); + } //if self.core.shader_storage_image_array_dynamic_indexing != 0 { //if self.core.shader_clip_distance != 0 { //if self.core.shader_cull_distance != 0 { @@ -284,15 +312,29 @@ impl PhysicalDeviceFeatures { ); if let Some(ref vulkan_1_2) = self.vulkan_1_2 { - if vulkan_1_2.shader_sampled_image_array_non_uniform_indexing != 0 { - features |= F::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING; - } - if vulkan_1_2.shader_storage_image_array_non_uniform_indexing != 0 { - features |= F::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING; - } - //if vulkan_1_2.shader_storage_buffer_array_non_uniform_indexing != 0 { - if vulkan_1_2.shader_uniform_buffer_array_non_uniform_indexing != 0 { - features |= F::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING; + const STORAGE: F = F::STORAGE_RESOURCE_BINDING_ARRAY; + if Self::all_features_supported( + &features, + &[ + ( + F::BUFFER_BINDING_ARRAY, + vulkan_1_2.shader_uniform_buffer_array_non_uniform_indexing, + ), + ( + F::TEXTURE_BINDING_ARRAY, + vulkan_1_2.shader_sampled_image_array_non_uniform_indexing, + ), + ( + F::BUFFER_BINDING_ARRAY | STORAGE, + vulkan_1_2.shader_storage_buffer_array_non_uniform_indexing, + ), + ( + F::TEXTURE_BINDING_ARRAY | STORAGE, + vulkan_1_2.shader_storage_image_array_non_uniform_indexing, + ), + ], + ) { + features.insert(F::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING); } if vulkan_1_2.runtime_descriptor_array != 0 { features |= F::UNSIZED_BINDING_ARRAY; @@ -305,15 +347,29 @@ impl PhysicalDeviceFeatures { } if let Some(ref descriptor_indexing) = self.descriptor_indexing { - if descriptor_indexing.shader_sampled_image_array_non_uniform_indexing != 0 { - features |= F::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING; - } - if descriptor_indexing.shader_storage_image_array_non_uniform_indexing != 0 { - features |= F::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING; - } - //if descriptor_indexing.shader_storage_buffer_array_non_uniform_indexing != 0 { - if descriptor_indexing.shader_uniform_buffer_array_non_uniform_indexing != 0 { - features |= F::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING; + const STORAGE: F = F::STORAGE_RESOURCE_BINDING_ARRAY; + if Self::all_features_supported( + &features, + &[ + ( + F::BUFFER_BINDING_ARRAY, + descriptor_indexing.shader_uniform_buffer_array_non_uniform_indexing, + ), + ( + F::TEXTURE_BINDING_ARRAY, + descriptor_indexing.shader_sampled_image_array_non_uniform_indexing, + ), + ( + F::BUFFER_BINDING_ARRAY | STORAGE, + descriptor_indexing.shader_storage_buffer_array_non_uniform_indexing, + ), + ( + F::TEXTURE_BINDING_ARRAY | STORAGE, + descriptor_indexing.shader_storage_image_array_non_uniform_indexing, + ), + ], + ) { + features.insert(F::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING); } if descriptor_indexing.runtime_descriptor_array != 0 { features |= F::UNSIZED_BINDING_ARRAY; @@ -322,6 +378,15 @@ impl PhysicalDeviceFeatures { (features, dl_flags) } + + fn all_features_supported( + features: &wgt::Features, + implications: &[(wgt::Features, vk::Bool32)], + ) -> bool { + implications + .iter() + .all(|&(flag, support)| !features.contains(flag) || support != 0) + } } /// Information gathered about a physical device capabilities. diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 8455888181..af865e3def 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -235,11 +235,16 @@ bitflags::bitflags! { /// /// This is a native only feature. const MAPPABLE_PRIMARY_BUFFERS = 0x0000_0000_0001_0000; - /// Allows the user to create uniform arrays of sampled textures in shaders: + /// Allows the user to create uniform arrays of textures in shaders: /// /// eg. `uniform texture2D textures[10]`. /// - /// This capability allows them to exist and to be indexed by compile time constant + /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user + /// may also create uniform arrays of storage textures. + /// + /// eg. `uniform image2D textures[10]`. + /// + /// This capability allows them to exist and to be indexed by dynamically uniform /// values. /// /// Supported platforms: @@ -248,21 +253,8 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const SAMPLED_TEXTURE_BINDING_ARRAY = 0x0000_0000_0002_0000; - /// Allows shaders to index sampled texture arrays with dynamically uniform values: - /// - /// eg. `texture_array[uniform_value]` - /// - /// This capability means the hardware will also support SAMPLED_TEXTURE_BINDING_ARRAY. - /// - /// Supported platforms: - /// - DX12 - /// - Metal (with MSL 2.0+ on macOS 10.13+) - /// - Vulkan's shaderSampledImageArrayDynamicIndexing feature - /// - /// This is a native only feature. - const SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING = 0x0000_0000_0004_0000; - /// Allows shaders to index sampled texture arrays with dynamically non-uniform values: + const TEXTURE_BINDING_ARRAY = 0x0000_0000_0002_0000; + /// Allows shaders to index resource arrays with dynamically non-uniform values: /// /// eg. `texture_array[vertex_data]` /// @@ -280,21 +272,18 @@ bitflags::bitflags! { /// /// HLSL does not need any extension. /// - /// This capability means the hardware will also support SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING - /// and SAMPLED_TEXTURE_BINDING_ARRAY. - /// /// Supported platforms: /// - DX12 /// - Metal (with MSL 2.0+ on macOS 10.13+) /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderSampledImageArrayNonUniformIndexing feature) /// /// This is a native only feature. - const SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0000_0008_0000; + const RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0000_0008_0000; /// Allows the user to create unsized uniform arrays of bindings: /// /// eg. `uniform texture2D textures[]`. /// - /// If this capability is supported, SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING is very likely + /// If this capability is supported, [`Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING`] is very likely /// to also be supported /// /// Supported platforms: @@ -437,93 +426,20 @@ bitflags::bitflags! { /// /// eg. `uniform myBuffer { .... } buffer_array[10]`. /// - /// This capability allows them to exist and to be indexed by compile time constant + /// This capability allows them to exist and to be indexed by dynamically uniform /// values. /// + /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user + /// may also create arrays of storage buffers. + /// + /// eg. `buffer myBuffer { ... } buffer_array[10]` + /// /// Supported platforms: /// - DX12 /// - Vulkan /// /// This is a native only feature. const BUFFER_BINDING_ARRAY = 0x0000_0001_0000_0000; - /// Allows shaders to index uniform buffer arrays with dynamically uniform values: - /// - /// eg. `buffer_array[uniform_value]` - /// - /// This capability means the hardware will also support BUFFER_BINDING_ARRAY. - /// - /// Supported platforms: - /// - DX12 - /// - Vulkan's shaderUniformBufferArrayDynamicIndexing feature - /// - /// This is a native only feature. - const UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING = 0x0000_0002_0000_0000; - /// Allows shaders to index uniform buffer arrays with dynamically non-uniform values: - /// - /// eg. `buffer_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: - /// - /// eg. `layout(location = 0) nonuniformEXT flat in int vertex_data;` - /// - /// or as `nonuniformEXT` constructor: - /// - /// eg. `buffer_array[nonuniformEXT(vertex_data)]` - /// - /// HLSL does not need any extension. - /// - /// This capability means the hardware will also support UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING - /// and BUFFER_BINDING_ARRAY. - /// - /// Supported platforms: - /// - DX12 - /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderUniformBufferArrayNonUniformIndexing feature) - /// - /// This is a native only feature. - const UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0004_0000_0000; - /// Allows shaders to index storage buffer arrays with dynamically uniform values: - /// - /// eg. `buffer_array[uniform_value]` - /// - /// This capability means the hardware will also support BUFFER_BINDING_ARRAY. - /// - /// Supported platforms: - /// - DX12 - /// - Vulkan's shaderStorageBufferArrayDynamicIndexing feature - /// - /// This is a native only feature. - const STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING = 0x0000_0008_0000_0000; - /// Allows shaders to index storage buffer arrays with dynamically non-uniform values: - /// - /// eg. `buffer_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: - /// - /// eg. `layout(location = 0) nonuniformEXT flat in int vertex_data;` - /// - /// or as `nonuniformEXT` constructor: - /// - /// eg. `buffer_array[nonuniformEXT(vertex_data)]` - /// - /// HLSL does not need any extension. - /// - /// This capability means the hardware will also support STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING - /// and BUFFER_BINDING_ARRAY. - /// - /// Supported platforms: - /// - DX12 - /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderStorageBufferArrayNonUniformIndexing feature) - /// - /// This is a native only feature. - const STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0010_0000_0000; /// Enables bindings of writable storage buffers and textures visible to vertex shaders. /// /// Note: some (tiled-based) platforms do not support vertex shaders with any side-effects. @@ -533,11 +449,11 @@ bitflags::bitflags! { /// /// This is a native-only feature. const VERTEX_WRITABLE_STORAGE = 0x0000_0020_0000_0000; - /// Allows the user to create uniform arrays of storage textures in shaders: + /// Allows the user to create uniform arrays of storage buffers or textures in shaders, + /// if resp. [`Features::BUFFER_BINDING_ARRAY`] or [`Features::TEXTURE_BINDING_ARRAY`] + /// is supported. /// - /// eg. `uniform image2D textures[10]`. - /// - /// This capability allows them to exist and to be indexed by compile time constant + /// This capability allows them to exist and to be indexed by dynamically uniform /// values. /// /// Supported platforms: @@ -545,44 +461,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const STORAGE_TEXTURE_BINDING_ARRAY = 0x0000_0040_0000_0000; - /// Allows shaders to index storage texture arrays with dynamically uniform values: - /// - /// eg. `texture_array[uniform_value]` - /// - /// This capability means the hardware will also support STORAGE_TEXTURE_BINDING_ARRAY. - /// - /// Supported platforms: - /// - Metal (with MSL 2.2+ on macOS 10.13+) - /// - Vulkan's shaderSampledImageArrayDynamicIndexing feature - /// - /// This is a native only feature. - const STORAGE_TEXTURE_ARRAY_DYNAMIC_INDEXING = 0x0000_0080_0000_0000; - /// Allows shaders to index storage texture arrays with dynamically non-uniform values: - /// - /// eg. `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: - /// - /// eg. `layout(location = 0) nonuniformEXT flat in int vertex_data;` - /// - /// or as `nonuniformEXT` constructor: - /// - /// eg. `texture_array[nonuniformEXT(vertex_data)]` - /// - /// This capability means the hardware will also support STORAGE_TEXTURE_ARRAY_DYNAMIC_INDEXING - /// and STORAGE_TEXTURE_BINDING_ARRAY. - /// - /// Supported platforms: - /// - Metal (with MSL 2.2+ on macOS 10.13+) - /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderSampledImageArrayNonUniformIndexing feature) - /// - /// This is a native only feature. - const STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0100_0000_0000; + const STORAGE_RESOURCE_BINDING_ARRAY = 0x0000_0040_0000_0000; /// Enables clear to zero for buffers & images. /// /// Supported platforms: diff --git a/wgpu/examples/texture-arrays/main.rs b/wgpu/examples/texture-arrays/main.rs index 8dbbac9870..41cbaf7fec 100644 --- a/wgpu/examples/texture-arrays/main.rs +++ b/wgpu/examples/texture-arrays/main.rs @@ -72,12 +72,11 @@ struct Example { impl framework::Example for Example { fn optional_features() -> wgpu::Features { wgpu::Features::UNSIZED_BINDING_ARRAY - | wgpu::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING - | wgpu::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING + | wgpu::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING | wgpu::Features::PUSH_CONSTANTS } fn required_features() -> wgpu::Features { - wgpu::Features::SAMPLED_TEXTURE_BINDING_ARRAY | wgpu::Features::SPIRV_SHADER_PASSTHROUGH + wgpu::Features::TEXTURE_BINDING_ARRAY | wgpu::Features::SPIRV_SHADER_PASSTHROUGH } fn required_limits() -> wgpu::Limits { wgpu::Limits { @@ -94,23 +93,16 @@ impl framework::Example for Example { let mut uniform_workaround = false; let vs_module = device.create_shader_module(&wgpu::include_spirv!("shader.vert.spv")); let fs_source = match device.features() { - //f if f.contains(wgpu::Features::UNSIZED_BINDING_ARRAY) => { - // wgpu::include_spirv_raw!("unsized-non-uniform.frag.spv") - //} - f if f.contains(wgpu::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) => { + f if f.contains(wgpu::Features::UNSIZED_BINDING_ARRAY) => { + wgpu::include_spirv_raw!("unsized-non-uniform.frag.spv") + } + f if f.contains(wgpu::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING) => { wgpu::include_spirv_raw!("non-uniform.frag.spv") } - f if f.contains( - wgpu::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING - | wgpu::Features::PUSH_CONSTANTS, - ) => - { + f if f.contains(wgpu::Features::TEXTURE_BINDING_ARRAY) => { uniform_workaround = true; wgpu::include_spirv_raw!("uniform.frag.spv") } - f if f.contains(wgpu::Features::SAMPLED_TEXTURE_BINDING_ARRAY) => { - wgpu::include_spirv_raw!("constant.frag.spv") - } _ => unreachable!(), }; let fs_module = unsafe { device.create_shader_module_spirv(&fs_source) }; diff --git a/wgpu/src/backend/direct.rs b/wgpu/src/backend/direct.rs index 27c2bc2a7c..c5fc381593 100644 --- a/wgpu/src/backend/direct.rs +++ b/wgpu/src/backend/direct.rs @@ -896,10 +896,7 @@ impl crate::Context for Context { use wgc::binding_model as bm; let mut arrayed_texture_views = Vec::new(); - if device - .features - .contains(Features::SAMPLED_TEXTURE_BINDING_ARRAY) - { + if device.features.contains(Features::TEXTURE_BINDING_ARRAY) { // gather all the array view IDs first for entry in desc.entries.iter() { if let BindingResource::TextureViewArray(array) = entry.resource {