Splits non-uniform indexing into two different features (#1785)

This commit is contained in:
Connor Fitzgerald 2021-08-10 22:43:08 -04:00 committed by GitHub
parent a60d2f6f3b
commit 3afab9c5aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 48 deletions

View File

@ -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

View File

@ -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;

View File

@ -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));
}
}
}

View File

@ -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;
}
}

View File

@ -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,