mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-01-10 22:28:07 -05:00
Use Update After Bind Descriptors for Bind Groups With Binding Arrays (#6815)
* Use Update After Bind Descriptors for Bind Groups With Binding Arrays Update After Bind x * Comments * Fix URL
This commit is contained in:
committed by
GitHub
parent
a45e2db43a
commit
d8833d0798
@@ -391,8 +391,10 @@ pub enum GPUFeatureName {
|
||||
StorageResourceBindingArray,
|
||||
#[webidl(rename = "sampled-texture-and-storage-buffer-array-non-uniform-indexing")]
|
||||
SampledTextureAndStorageBufferArrayNonUniformIndexing,
|
||||
#[webidl(rename = "uniform-buffer-and-storage-texture-array-non-uniform-indexing")]
|
||||
UniformBufferAndStorageTextureArrayNonUniformIndexing,
|
||||
#[webidl(rename = "storage-texture-array-non-uniform-indexing")]
|
||||
StorageTextureArrayNonUniformIndexing,
|
||||
#[webidl(rename = "uniform-buffer-binding-arrays")]
|
||||
UniformBufferBindingArrays,
|
||||
#[webidl(rename = "partially-bound-binding-array")]
|
||||
PartiallyBoundBindingArray,
|
||||
#[webidl(rename = "multi-draw-indirect")]
|
||||
@@ -462,7 +464,8 @@ pub fn feature_names_to_features(names: Vec<GPUFeatureName>) -> wgpu_types::Feat
|
||||
GPUFeatureName::BufferBindingArray => Features::BUFFER_BINDING_ARRAY,
|
||||
GPUFeatureName::StorageResourceBindingArray => Features::STORAGE_RESOURCE_BINDING_ARRAY,
|
||||
GPUFeatureName::SampledTextureAndStorageBufferArrayNonUniformIndexing => Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
||||
GPUFeatureName::UniformBufferAndStorageTextureArrayNonUniformIndexing => Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
GPUFeatureName::StorageTextureArrayNonUniformIndexing => Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
GPUFeatureName::UniformBufferBindingArrays => Features::UNIFORM_BUFFER_BINDING_ARRAYS,
|
||||
GPUFeatureName::PartiallyBoundBindingArray => Features::PARTIALLY_BOUND_BINDING_ARRAY,
|
||||
GPUFeatureName::MultiDrawIndirect => Features::MULTI_DRAW_INDIRECT,
|
||||
GPUFeatureName::MultiDrawIndirectCount => Features::MULTI_DRAW_INDIRECT_COUNT,
|
||||
@@ -575,10 +578,11 @@ pub fn features_to_feature_names(features: wgpu_types::Features) -> HashSet<GPUF
|
||||
) {
|
||||
return_features.insert(SampledTextureAndStorageBufferArrayNonUniformIndexing);
|
||||
}
|
||||
if features.contains(
|
||||
wgpu_types::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
) {
|
||||
return_features.insert(UniformBufferAndStorageTextureArrayNonUniformIndexing);
|
||||
if features.contains(wgpu_types::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING) {
|
||||
return_features.insert(StorageTextureArrayNonUniformIndexing);
|
||||
}
|
||||
if features.contains(wgpu_types::Features::UNIFORM_BUFFER_BINDING_ARRAYS) {
|
||||
return_features.insert(UniformBufferBindingArrays);
|
||||
}
|
||||
if features.contains(wgpu_types::Features::PARTIALLY_BOUND_BINDING_ARRAY) {
|
||||
return_features.insert(PartiallyBoundBindingArray);
|
||||
|
||||
@@ -531,7 +531,8 @@ impl FunctionInfo {
|
||||
..
|
||||
} => {
|
||||
// these are nasty aliases, but these idents are too long and break rustfmt
|
||||
let ub_st = super::Capabilities::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
|
||||
let sto = super::Capabilities::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
|
||||
let uni = super::Capabilities::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING;
|
||||
let st_sb = super::Capabilities::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING;
|
||||
let sampler = super::Capabilities::SAMPLER_NON_UNIFORM_INDEXING;
|
||||
|
||||
@@ -542,7 +543,7 @@ impl FunctionInfo {
|
||||
needed_caps |= match *array_element_ty {
|
||||
// If we're an image, use the appropriate limit.
|
||||
crate::TypeInner::Image { class, .. } => match class {
|
||||
crate::ImageClass::Storage { .. } => ub_st,
|
||||
crate::ImageClass::Storage { .. } => sto,
|
||||
_ => st_sb,
|
||||
},
|
||||
crate::TypeInner::Sampler { .. } => sampler,
|
||||
@@ -551,7 +552,7 @@ impl FunctionInfo {
|
||||
if let E::GlobalVariable(global_handle) = expression_arena[base] {
|
||||
let global = &resolve_context.global_vars[global_handle];
|
||||
match global.space {
|
||||
crate::AddressSpace::Uniform => ub_st,
|
||||
crate::AddressSpace::Uniform => uni,
|
||||
crate::AddressSpace::Storage { .. } => st_sb,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
@@ -90,47 +90,49 @@ bitflags::bitflags! {
|
||||
const PRIMITIVE_INDEX = 1 << 2;
|
||||
/// Support for non-uniform indexing of sampled textures and storage buffer arrays.
|
||||
const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 3;
|
||||
/// Support for non-uniform indexing of uniform buffers and storage texture arrays.
|
||||
const UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 4;
|
||||
/// Support for non-uniform indexing of storage texture arrays.
|
||||
const STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 4;
|
||||
/// Support for non-uniform indexing of uniform buffer arrays.
|
||||
const UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 5;
|
||||
/// Support for non-uniform indexing of samplers.
|
||||
const SAMPLER_NON_UNIFORM_INDEXING = 1 << 5;
|
||||
const SAMPLER_NON_UNIFORM_INDEXING = 1 << 6;
|
||||
/// Support for [`BuiltIn::ClipDistance`].
|
||||
///
|
||||
/// [`BuiltIn::ClipDistance`]: crate::BuiltIn::ClipDistance
|
||||
const CLIP_DISTANCE = 1 << 6;
|
||||
const CLIP_DISTANCE = 1 << 7;
|
||||
/// Support for [`BuiltIn::CullDistance`].
|
||||
///
|
||||
/// [`BuiltIn::CullDistance`]: crate::BuiltIn::CullDistance
|
||||
const CULL_DISTANCE = 1 << 7;
|
||||
const CULL_DISTANCE = 1 << 8;
|
||||
/// Support for 16-bit normalized storage texture formats.
|
||||
const STORAGE_TEXTURE_16BIT_NORM_FORMATS = 1 << 8;
|
||||
const STORAGE_TEXTURE_16BIT_NORM_FORMATS = 1 << 9;
|
||||
/// Support for [`BuiltIn::ViewIndex`].
|
||||
///
|
||||
/// [`BuiltIn::ViewIndex`]: crate::BuiltIn::ViewIndex
|
||||
const MULTIVIEW = 1 << 9;
|
||||
const MULTIVIEW = 1 << 10;
|
||||
/// Support for `early_depth_test`.
|
||||
const EARLY_DEPTH_TEST = 1 << 10;
|
||||
const EARLY_DEPTH_TEST = 1 << 11;
|
||||
/// Support for [`BuiltIn::SampleIndex`] and [`Sampling::Sample`].
|
||||
///
|
||||
/// [`BuiltIn::SampleIndex`]: crate::BuiltIn::SampleIndex
|
||||
/// [`Sampling::Sample`]: crate::Sampling::Sample
|
||||
const MULTISAMPLED_SHADING = 1 << 11;
|
||||
const MULTISAMPLED_SHADING = 1 << 12;
|
||||
/// Support for ray queries and acceleration structures.
|
||||
const RAY_QUERY = 1 << 12;
|
||||
const RAY_QUERY = 1 << 13;
|
||||
/// Support for generating two sources for blending from fragment shaders.
|
||||
const DUAL_SOURCE_BLENDING = 1 << 13;
|
||||
const DUAL_SOURCE_BLENDING = 1 << 14;
|
||||
/// Support for arrayed cube textures.
|
||||
const CUBE_ARRAY_TEXTURES = 1 << 14;
|
||||
const CUBE_ARRAY_TEXTURES = 1 << 15;
|
||||
/// Support for 64-bit signed and unsigned integers.
|
||||
const SHADER_INT64 = 1 << 15;
|
||||
const SHADER_INT64 = 1 << 16;
|
||||
/// Support for subgroup operations.
|
||||
/// Implies support for subgroup operations in both fragment and compute stages,
|
||||
/// but not necessarily in the vertex stage, which requires [`Capabilities::SUBGROUP_VERTEX_STAGE`].
|
||||
const SUBGROUP = 1 << 16;
|
||||
const SUBGROUP = 1 << 17;
|
||||
/// Support for subgroup barriers.
|
||||
const SUBGROUP_BARRIER = 1 << 17;
|
||||
const SUBGROUP_BARRIER = 1 << 18;
|
||||
/// Support for subgroup operations in the vertex stage.
|
||||
const SUBGROUP_VERTEX_STAGE = 1 << 18;
|
||||
const SUBGROUP_VERTEX_STAGE = 1 << 19;
|
||||
/// Support for [`AtomicFunction::Min`] and [`AtomicFunction::Max`] on
|
||||
/// 64-bit integers in the [`Storage`] address space, when the return
|
||||
/// value is not used.
|
||||
@@ -140,9 +142,9 @@ bitflags::bitflags! {
|
||||
/// [`AtomicFunction::Min`]: crate::AtomicFunction::Min
|
||||
/// [`AtomicFunction::Max`]: crate::AtomicFunction::Max
|
||||
/// [`Storage`]: crate::AddressSpace::Storage
|
||||
const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 19;
|
||||
const SHADER_INT64_ATOMIC_MIN_MAX = 1 << 20;
|
||||
/// Support for all atomic operations on 64-bit integers.
|
||||
const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 20;
|
||||
const SHADER_INT64_ATOMIC_ALL_OPS = 1 << 21;
|
||||
/// Support for [`AtomicFunction::Add`], [`AtomicFunction::Sub`],
|
||||
/// and [`AtomicFunction::Exchange { compare: None }`] on 32-bit floating-point numbers
|
||||
/// in the [`Storage`] address space.
|
||||
@@ -151,11 +153,11 @@ bitflags::bitflags! {
|
||||
/// [`AtomicFunction::Sub`]: crate::AtomicFunction::Sub
|
||||
/// [`AtomicFunction::Exchange { compare: None }`]: crate::AtomicFunction::Exchange
|
||||
/// [`Storage`]: crate::AddressSpace::Storage
|
||||
const SHADER_FLOAT32_ATOMIC = 1 << 21;
|
||||
const SHADER_FLOAT32_ATOMIC = 1 << 22;
|
||||
/// Support for atomic operations on images.
|
||||
const TEXTURE_ATOMIC = 1 << 22;
|
||||
const TEXTURE_ATOMIC = 1 << 23;
|
||||
/// Support for atomic operations on 64-bit images.
|
||||
const TEXTURE_INT64_ATOMIC = 1 << 23;
|
||||
const TEXTURE_INT64_ATOMIC = 1 << 24;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,7 @@ use wgpu_test::{gpu_test, FailureCase, GpuTestConfiguration, TestParameters, Tes
|
||||
static BINDING_ARRAY_UNIFORM_BUFFERS: GpuTestConfiguration = GpuTestConfiguration::new()
|
||||
.parameters(
|
||||
TestParameters::default()
|
||||
.features(
|
||||
Features::BUFFER_BINDING_ARRAY
|
||||
| Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
)
|
||||
.features(Features::BUFFER_BINDING_ARRAY | Features::UNIFORM_BUFFER_BINDING_ARRAYS)
|
||||
.limits(Limits {
|
||||
max_uniform_buffers_per_shader_stage: 16,
|
||||
..Limits::default()
|
||||
@@ -31,7 +28,7 @@ static PARTIAL_BINDING_ARRAY_UNIFORM_BUFFERS: GpuTestConfiguration = GpuTestConf
|
||||
.features(
|
||||
Features::BUFFER_BINDING_ARRAY
|
||||
| Features::PARTIALLY_BOUND_BINDING_ARRAY
|
||||
| Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
| Features::UNIFORM_BUFFER_BINDING_ARRAYS,
|
||||
)
|
||||
.limits(Limits {
|
||||
max_uniform_buffers_per_shader_stage: 32,
|
||||
|
||||
@@ -13,7 +13,7 @@ static BINDING_ARRAY_STORAGE_TEXTURES: GpuTestConfiguration = GpuTestConfigurati
|
||||
.features(
|
||||
Features::TEXTURE_BINDING_ARRAY
|
||||
| Features::STORAGE_RESOURCE_BINDING_ARRAY
|
||||
| Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
|
||||
)
|
||||
.limits(Limits {
|
||||
@@ -32,7 +32,7 @@ static PARTIAL_BINDING_ARRAY_STORAGE_TEXTURES: GpuTestConfiguration = GpuTestCon
|
||||
Features::TEXTURE_BINDING_ARRAY
|
||||
| Features::PARTIALLY_BOUND_BINDING_ARRAY
|
||||
| Features::STORAGE_RESOURCE_BINDING_ARRAY
|
||||
| Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
|
||||
)
|
||||
.limits(Limits {
|
||||
|
||||
@@ -392,9 +392,12 @@ pub fn create_validator(
|
||||
.contains(wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING),
|
||||
);
|
||||
caps.set(
|
||||
Caps::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
features
|
||||
.contains(wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING),
|
||||
Caps::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
features.contains(wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING),
|
||||
);
|
||||
caps.set(
|
||||
Caps::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
||||
features.contains(wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS),
|
||||
);
|
||||
// TODO: This needs a proper wgpu feature
|
||||
caps.set(
|
||||
|
||||
@@ -372,7 +372,7 @@ impl super::Adapter {
|
||||
features.set(
|
||||
wgt::Features::TEXTURE_BINDING_ARRAY
|
||||
| wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY
|
||||
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
||||
shader_model >= naga::back::hlsl::ShaderModel::V5_1,
|
||||
);
|
||||
|
||||
@@ -925,7 +925,7 @@ impl super::PrivateCapabilities {
|
||||
features.set(
|
||||
F::TEXTURE_BINDING_ARRAY
|
||||
| F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
|
||||
| F::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| F::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| F::PARTIALLY_BOUND_BINDING_ARRAY,
|
||||
self.msl_version >= MTLLanguageVersion::V3_0
|
||||
&& self.supports_arrays_of_textures
|
||||
|
||||
@@ -12,7 +12,8 @@ fn depth_stencil_required_flags() -> vk::FormatFeatureFlags {
|
||||
//TODO: const fn?
|
||||
fn indexing_features() -> wgt::Features {
|
||||
wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
|
||||
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS
|
||||
| wgt::Features::PARTIALLY_BOUND_BINDING_ARRAY
|
||||
}
|
||||
|
||||
@@ -217,14 +218,12 @@ impl PhysicalDeviceFeatures {
|
||||
| wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY
|
||||
| wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
||||
);
|
||||
let needs_uniform_buffer_non_uniform = requested_features.contains(
|
||||
wgt::Features::TEXTURE_BINDING_ARRAY
|
||||
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
);
|
||||
let needs_uniform_buffer_non_uniform =
|
||||
requested_features.contains(wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS);
|
||||
let needs_storage_image_non_uniform = requested_features.contains(
|
||||
wgt::Features::TEXTURE_BINDING_ARRAY
|
||||
| wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY
|
||||
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
| wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
);
|
||||
let needs_partially_bound =
|
||||
requested_features.intersects(wgt::Features::PARTIALLY_BOUND_BINDING_ARRAY);
|
||||
@@ -498,7 +497,6 @@ impl PhysicalDeviceFeatures {
|
||||
phd: vk::PhysicalDevice,
|
||||
caps: &PhysicalDeviceProperties,
|
||||
) -> (wgt::Features, wgt::DownlevelFlags) {
|
||||
use crate::auxil::db;
|
||||
use wgt::{DownlevelFlags as Df, Features as F};
|
||||
let mut features = F::empty()
|
||||
| F::SPIRV_SHADER_PASSTHROUGH
|
||||
@@ -583,31 +581,13 @@ impl PhysicalDeviceFeatures {
|
||||
F::VERTEX_WRITABLE_STORAGE,
|
||||
self.core.vertex_pipeline_stores_and_atomics != 0,
|
||||
);
|
||||
//if self.core.shader_image_gather_extended != 0 {
|
||||
//if self.core.shader_storage_image_extended_formats != 0 {
|
||||
features.set(
|
||||
F::BUFFER_BINDING_ARRAY,
|
||||
self.core.shader_uniform_buffer_array_dynamic_indexing != 0,
|
||||
);
|
||||
features.set(
|
||||
F::TEXTURE_BINDING_ARRAY,
|
||||
self.core.shader_sampled_image_array_dynamic_indexing != 0,
|
||||
);
|
||||
features.set(F::SHADER_PRIMITIVE_INDEX, self.core.geometry_shader != 0);
|
||||
features.set(
|
||||
F::STORAGE_RESOURCE_BINDING_ARRAY,
|
||||
(features.contains(F::BUFFER_BINDING_ARRAY)
|
||||
&& self.core.shader_storage_buffer_array_dynamic_indexing != 0)
|
||||
|| (features.contains(F::TEXTURE_BINDING_ARRAY)
|
||||
&& self.core.shader_storage_image_array_dynamic_indexing != 0),
|
||||
);
|
||||
//if self.core.shader_storage_image_array_dynamic_indexing != 0 {
|
||||
//if self.core.shader_clip_distance != 0 {
|
||||
//if self.core.shader_cull_distance != 0 {
|
||||
|
||||
features.set(F::SHADER_F64, self.core.shader_float64 != 0);
|
||||
features.set(F::SHADER_INT64, self.core.shader_int64 != 0);
|
||||
features.set(F::SHADER_I16, self.core.shader_int16 != 0);
|
||||
|
||||
features.set(F::SHADER_PRIMITIVE_INDEX, self.core.geometry_shader != 0);
|
||||
|
||||
if let Some(ref shader_atomic_int64) = self.shader_atomic_int64 {
|
||||
features.set(
|
||||
F::SHADER_INT64_ATOMIC_ALL_OPS | F::SHADER_INT64_ATOMIC_MIN_MAX,
|
||||
@@ -645,29 +625,38 @@ impl PhysicalDeviceFeatures {
|
||||
caps.supports_extension(ext::conservative_rasterization::NAME),
|
||||
);
|
||||
|
||||
let intel_windows = caps.properties.vendor_id == db::intel::VENDOR && cfg!(windows);
|
||||
|
||||
if let Some(ref descriptor_indexing) = self.descriptor_indexing {
|
||||
const STORAGE: F = F::STORAGE_RESOURCE_BINDING_ARRAY;
|
||||
features.set(
|
||||
F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
||||
(features.contains(F::TEXTURE_BINDING_ARRAY)
|
||||
&& descriptor_indexing.shader_sampled_image_array_non_uniform_indexing != 0)
|
||||
&& (features.contains(F::BUFFER_BINDING_ARRAY | STORAGE)
|
||||
&& descriptor_indexing.shader_storage_buffer_array_non_uniform_indexing
|
||||
!= 0),
|
||||
);
|
||||
features.set(
|
||||
F::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
(features.contains(F::BUFFER_BINDING_ARRAY)
|
||||
&& descriptor_indexing.shader_uniform_buffer_array_non_uniform_indexing != 0)
|
||||
&& (features.contains(F::TEXTURE_BINDING_ARRAY | STORAGE)
|
||||
&& descriptor_indexing.shader_storage_image_array_non_uniform_indexing
|
||||
!= 0),
|
||||
);
|
||||
if descriptor_indexing.descriptor_binding_partially_bound != 0 && !intel_windows {
|
||||
features |= F::PARTIALLY_BOUND_BINDING_ARRAY;
|
||||
}
|
||||
// We use update-after-bind descriptors for all bind groups containing binding arrays.
|
||||
//
|
||||
// In those bind groups, we allow all binding types except uniform buffers to be present.
|
||||
//
|
||||
// As we can only switch between update-after-bind and not on a per bind group basis,
|
||||
// all supported binding types need to be able to be marked update after bind.
|
||||
//
|
||||
// As such, we enable all features as a whole, rather individually.
|
||||
let supports_descriptor_indexing =
|
||||
// Sampled Images
|
||||
descriptor_indexing.shader_sampled_image_array_non_uniform_indexing != 0
|
||||
&& descriptor_indexing.descriptor_binding_sampled_image_update_after_bind != 0
|
||||
// Storage Images
|
||||
&& descriptor_indexing.shader_storage_image_array_non_uniform_indexing != 0
|
||||
&& descriptor_indexing.descriptor_binding_storage_image_update_after_bind != 0
|
||||
// Storage Buffers
|
||||
&& descriptor_indexing.shader_storage_buffer_array_non_uniform_indexing != 0
|
||||
&& descriptor_indexing.descriptor_binding_storage_buffer_update_after_bind != 0;
|
||||
|
||||
let descriptor_indexing_features = F::BUFFER_BINDING_ARRAY
|
||||
| F::TEXTURE_BINDING_ARRAY
|
||||
| F::STORAGE_RESOURCE_BINDING_ARRAY
|
||||
| F::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
|
||||
| F::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
|
||||
|
||||
features.set(descriptor_indexing_features, supports_descriptor_indexing);
|
||||
|
||||
let supports_partially_bound =
|
||||
descriptor_indexing.descriptor_binding_partially_bound != 0;
|
||||
|
||||
features.set(F::PARTIALLY_BOUND_BINDING_ARRAY, supports_partially_bound);
|
||||
}
|
||||
|
||||
features.set(F::DEPTH_CLIP_CONTROL, self.core.depth_clamp != 0);
|
||||
@@ -1835,7 +1824,8 @@ impl super::Adapter {
|
||||
|
||||
if features.intersects(
|
||||
wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING
|
||||
| wgt::Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||
| wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING
|
||||
| wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS,
|
||||
) {
|
||||
capabilities.push(spv::Capability::ShaderNonUniform);
|
||||
}
|
||||
|
||||
@@ -1611,11 +1611,19 @@ impl crate::Device for super::Device {
|
||||
super::AccelerationStructure,
|
||||
>,
|
||||
) -> Result<super::BindGroup, crate::DeviceError> {
|
||||
let contains_binding_arrays = !desc.layout.binding_arrays.is_empty();
|
||||
|
||||
let desc_set_layout_flags = if contains_binding_arrays {
|
||||
gpu_descriptor::DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND
|
||||
} else {
|
||||
gpu_descriptor::DescriptorSetLayoutCreateFlags::empty()
|
||||
};
|
||||
|
||||
let mut vk_sets = unsafe {
|
||||
self.desc_allocator.lock().allocate(
|
||||
&*self.shared,
|
||||
&desc.layout.raw,
|
||||
gpu_descriptor::DescriptorSetLayoutCreateFlags::empty(),
|
||||
desc_set_layout_flags,
|
||||
&desc.layout.desc_count,
|
||||
1,
|
||||
)?
|
||||
|
||||
@@ -756,31 +756,17 @@ bitflags_array! {
|
||||
///
|
||||
/// This is a native only feature.
|
||||
const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 1 << 11;
|
||||
/// Allows shaders to index uniform buffer and storage texture resource arrays with dynamically non-uniform values:
|
||||
/// Allows shaders to index storage texture resource arrays with dynamically non-uniform values:
|
||||
///
|
||||
/// ex. `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:
|
||||
///
|
||||
/// ex. `layout(location = 0) nonuniformEXT flat in int vertex_data;`
|
||||
///
|
||||
/// or as `nonuniformEXT` constructor:
|
||||
///
|
||||
/// ex. `texture_array[nonuniformEXT(vertex_data)]`
|
||||
///
|
||||
/// WGSL and HLSL do 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)
|
||||
/// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s shaderStorageTextureArrayNonUniformIndexing feature)
|
||||
///
|
||||
/// This is a native only feature.
|
||||
const UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 12;
|
||||
const STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 1 << 12;
|
||||
/// Allows the user to create bind groups containing arrays with less bindings than the BindGroupLayout.
|
||||
///
|
||||
/// Supported platforms:
|
||||
@@ -1151,6 +1137,22 @@ bitflags_array! {
|
||||
/// This is a native only feature.
|
||||
const TEXTURE_INT64_ATOMIC = 1 << 45;
|
||||
|
||||
/// Allows uniform buffers to be bound as binding arrays.
|
||||
///
|
||||
/// This allows:
|
||||
/// - Shaders to contain `var<uniform> buffer: binding_array<UniformBuffer>;`
|
||||
/// - The `count` field of `BindGroupLayoutEntry`s with `Uniform` buffers, to be set to `Some`.
|
||||
///
|
||||
/// Supported platforms:
|
||||
/// - None (<https://github.com/gfx-rs/wgpu/issues/7149>)
|
||||
///
|
||||
/// Potential Platforms:
|
||||
/// - DX12
|
||||
/// - Metal
|
||||
/// - Vulkan 1.2+ (or VK_EXT_descriptor_indexing)'s `shaderUniformBufferArrayNonUniformIndexing` feature)
|
||||
///
|
||||
/// This is a native only feature.
|
||||
const UNIFORM_BUFFER_BINDING_ARRAYS = 1 << 46;
|
||||
}
|
||||
|
||||
/// Features that are not guaranteed to be supported.
|
||||
|
||||
Reference in New Issue
Block a user