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.
This commit is contained in:
Alex S
2021-06-19 18:33:57 +03:00
parent ce753cf542
commit 2828100143
6 changed files with 164 additions and 226 deletions

View File

@@ -988,11 +988,20 @@ impl<A: HalApi> Device<A> {
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,

View File

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

View File

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

View File

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

View File

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

View File

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