mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 23:04:07 +00:00
Added storage texture array support.
I also took the liberty to refactor texture format checking a bit, and tighten up sampled texture support detection for Metal as well.
This commit is contained in:
parent
ca291bfc4f
commit
52fab481e6
@ -982,7 +982,7 @@ impl<A: HalApi> Device<A> {
|
|||||||
Bt::Sampler { .. } => (None, false),
|
Bt::Sampler { .. } => (None, false),
|
||||||
Bt::Texture { .. } => (Some(wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY), false),
|
Bt::Texture { .. } => (Some(wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY), false),
|
||||||
Bt::StorageTexture { access, .. } => (
|
Bt::StorageTexture { access, .. } => (
|
||||||
None,
|
Some(wgt::Features::STORAGE_TEXTURE_BINDING_ARRAY),
|
||||||
match access {
|
match access {
|
||||||
wgt::StorageTextureAccess::ReadOnly => false,
|
wgt::StorageTextureAccess::ReadOnly => false,
|
||||||
wgt::StorageTextureAccess::WriteOnly => true,
|
wgt::StorageTextureAccess::WriteOnly => true,
|
||||||
@ -1304,104 +1304,13 @@ impl<A: HalApi> Device<A> {
|
|||||||
.views
|
.views
|
||||||
.use_extend(&*texture_view_guard, id, (), ())
|
.use_extend(&*texture_view_guard, id, (), ())
|
||||||
.map_err(|_| Error::InvalidTextureView(id))?;
|
.map_err(|_| Error::InvalidTextureView(id))?;
|
||||||
let format_info = view.desc.format.describe();
|
let (pub_usage, internal_use) = Self::texture_use_parameters(
|
||||||
let (pub_usage, internal_use) = match decl.ty {
|
binding,
|
||||||
wgt::BindingType::Texture {
|
decl,
|
||||||
sample_type,
|
view,
|
||||||
view_dimension,
|
"SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture",
|
||||||
multisampled,
|
)?;
|
||||||
} => {
|
|
||||||
use wgt::TextureSampleType as Tst;
|
|
||||||
if multisampled != (view.samples != 1) {
|
|
||||||
return Err(Error::InvalidTextureMultisample {
|
|
||||||
binding,
|
|
||||||
layout_multisampled: multisampled,
|
|
||||||
view_samples: view.samples,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
match (sample_type, format_info.sample_type, view.format_features.filterable ) {
|
|
||||||
(Tst::Uint, Tst::Uint, ..) |
|
|
||||||
(Tst::Sint, Tst::Sint, ..) |
|
|
||||||
(Tst::Depth, Tst::Depth, ..) |
|
|
||||||
// if we expect non-filterable, accept anything float
|
|
||||||
(Tst::Float { filterable: false }, Tst::Float { .. }, ..) |
|
|
||||||
// if we expect filterable, require it
|
|
||||||
(Tst::Float { filterable: true }, Tst::Float { filterable: true }, ..) |
|
|
||||||
// if we expect filterable, also accept Float that is defined as unfilterable if filterable feature is explicitly enabled
|
|
||||||
// (only hit if wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES is enabled)
|
|
||||||
(Tst::Float { filterable: true }, Tst::Float { .. }, true) |
|
|
||||||
// if we expect float, also accept depth
|
|
||||||
(Tst::Float { .. }, Tst::Depth, ..) => {}
|
|
||||||
_ => {
|
|
||||||
return Err(Error::InvalidTextureSampleType {
|
|
||||||
binding,
|
|
||||||
layout_sample_type: sample_type,
|
|
||||||
view_format: view.desc.format,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if view_dimension != view.desc.dimension {
|
|
||||||
return Err(Error::InvalidTextureDimension {
|
|
||||||
binding,
|
|
||||||
layout_dimension: view_dimension,
|
|
||||||
view_dimension: view.desc.dimension,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
(wgt::TextureUsage::SAMPLED, view.sampled_internal_use)
|
|
||||||
}
|
|
||||||
wgt::BindingType::StorageTexture {
|
|
||||||
access,
|
|
||||||
format,
|
|
||||||
view_dimension,
|
|
||||||
} => {
|
|
||||||
if format != view.desc.format {
|
|
||||||
return Err(Error::InvalidStorageTextureFormat {
|
|
||||||
binding,
|
|
||||||
layout_format: format,
|
|
||||||
view_format: view.desc.format,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if view_dimension != view.desc.dimension {
|
|
||||||
return Err(Error::InvalidTextureDimension {
|
|
||||||
binding,
|
|
||||||
layout_dimension: view_dimension,
|
|
||||||
view_dimension: view.desc.dimension,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let internal_use = match access {
|
|
||||||
wgt::StorageTextureAccess::ReadOnly => {
|
|
||||||
hal::TextureUse::STORAGE_LOAD
|
|
||||||
}
|
|
||||||
wgt::StorageTextureAccess::WriteOnly => {
|
|
||||||
hal::TextureUse::STORAGE_STORE
|
|
||||||
}
|
|
||||||
wgt::StorageTextureAccess::ReadWrite => {
|
|
||||||
if !view.format_features.flags.contains(
|
|
||||||
wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE,
|
|
||||||
) {
|
|
||||||
return Err(Error::StorageReadWriteNotSupported(
|
|
||||||
view.desc.format,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
hal::TextureUse::STORAGE_STORE | hal::TextureUse::STORAGE_LOAD
|
|
||||||
}
|
|
||||||
};
|
|
||||||
(wgt::TextureUsage::STORAGE, internal_use)
|
|
||||||
}
|
|
||||||
_ => return Err(Error::WrongBindingType {
|
|
||||||
binding,
|
|
||||||
actual: decl.ty,
|
|
||||||
expected:
|
|
||||||
"SampledTexture, ReadonlyStorageTexture or WriteonlyStorageTexture",
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
if hal::FormatAspect::from(view.desc.format)
|
|
||||||
.contains(hal::FormatAspect::DEPTH | hal::FormatAspect::STENCIL)
|
|
||||||
{
|
|
||||||
return Err(Error::DepthStencilAspect);
|
|
||||||
}
|
|
||||||
match view.source {
|
match view.source {
|
||||||
resource::TextureViewSource::Native(ref source_id) => {
|
resource::TextureViewSource::Native(ref source_id) => {
|
||||||
// Careful here: the texture may no longer have its own ref count,
|
// Careful here: the texture may no longer have its own ref count,
|
||||||
@ -1449,18 +1358,10 @@ impl<A: HalApi> Device<A> {
|
|||||||
.views
|
.views
|
||||||
.use_extend(&*texture_view_guard, id, (), ())
|
.use_extend(&*texture_view_guard, id, (), ())
|
||||||
.map_err(|_| Error::InvalidTextureView(id))?;
|
.map_err(|_| Error::InvalidTextureView(id))?;
|
||||||
let (pub_usage, internal_use) = match decl.ty {
|
let (pub_usage, internal_use) =
|
||||||
wgt::BindingType::Texture { .. } => {
|
Self::texture_use_parameters(binding, decl, view,
|
||||||
(wgt::TextureUsage::SAMPLED, view.sampled_internal_use)
|
"SampledTextureArray, ReadonlyStorageTextureArray or WriteonlyStorageTextureArray"
|
||||||
}
|
)?;
|
||||||
_ => {
|
|
||||||
return Err(Error::WrongBindingType {
|
|
||||||
binding,
|
|
||||||
actual: decl.ty,
|
|
||||||
expected: "SampledTextureArray",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
match view.source {
|
match view.source {
|
||||||
resource::TextureViewSource::Native(ref source_id) => {
|
resource::TextureViewSource::Native(ref source_id) => {
|
||||||
@ -1533,6 +1434,109 @@ impl<A: HalApi> Device<A> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn texture_use_parameters(
|
||||||
|
binding: u32,
|
||||||
|
decl: &wgt::BindGroupLayoutEntry,
|
||||||
|
view: &crate::resource::TextureView<A>,
|
||||||
|
expected: &'static str,
|
||||||
|
) -> Result<(wgt::TextureUsage, hal::TextureUse), binding_model::CreateBindGroupError> {
|
||||||
|
use crate::binding_model::CreateBindGroupError as Error;
|
||||||
|
if hal::FormatAspect::from(view.desc.format)
|
||||||
|
.contains(hal::FormatAspect::DEPTH | hal::FormatAspect::STENCIL)
|
||||||
|
{
|
||||||
|
return Err(Error::DepthStencilAspect);
|
||||||
|
}
|
||||||
|
let format_info = view.desc.format.describe();
|
||||||
|
match decl.ty {
|
||||||
|
wgt::BindingType::Texture {
|
||||||
|
sample_type,
|
||||||
|
view_dimension,
|
||||||
|
multisampled,
|
||||||
|
} => {
|
||||||
|
use wgt::TextureSampleType as Tst;
|
||||||
|
if multisampled != (view.samples != 1) {
|
||||||
|
return Err(Error::InvalidTextureMultisample {
|
||||||
|
binding,
|
||||||
|
layout_multisampled: multisampled,
|
||||||
|
view_samples: view.samples,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
match (sample_type, format_info.sample_type, view.format_features.filterable) {
|
||||||
|
(Tst::Uint, Tst::Uint, ..) |
|
||||||
|
(Tst::Sint, Tst::Sint, ..) |
|
||||||
|
(Tst::Depth, Tst::Depth, ..) |
|
||||||
|
// if we expect non-filterable, accept anything float
|
||||||
|
(Tst::Float { filterable: false }, Tst::Float { .. }, ..) |
|
||||||
|
// if we expect filterable, require it
|
||||||
|
(Tst::Float { filterable: true }, Tst::Float { filterable: true }, ..) |
|
||||||
|
// if we expect filterable, also accept Float that is defined as unfilterable if filterable feature is explicitly enabled
|
||||||
|
// (only hit if wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES is enabled)
|
||||||
|
(Tst::Float { filterable: true }, Tst::Float { .. }, true) |
|
||||||
|
// if we expect float, also accept depth
|
||||||
|
(Tst::Float { .. }, Tst::Depth, ..) => {}
|
||||||
|
_ => {
|
||||||
|
return Err(Error::InvalidTextureSampleType {
|
||||||
|
binding,
|
||||||
|
layout_sample_type: sample_type,
|
||||||
|
view_format: view.desc.format,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if view_dimension != view.desc.dimension {
|
||||||
|
return Err(Error::InvalidTextureDimension {
|
||||||
|
binding,
|
||||||
|
layout_dimension: view_dimension,
|
||||||
|
view_dimension: view.desc.dimension,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok((wgt::TextureUsage::SAMPLED, view.sampled_internal_use))
|
||||||
|
}
|
||||||
|
wgt::BindingType::StorageTexture {
|
||||||
|
access,
|
||||||
|
format,
|
||||||
|
view_dimension,
|
||||||
|
} => {
|
||||||
|
if format != view.desc.format {
|
||||||
|
return Err(Error::InvalidStorageTextureFormat {
|
||||||
|
binding,
|
||||||
|
layout_format: format,
|
||||||
|
view_format: view.desc.format,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if view_dimension != view.desc.dimension {
|
||||||
|
return Err(Error::InvalidTextureDimension {
|
||||||
|
binding,
|
||||||
|
layout_dimension: view_dimension,
|
||||||
|
view_dimension: view.desc.dimension,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let internal_use = match access {
|
||||||
|
wgt::StorageTextureAccess::ReadOnly => hal::TextureUse::STORAGE_LOAD,
|
||||||
|
wgt::StorageTextureAccess::WriteOnly => hal::TextureUse::STORAGE_STORE,
|
||||||
|
wgt::StorageTextureAccess::ReadWrite => {
|
||||||
|
if !view
|
||||||
|
.format_features
|
||||||
|
.flags
|
||||||
|
.contains(wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE)
|
||||||
|
{
|
||||||
|
return Err(Error::StorageReadWriteNotSupported(view.desc.format));
|
||||||
|
}
|
||||||
|
|
||||||
|
hal::TextureUse::STORAGE_STORE | hal::TextureUse::STORAGE_LOAD
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok((wgt::TextureUsage::STORAGE, internal_use))
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(Error::WrongBindingType {
|
||||||
|
binding,
|
||||||
|
actual: decl.ty,
|
||||||
|
expected,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn create_pipeline_layout(
|
fn create_pipeline_layout(
|
||||||
&self,
|
&self,
|
||||||
self_id: id::DeviceId,
|
self_id: id::DeviceId,
|
||||||
|
@ -817,6 +817,22 @@ impl super::PrivateCapabilities {
|
|||||||
} else {
|
} else {
|
||||||
Self::version_at_least(major, minor, 11, 0)
|
Self::version_at_least(major, minor, 11, 0)
|
||||||
},
|
},
|
||||||
|
supports_arrays_of_textures: Self::supports_any(
|
||||||
|
&device,
|
||||||
|
&[
|
||||||
|
MTLFeatureSet::iOS_GPUFamily3_v2,
|
||||||
|
MTLFeatureSet::iOS_GPUFamily4_v1,
|
||||||
|
MTLFeatureSet::iOS_GPUFamily5_v1,
|
||||||
|
MTLFeatureSet::tvOS_GPUFamily2_v1,
|
||||||
|
MTLFeatureSet::macOS_GPUFamily1_v3,
|
||||||
|
MTLFeatureSet::macOS_GPUFamily2_v1,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
supports_arrays_of_textures_write: device.supports_family(MTLGPUFamily::Apple6)
|
||||||
|
|| device.supports_family(MTLGPUFamily::Mac1)
|
||||||
|
|| device.supports_family(MTLGPUFamily::Mac2)
|
||||||
|
|| device.supports_family(MTLGPUFamily::MacCatalyst1)
|
||||||
|
|| device.supports_family(MTLGPUFamily::MacCatalyst2),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -830,8 +846,21 @@ impl super::PrivateCapabilities {
|
|||||||
| F::VERTEX_WRITABLE_STORAGE;
|
| F::VERTEX_WRITABLE_STORAGE;
|
||||||
|
|
||||||
features.set(
|
features.set(
|
||||||
F::SAMPLED_TEXTURE_BINDING_ARRAY | F::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING,
|
F::SAMPLED_TEXTURE_BINDING_ARRAY
|
||||||
self.msl_version >= MTLLanguageVersion::V2_0,
|
| F::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING
|
||||||
|
| F::SAMPLED_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
|
||||||
|
//// 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,
|
||||||
);
|
);
|
||||||
features.set(
|
features.set(
|
||||||
F::ADDRESS_MODE_CLAMP_TO_BORDER,
|
F::ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||||
|
@ -192,6 +192,8 @@ struct PrivateCapabilities {
|
|||||||
can_set_maximum_drawables_count: bool,
|
can_set_maximum_drawables_count: bool,
|
||||||
can_set_display_sync: bool,
|
can_set_display_sync: bool,
|
||||||
can_set_next_drawable_timeout: bool,
|
can_set_next_drawable_timeout: bool,
|
||||||
|
supports_arrays_of_textures: bool,
|
||||||
|
supports_arrays_of_textures_write: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -138,7 +138,11 @@ impl PhysicalDeviceFeatures {
|
|||||||
wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
//.shader_storage_image_array_non_uniform_indexing(
|
.shader_storage_image_array_non_uniform_indexing(
|
||||||
|
requested_features.contains(
|
||||||
|
wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||||
|
),
|
||||||
|
)
|
||||||
//.shader_storage_buffer_array_non_uniform_indexing(
|
//.shader_storage_buffer_array_non_uniform_indexing(
|
||||||
.shader_uniform_buffer_array_non_uniform_indexing(
|
.shader_uniform_buffer_array_non_uniform_indexing(
|
||||||
requested_features
|
requested_features
|
||||||
@ -164,7 +168,11 @@ impl PhysicalDeviceFeatures {
|
|||||||
wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
//.shader_storage_image_array_non_uniform_indexing(
|
.shader_storage_image_array_non_uniform_indexing(
|
||||||
|
requested_features.contains(
|
||||||
|
wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||||
|
),
|
||||||
|
)
|
||||||
//.shader_storage_buffer_array_non_uniform_indexing(
|
//.shader_storage_buffer_array_non_uniform_indexing(
|
||||||
.shader_uniform_buffer_array_non_uniform_indexing(
|
.shader_uniform_buffer_array_non_uniform_indexing(
|
||||||
requested_features
|
requested_features
|
||||||
@ -199,6 +207,7 @@ impl PhysicalDeviceFeatures {
|
|||||||
| F::PUSH_CONSTANTS
|
| F::PUSH_CONSTANTS
|
||||||
| F::ADDRESS_MODE_CLAMP_TO_BORDER
|
| F::ADDRESS_MODE_CLAMP_TO_BORDER
|
||||||
| F::SAMPLED_TEXTURE_BINDING_ARRAY
|
| F::SAMPLED_TEXTURE_BINDING_ARRAY
|
||||||
|
| F::STORAGE_TEXTURE_BINDING_ARRAY
|
||||||
| F::BUFFER_BINDING_ARRAY;
|
| F::BUFFER_BINDING_ARRAY;
|
||||||
let mut dl_flags = Df::all();
|
let mut dl_flags = Df::all();
|
||||||
|
|
||||||
@ -244,6 +253,10 @@ impl PhysicalDeviceFeatures {
|
|||||||
F::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING,
|
F::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING,
|
||||||
self.core.shader_sampled_image_array_dynamic_indexing != 0,
|
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(
|
features.set(
|
||||||
F::STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
F::STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
||||||
self.core.shader_storage_buffer_array_dynamic_indexing != 0,
|
self.core.shader_storage_buffer_array_dynamic_indexing != 0,
|
||||||
@ -270,7 +283,9 @@ impl PhysicalDeviceFeatures {
|
|||||||
if vulkan_1_2.shader_sampled_image_array_non_uniform_indexing != 0 {
|
if vulkan_1_2.shader_sampled_image_array_non_uniform_indexing != 0 {
|
||||||
features |= F::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
|
features |= F::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
|
||||||
}
|
}
|
||||||
//if vulkan_1_2.shader_storage_image_array_non_uniform_indexing != 0 {
|
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_storage_buffer_array_non_uniform_indexing != 0 {
|
||||||
if vulkan_1_2.shader_uniform_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;
|
features |= F::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING;
|
||||||
@ -289,7 +304,9 @@ impl PhysicalDeviceFeatures {
|
|||||||
if descriptor_indexing.shader_sampled_image_array_non_uniform_indexing != 0 {
|
if descriptor_indexing.shader_sampled_image_array_non_uniform_indexing != 0 {
|
||||||
features |= F::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
|
features |= F::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING;
|
||||||
}
|
}
|
||||||
//if descriptor_indexing.shader_storage_image_array_non_uniform_indexing != 0 {
|
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_storage_buffer_array_non_uniform_indexing != 0 {
|
||||||
if descriptor_indexing.shader_uniform_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;
|
features |= F::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING;
|
||||||
|
@ -537,6 +537,56 @@ bitflags::bitflags! {
|
|||||||
///
|
///
|
||||||
/// This is a native-only feature.
|
/// This is a native-only feature.
|
||||||
const VERTEX_WRITABLE_STORAGE = 0x0000_0020_0000_0000;
|
const VERTEX_WRITABLE_STORAGE = 0x0000_0020_0000_0000;
|
||||||
|
/// Allows the user to create uniform arrays of storage textures in shaders:
|
||||||
|
///
|
||||||
|
/// eg. `uniform image2D textures[10]`.
|
||||||
|
///
|
||||||
|
/// This capability allows them to exist and to be indexed by compile time constant
|
||||||
|
/// values.
|
||||||
|
///
|
||||||
|
/// Supported platforms:
|
||||||
|
/// - Metal (with MSL 2.2+ on macOS 10.13+)
|
||||||
|
/// - 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;
|
||||||
/// Enables clear to zero for buffers & images.
|
/// Enables clear to zero for buffers & images.
|
||||||
///
|
///
|
||||||
/// Supported platforms:
|
/// Supported platforms:
|
||||||
|
Loading…
Reference in New Issue
Block a user