mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
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:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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) };
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user