From 3afab9c5aaba0f87be539fc656c3aabf245d2503 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Tue, 10 Aug 2021 22:43:08 -0400 Subject: [PATCH] Splits non-uniform indexing into two different features (#1785) --- wgpu-hal/src/metal/adapter.rs | 4 +- wgpu-hal/src/vulkan/adapter.rs | 54 ++++++++++++++--------- wgpu-info/src/main.rs | 2 +- wgpu-types/src/lib.rs | 66 ++++++++++++++++++---------- wgpu/examples/texture-arrays/main.rs | 11 +++-- 5 files changed, 89 insertions(+), 48 deletions(-) diff --git a/wgpu-hal/src/metal/adapter.rs b/wgpu-hal/src/metal/adapter.rs index 6456510f..878f39a4 100644 --- a/wgpu-hal/src/metal/adapter.rs +++ b/wgpu-hal/src/metal/adapter.rs @@ -864,7 +864,9 @@ impl super::PrivateCapabilities { | F::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES; features.set( - F::TEXTURE_BINDING_ARRAY | F::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + F::TEXTURE_BINDING_ARRAY + | F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING + | F::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_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 diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index e97dec93..f6e84cd3 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -138,28 +138,28 @@ impl PhysicalDeviceFeatures { .shader_sampled_image_array_non_uniform_indexing( requested_features.contains( wgt::Features::TEXTURE_BINDING_ARRAY - | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + | wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, ), ) .shader_storage_image_array_non_uniform_indexing( requested_features.contains( wgt::Features::TEXTURE_BINDING_ARRAY | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY - | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + | wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, ), ) //.shader_storage_buffer_array_non_uniform_indexing( .shader_uniform_buffer_array_non_uniform_indexing( requested_features.contains( wgt::Features::BUFFER_BINDING_ARRAY - | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + | wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_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, + | wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, ), ) .runtime_descriptor_array( @@ -181,28 +181,28 @@ impl PhysicalDeviceFeatures { .shader_sampled_image_array_non_uniform_indexing( requested_features.contains( wgt::Features::TEXTURE_BINDING_ARRAY - | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + | wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, ), ) .shader_storage_image_array_non_uniform_indexing( requested_features.contains( wgt::Features::TEXTURE_BINDING_ARRAY | wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY - | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + | wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, ), ) //.shader_storage_buffer_array_non_uniform_indexing( .shader_uniform_buffer_array_non_uniform_indexing( requested_features.contains( wgt::Features::BUFFER_BINDING_ARRAY - | wgt::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + | wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_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, + | wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, ), ) .runtime_descriptor_array( @@ -330,10 +330,6 @@ impl PhysicalDeviceFeatures { 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, @@ -342,13 +338,24 @@ impl PhysicalDeviceFeatures { F::BUFFER_BINDING_ARRAY | STORAGE, vulkan_1_2.shader_storage_buffer_array_non_uniform_indexing, ), + ], + ) { + features.insert(F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING); + } + if Self::all_features_supported( + &features, + &[ ( - F::TEXTURE_BINDING_ARRAY | STORAGE, - vulkan_1_2.shader_storage_image_array_non_uniform_indexing, + F::BUFFER_BINDING_ARRAY, + vulkan_1_2.shader_uniform_buffer_array_non_uniform_indexing, + ), + ( + F::BUFFER_BINDING_ARRAY | STORAGE, + vulkan_1_2.shader_storage_buffer_array_non_uniform_indexing, ), ], ) { - features.insert(F::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING); + features.insert(F::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING); } if vulkan_1_2.runtime_descriptor_array != 0 { features |= F::UNSIZED_BINDING_ARRAY; @@ -365,10 +372,6 @@ impl PhysicalDeviceFeatures { 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, @@ -377,13 +380,24 @@ impl PhysicalDeviceFeatures { F::BUFFER_BINDING_ARRAY | STORAGE, descriptor_indexing.shader_storage_buffer_array_non_uniform_indexing, ), + ], + ) { + features.insert(F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING); + } + if Self::all_features_supported( + &features, + &[ + ( + F::BUFFER_BINDING_ARRAY, + descriptor_indexing.shader_uniform_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); + features.insert(F::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING); } if descriptor_indexing.runtime_descriptor_array != 0 { features |= F::UNSIZED_BINDING_ARRAY; diff --git a/wgpu-info/src/main.rs b/wgpu-info/src/main.rs index 77fc4777..1c69e61a 100644 --- a/wgpu-info/src/main.rs +++ b/wgpu-info/src/main.rs @@ -24,7 +24,7 @@ fn print_info_from_adapter(adapter: &wgpu::Adapter, idx: usize) { let bit = wgpu::Features::from_bits(1 << i as u64); if let Some(bit) = bit { if wgpu::Features::all().contains(bit) { - println!("\t\t{:<44} {}", format!("{:?}:", bit), features.contains(bit)); + println!("\t\t{:<63} {}", format!("{:?}:", bit), features.contains(bit)); } } } diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 37d46d00..871d3ca0 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -285,7 +285,7 @@ bitflags::bitflags! { /// /// This is a native only feature. const STORAGE_RESOURCE_BINDING_ARRAY = 1 << 19; - /// Allows shaders to index resource arrays with dynamically non-uniform values: + /// Allows shaders to index sampled texture and storage buffer resource arrays with dynamically non-uniform values: /// /// eg. `texture_array[vertex_data]` /// @@ -306,23 +306,45 @@ bitflags::bitflags! { /// Supported platforms: /// - DX12 /// - Metal (with MSL 2.0+ on macOS 10.13+) - /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderSampledImageArrayNonUniformIndexing feature) + /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderSampledImageArrayNonUniformIndexing & shaderStorageBufferArrayNonUniformIndexing feature) /// /// This is a native only feature. - const RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING = 1 << 20; + const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 20; + /// Allows shaders to index uniform buffer and storage texture resource 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)]` + /// + /// HLSL does 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) + /// + /// This is a native only feature. + const UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 21; /// Allows the user to create unsized uniform arrays of bindings: /// /// eg. `uniform texture2D textures[]`. /// - /// If this capability is supported, [`Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING`] is very likely - /// to also be supported - /// /// Supported platforms: /// - DX12 /// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s runtimeDescriptorArray feature /// /// This is a native only feature. - const UNSIZED_BINDING_ARRAY = 1 << 21; + const UNSIZED_BINDING_ARRAY = 1 << 22; /// 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. @@ -332,7 +354,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const MULTI_DRAW_INDIRECT = 1 << 22; + const MULTI_DRAW_INDIRECT = 1 << 23; /// 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. @@ -342,7 +364,7 @@ bitflags::bitflags! { /// - Vulkan 1.2+ (or VK_KHR_draw_indirect_count) /// /// This is a native only feature. - const MULTI_DRAW_INDIRECT_COUNT = 1 << 23; + const MULTI_DRAW_INDIRECT_COUNT = 1 << 24; /// Allows the use of push constants: small, fast bits of memory that can be updated /// inside a [`RenderPass`]. /// @@ -359,7 +381,7 @@ bitflags::bitflags! { /// - OpenGL (emulated with uniforms) /// /// This is a native only feature. - const PUSH_CONSTANTS = 1 << 24; + const PUSH_CONSTANTS = 1 << 25; /// Allows the use of [`AddressMode::ClampToBorder`]. /// /// Supported platforms: @@ -370,7 +392,7 @@ bitflags::bitflags! { /// - OpenGL /// /// This is a web and native feature. - const ADDRESS_MODE_CLAMP_TO_BORDER = 1 << 25; + const ADDRESS_MODE_CLAMP_TO_BORDER = 1 << 26; /// 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 @@ -380,7 +402,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const NON_FILL_POLYGON_MODE = 1 << 26; + const NON_FILL_POLYGON_MODE = 1 << 27; /// 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. /// @@ -395,7 +417,7 @@ bitflags::bitflags! { /// - Mobile (some) /// /// This is a native-only feature. - const TEXTURE_COMPRESSION_ETC2 = 1 << 27; + const TEXTURE_COMPRESSION_ETC2 = 1 << 28; /// Enables ASTC family of compressed textures. ASTC textures use pixel blocks varying from 4x4 to 12x12. /// Blocks are always 16 bytes. /// @@ -410,7 +432,7 @@ bitflags::bitflags! { /// - Mobile (some) /// /// This is a native-only feature. - const TEXTURE_COMPRESSION_ASTC_LDR = 1 << 28; + const TEXTURE_COMPRESSION_ASTC_LDR = 1 << 29; /// Enables device specific texture format features. /// /// See `TextureFormatFeatures` for a listing of the features in question. @@ -422,7 +444,7 @@ bitflags::bitflags! { /// This extension does not enable additional formats. /// /// This is a native-only feature. - const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 1 << 29; + const TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES = 1 << 30; /// Enables 64-bit floating point types in SPIR-V shaders. /// /// Note: even when supported by GPU hardware, 64-bit floating point operations are @@ -432,7 +454,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native-only feature. - const SHADER_FLOAT64 = 1 << 30; + const SHADER_FLOAT64 = 1 << 31; /// Enables using 64-bit types for vertex attributes. /// /// Requires SHADER_FLOAT64. @@ -440,7 +462,7 @@ bitflags::bitflags! { /// Supported Platforms: N/A /// /// This is a native-only feature. - const VERTEX_ATTRIBUTE_64BIT = 1 << 31; + const VERTEX_ATTRIBUTE_64BIT = 1 << 32; /// Allows the user to set a overestimation-conservative-rasterization in [`PrimitiveState::conservative`] /// /// Processing of degenerate triangles/lines is hardware specific. @@ -450,7 +472,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const CONSERVATIVE_RASTERIZATION = 1 << 32; + const CONSERVATIVE_RASTERIZATION = 1 << 33; /// 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. @@ -459,14 +481,14 @@ bitflags::bitflags! { /// - All /// /// This is a native-only feature. - const VERTEX_WRITABLE_STORAGE = 1 << 33; + const VERTEX_WRITABLE_STORAGE = 1 << 34; /// Enables clear to zero for buffers & images. /// /// Supported platforms: /// - All /// /// This is a native only feature. - const CLEAR_COMMANDS = 1 << 34; + const CLEAR_COMMANDS = 1 << 35; /// Enables creating shader modules from SPIR-V binary data (unsafe). /// /// SPIR-V data is not parsed or interpreted in any way; you can use @@ -478,7 +500,7 @@ bitflags::bitflags! { /// Vulkan implementation. /// /// This is a native only feature. - const SPIRV_SHADER_PASSTHROUGH = 1 << 35; + const SPIRV_SHADER_PASSTHROUGH = 1 << 36; /// Enables `builtin(primitive_index)` in fragment shaders. /// /// Note: enables geometry processing for pipelines using the builtin. @@ -489,7 +511,7 @@ bitflags::bitflags! { /// - Vulkan /// /// This is a native only feature. - const SHADER_PRIMITIVE_INDEX = 1 << 36; + const SHADER_PRIMITIVE_INDEX = 1 << 37; } } diff --git a/wgpu/examples/texture-arrays/main.rs b/wgpu/examples/texture-arrays/main.rs index 9f498bab..dd86e6cf 100644 --- a/wgpu/examples/texture-arrays/main.rs +++ b/wgpu/examples/texture-arrays/main.rs @@ -72,7 +72,7 @@ struct Example { impl framework::Example for Example { fn optional_features() -> wgpu::Features { wgpu::Features::UNSIZED_BINDING_ARRAY - | wgpu::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING + | wgpu::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING | wgpu::Features::PUSH_CONSTANTS } fn required_features() -> wgpu::Features { @@ -96,7 +96,10 @@ impl framework::Example for Example { 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) => { + f if f.contains( + wgpu::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, + ) => + { wgpu::include_spirv_raw!("non-uniform.frag.spv") } f if f.contains(wgpu::Features::TEXTURE_BINDING_ARRAY) => { @@ -355,7 +358,7 @@ fn texture_arrays_non_uniform() { width: 1024, height: 768, optional_features: wgpu::Features::TEXTURE_BINDING_ARRAY - | wgpu::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING, + | wgpu::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, base_test_parameters: framework::test_common::TestParameters::default().failure(), tolerance: 0, max_outliers: 0, @@ -370,7 +373,7 @@ fn texture_arrays_unsized_non_uniform() { width: 1024, height: 768, optional_features: wgpu::Features::TEXTURE_BINDING_ARRAY - | wgpu::Features::RESOURCE_BINDING_ARRAY_NON_UNIFORM_INDEXING + | wgpu::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING | wgpu::Features::UNSIZED_BINDING_ARRAY, base_test_parameters: framework::test_common::TestParameters::default().failure(), tolerance: 0,