diff --git a/player/tests/data/buffer-clear.ron b/player/tests/data/buffer-clear.ron index c11b15800b..a6a29f1af9 100644 --- a/player/tests/data/buffer-clear.ron +++ b/player/tests/data/buffer-clear.ron @@ -1,5 +1,5 @@ ( - features: (bits: 0x0000_0001_0000_0000), + features: (bits: 0x0000_0004_0000_0000), expectations: [ ( name: "basic", diff --git a/player/tests/data/clear-buffer-image.ron b/player/tests/data/clear-buffer-image.ron index 42fff3a0b1..9cd31b8372 100644 --- a/player/tests/data/clear-buffer-image.ron +++ b/player/tests/data/clear-buffer-image.ron @@ -1,5 +1,5 @@ ( - features: (bits: 0x0000_0200_0000_0000), + features: (bits: 0x0000_0004_0000_0000), expectations: [ ( name: "Quad", @@ -95,4 +95,4 @@ ) ]), ], -) \ No newline at end of file +) 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..c05f8c2a67 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,39 @@ 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: + const TEXTURE_BINDING_ARRAY = 0x0000_0000_0002_0000; + /// Allows the user to create arrays of buffers in shaders: + /// + /// eg. `uniform myBuffer { .... } buffer_array[10]`. + /// + /// This capability allows them to exist and to be indexed by dynamically uniform + /// values. /// - /// eg. `texture_array[uniform_value]` + /// If [`Features::STORAGE_RESOURCE_BINDING_ARRAY`] is supported as well as this, the user + /// may also create arrays of storage buffers. /// - /// This capability means the hardware will also support SAMPLED_TEXTURE_BINDING_ARRAY. + /// eg. `buffer myBuffer { ... } buffer_array[10]` /// /// Supported platforms: /// - DX12 - /// - Metal (with MSL 2.0+ on macOS 10.13+) - /// - Vulkan's shaderSampledImageArrayDynamicIndexing feature + /// - Vulkan /// /// 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 BUFFER_BINDING_ARRAY = 0x0000_0000_0004_0000; + /// 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. + /// + /// This capability allows them to exist and to be indexed by dynamically uniform + /// values. + /// + /// Supported platforms: + /// - Metal (with MSL 2.2+ on macOS 10.13+) + /// - Vulkan + /// + /// This is a native only feature. + const STORAGE_RESOURCE_BINDING_ARRAY = 0x0000_0000_0008_0000; + /// Allows shaders to index resource arrays with dynamically non-uniform values: /// /// eg. `texture_array[vertex_data]` /// @@ -280,21 +303,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_0010_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: @@ -302,7 +322,7 @@ bitflags::bitflags! { /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s runtimeDescriptorArray feature /// /// This is a native only feature. - const UNSIZED_BINDING_ARRAY = 0x0000_0000_0010_0000; + const UNSIZED_BINDING_ARRAY = 0x0000_0000_0020_0000; /// Allows the user to call [`RenderPass::multi_draw_indirect`] and [`RenderPass::multi_draw_indexed_indirect`]. /// /// Allows multiple indirect calls to be dispatched from a single buffer. @@ -313,7 +333,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const MULTI_DRAW_INDIRECT = 0x0000_0000_0020_0000; + const MULTI_DRAW_INDIRECT = 0x0000_0000_0040_0000; /// Allows the user to call [`RenderPass::multi_draw_indirect_count`] and [`RenderPass::multi_draw_indexed_indirect_count`]. /// /// This allows the use of a buffer containing the actual number of draw calls. @@ -323,7 +343,7 @@ bitflags::bitflags! { /// - Vulkan 1.2+ (or VK_KHR_draw_indirect_count) /// /// This is a native only feature. - const MULTI_DRAW_INDIRECT_COUNT = 0x0000_0000_0040_0000; + const MULTI_DRAW_INDIRECT_COUNT = 0x0000_0000_0080_0000; /// Allows the use of push constants: small, fast bits of memory that can be updated /// inside a [`RenderPass`]. /// @@ -340,7 +360,7 @@ bitflags::bitflags! { /// - OpenGL (emulated with uniforms) /// /// This is a native only feature. - const PUSH_CONSTANTS = 0x0000_0000_0080_0000; + const PUSH_CONSTANTS = 0x0000_0000_0100_0000; /// Allows the use of [`AddressMode::ClampToBorder`]. /// /// Supported platforms: @@ -351,7 +371,7 @@ bitflags::bitflags! { /// - OpenGL /// /// This is a web and native feature. - const ADDRESS_MODE_CLAMP_TO_BORDER = 0x0000_0000_0100_0000; + const ADDRESS_MODE_CLAMP_TO_BORDER = 0x0000_0000_0200_0000; /// Allows the user to set a non-fill polygon mode in [`PrimitiveState::polygon_mode`] /// /// This allows drawing polygons/triangles as lines (wireframe) or points instead of filled @@ -361,7 +381,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const NON_FILL_POLYGON_MODE = 0x0000_0000_0200_0000; + const NON_FILL_POLYGON_MODE = 0x0000_0000_0400_0000; /// Enables ETC family of compressed textures. All ETC textures use 4x4 pixel blocks. /// ETC2 RGB and RGBA1 are 8 bytes per block. RTC2 RGBA8 and EAC are 16 bytes per block. /// @@ -376,7 +396,7 @@ bitflags::bitflags! { /// - Mobile (some) /// /// This is a native-only feature. - const TEXTURE_COMPRESSION_ETC2 = 0x0000_0000_0400_0000; + const TEXTURE_COMPRESSION_ETC2 = 0x0000_0000_0800_0000; /// Enables ASTC family of compressed textures. ASTC textures use pixel blocks varying from 4x4 to 12x12. /// Blocks are always 16 bytes. /// @@ -391,7 +411,7 @@ bitflags::bitflags! { /// - Mobile (some) /// /// This is a native-only feature. - const TEXTURE_COMPRESSION_ASTC_LDR = 0x0000_0000_0800_0000; + const TEXTURE_COMPRESSION_ASTC_LDR = 0x0000_0000_1000_0000; /// Enables device specific texture format features. /// /// See `TextureFormatFeatures` for a listing of the features in question. @@ -403,7 +423,7 @@ bitflags::bitflags! { /// This extension does not enable additional formats. /// /// This is a native-only feature. - const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 0x0000_0000_1000_0000; + const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 0x0000_0000_2000_0000; /// Enables 64-bit floating point types in SPIR-V shaders. /// /// Note: even when supported by GPU hardware, 64-bit floating point operations are @@ -413,7 +433,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native-only feature. - const SHADER_FLOAT64 = 0x0000_0000_2000_0000; + const SHADER_FLOAT64 = 0x0000_0000_4000_0000; /// Enables using 64-bit types for vertex attributes. /// /// Requires SHADER_FLOAT64. @@ -421,7 +441,7 @@ bitflags::bitflags! { /// Supported Platforms: N/A /// /// This is a native-only feature. - const VERTEX_ATTRIBUTE_64BIT = 0x0000_0000_4000_0000; + const VERTEX_ATTRIBUTE_64BIT = 0x0000_0000_8000_0000; /// Allows the user to set a overestimation-conservative-rasterization in [`PrimitiveState::conservative`] /// /// Processing of degenerate triangles/lines is hardware specific. @@ -432,98 +452,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const CONSERVATIVE_RASTERIZATION = 0x0000_0000_8000_0000; - /// Allows the user to create arrays of buffers in shaders: - /// - /// eg. `uniform myBuffer { .... } buffer_array[10]`. - /// - /// This capability allows them to exist and to be indexed by compile time constant - /// values. - /// - /// 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; + const CONSERVATIVE_RASTERIZATION = 0x0000_0001_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. @@ -532,64 +461,14 @@ bitflags::bitflags! { /// - All /// /// 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: - /// - /// eg. `uniform image2D textures[10]`. - /// - /// This capability allows them to exist and to be indexed by compile time constant - /// values. - /// - /// Supported platforms: - /// - Metal (with MSL 2.2+ on macOS 10.13+) - /// - 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 VERTEX_WRITABLE_STORAGE = 0x0000_0002_0000_0000; /// Enables clear to zero for buffers & images. /// /// Supported platforms: /// - All /// /// This is a native only feature. - const CLEAR_COMMANDS = 0x0000_0200_0000_0000; + const CLEAR_COMMANDS = 0x0000_0400_0000_0000; /// Enables creating shader modules from SPIR-V binary data (unsafe). /// /// SPIR-V data is not parsed or interpreted in any way; you can use @@ -601,7 +480,12 @@ bitflags::bitflags! { /// Vulkan implementation. /// /// This is a native only feature. - const SPIRV_SHADER_PASSTHROUGH = 0x0000_0400_0000_0000; + const SPIRV_SHADER_PASSTHROUGH = 0x0000_0800_0000_0000; + + /// Features which are part of the upstream WebGPU standard. + const ALL_WEBGPU = 0x0000_0000_0000_FFFF; + /// Features that are only available when targeting native (not web). + const ALL_NATIVE = 0xFFFF_FFFF_FFFF_0000; } } 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 {