mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-29 18:23:36 +00:00
Merge #1391
1391: Simplify features r=cwfitzgerald a=kvark **Connections** Fixes #1390 Makes vertex writable storage optional (native-only for now) Fixes the follow-up to #891 **Description** Refactors the code so that adding new features and maintaining current ones is much easier. Refactors the way missing features are checked and reported, DRY way. **Testing** Not really tested Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
commit
13f2ca571c
@ -5,7 +5,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
device::{
|
device::{
|
||||||
descriptor::{DescriptorSet, DescriptorTotalCount},
|
descriptor::{DescriptorSet, DescriptorTotalCount},
|
||||||
DeviceError, SHADER_STAGE_COUNT,
|
DeviceError, MissingFeatures, SHADER_STAGE_COUNT,
|
||||||
},
|
},
|
||||||
hub::Resource,
|
hub::Resource,
|
||||||
id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureViewId, Valid},
|
id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureViewId, Valid},
|
||||||
@ -29,16 +29,26 @@ use std::{
|
|||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Error)]
|
||||||
|
pub enum BindGroupLayoutEntryError {
|
||||||
|
#[error("arrays of bindings unsupported for this type of binding")]
|
||||||
|
ArrayUnsupported,
|
||||||
|
#[error(transparent)]
|
||||||
|
MissingFeatures(#[from] MissingFeatures),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Error)]
|
#[derive(Clone, Debug, Error)]
|
||||||
pub enum CreateBindGroupLayoutError {
|
pub enum CreateBindGroupLayoutError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Device(#[from] DeviceError),
|
Device(#[from] DeviceError),
|
||||||
#[error("arrays of bindings unsupported for this type of binding")]
|
|
||||||
ArrayUnsupported,
|
|
||||||
#[error("conflicting binding at index {0}")]
|
#[error("conflicting binding at index {0}")]
|
||||||
ConflictBinding(u32),
|
ConflictBinding(u32),
|
||||||
#[error("required device feature is missing: {0:?}")]
|
#[error("binding {binding} entry is invalid")]
|
||||||
MissingFeature(wgt::Features),
|
Entry {
|
||||||
|
binding: u32,
|
||||||
|
#[source]
|
||||||
|
error: BindGroupLayoutEntryError,
|
||||||
|
},
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
TooManyBindings(BindingTypeMaxCountError),
|
TooManyBindings(BindingTypeMaxCountError),
|
||||||
}
|
}
|
||||||
@ -83,8 +93,6 @@ pub enum CreateBindGroupError {
|
|||||||
MissingBufferUsage(#[from] MissingBufferUsageError),
|
MissingBufferUsage(#[from] MissingBufferUsageError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
MissingTextureUsage(#[from] MissingTextureUsageError),
|
MissingTextureUsage(#[from] MissingTextureUsageError),
|
||||||
#[error("required device features not enabled: {0:?}")]
|
|
||||||
MissingFeatures(wgt::Features),
|
|
||||||
#[error("binding declared as a single item, but bind group is using it as an array")]
|
#[error("binding declared as a single item, but bind group is using it as an array")]
|
||||||
SingleBindingExpected,
|
SingleBindingExpected,
|
||||||
#[error("unable to create a bind group with a swap chain image")]
|
#[error("unable to create a bind group with a swap chain image")]
|
||||||
@ -419,8 +427,8 @@ pub enum CreatePipelineLayoutError {
|
|||||||
wgt::PUSH_CONSTANT_ALIGNMENT
|
wgt::PUSH_CONSTANT_ALIGNMENT
|
||||||
)]
|
)]
|
||||||
MisalignedPushConstantRange { index: usize, bound: u32 },
|
MisalignedPushConstantRange { index: usize, bound: u32 },
|
||||||
#[error("device does not have required feature: {0:?}")]
|
#[error(transparent)]
|
||||||
MissingFeature(wgt::Features),
|
MissingFeatures(#[from] MissingFeatures),
|
||||||
#[error("push constant range (index {index}) provides for stage(s) {provided:?} but there exists another range that provides stage(s) {intersected:?}. Each stage may only be provided by one range")]
|
#[error("push constant range (index {index}) provides for stage(s) {provided:?} but there exists another range that provides stage(s) {intersected:?}. Each stage may only be provided by one range")]
|
||||||
MoreThanOnePushConstantRangePerStage {
|
MoreThanOnePushConstantRangePerStage {
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -342,7 +342,6 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
spv::Capability::Image1D,
|
spv::Capability::Image1D,
|
||||||
spv::Capability::SampledCubeArray,
|
spv::Capability::SampledCubeArray,
|
||||||
spv::Capability::ImageCubeArray,
|
spv::Capability::ImageCubeArray,
|
||||||
spv::Capability::ImageMSArray,
|
|
||||||
spv::Capability::StorageImageExtendedFormats,
|
spv::Capability::StorageImageExtendedFormats,
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
@ -393,6 +392,14 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn require_features(&self, feature: wgt::Features) -> Result<(), MissingFeatures> {
|
||||||
|
if self.features.contains(feature) {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(MissingFeatures(feature))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn last_completed_submission_index(&self) -> SubmissionIndex {
|
pub(crate) fn last_completed_submission_index(&self) -> SubmissionIndex {
|
||||||
self.life_guard.submission_index.load(Ordering::Acquire)
|
self.life_guard.submission_index.load(Ordering::Acquire)
|
||||||
}
|
}
|
||||||
@ -616,13 +623,8 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
debug_assert_eq!(self_id.backend(), B::VARIANT);
|
debug_assert_eq!(self_id.backend(), B::VARIANT);
|
||||||
|
|
||||||
let format_desc = desc.format.describe();
|
let format_desc = desc.format.describe();
|
||||||
let required_features = format_desc.required_features;
|
self.require_features(format_desc.required_features)
|
||||||
if !self.features.contains(required_features) {
|
.map_err(|error| resource::CreateTextureError::MissingFeatures(desc.format, error))?;
|
||||||
return Err(resource::CreateTextureError::MissingFeature(
|
|
||||||
required_features,
|
|
||||||
desc.format,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure `D24Plus` textures cannot be copied
|
// Ensure `D24Plus` textures cannot be copied
|
||||||
match desc.format {
|
match desc.format {
|
||||||
@ -917,17 +919,12 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
self_id: id::DeviceId,
|
self_id: id::DeviceId,
|
||||||
desc: &resource::SamplerDescriptor,
|
desc: &resource::SamplerDescriptor,
|
||||||
) -> Result<resource::Sampler<B>, resource::CreateSamplerError> {
|
) -> Result<resource::Sampler<B>, resource::CreateSamplerError> {
|
||||||
let clamp_to_border_enabled = self
|
if desc
|
||||||
.features
|
|
||||||
.contains(wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER);
|
|
||||||
let clamp_to_border_found = desc
|
|
||||||
.address_modes
|
.address_modes
|
||||||
.iter()
|
.iter()
|
||||||
.any(|am| am == &wgt::AddressMode::ClampToBorder);
|
.any(|am| am == &wgt::AddressMode::ClampToBorder)
|
||||||
if clamp_to_border_found && !clamp_to_border_enabled {
|
{
|
||||||
return Err(resource::CreateSamplerError::MissingFeature(
|
self.require_features(wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER)?;
|
||||||
wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let actual_clamp = if let Some(clamp) = desc.anisotropy_clamp {
|
let actual_clamp = if let Some(clamp) = desc.anisotropy_clamp {
|
||||||
@ -1198,9 +1195,11 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
entry_map: binding_model::BindEntryMap,
|
entry_map: binding_model::BindEntryMap,
|
||||||
) -> Result<binding_model::BindGroupLayout<B>, binding_model::CreateBindGroupLayoutError> {
|
) -> Result<binding_model::BindGroupLayout<B>, binding_model::CreateBindGroupLayoutError> {
|
||||||
let mut desc_count = descriptor::DescriptorTotalCount::default();
|
let mut desc_count = descriptor::DescriptorTotalCount::default();
|
||||||
for binding in entry_map.values() {
|
for entry in entry_map.values() {
|
||||||
use wgt::BindingType as Bt;
|
use wgt::BindingType as Bt;
|
||||||
let (counter, array_feature) = match binding.ty {
|
|
||||||
|
let mut required_features = wgt::Features::empty();
|
||||||
|
let (counter, array_feature, is_writable_storage) = match entry.ty {
|
||||||
Bt::Buffer {
|
Bt::Buffer {
|
||||||
ty: wgt::BufferBindingType::Uniform,
|
ty: wgt::BufferBindingType::Uniform,
|
||||||
has_dynamic_offset: false,
|
has_dynamic_offset: false,
|
||||||
@ -1208,6 +1207,7 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
} => (
|
} => (
|
||||||
&mut desc_count.uniform_buffer,
|
&mut desc_count.uniform_buffer,
|
||||||
Some(wgt::Features::BUFFER_BINDING_ARRAY),
|
Some(wgt::Features::BUFFER_BINDING_ARRAY),
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
Bt::Buffer {
|
Bt::Buffer {
|
||||||
ty: wgt::BufferBindingType::Uniform,
|
ty: wgt::BufferBindingType::Uniform,
|
||||||
@ -1216,44 +1216,65 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
} => (
|
} => (
|
||||||
&mut desc_count.uniform_buffer_dynamic,
|
&mut desc_count.uniform_buffer_dynamic,
|
||||||
Some(wgt::Features::BUFFER_BINDING_ARRAY),
|
Some(wgt::Features::BUFFER_BINDING_ARRAY),
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
Bt::Buffer {
|
Bt::Buffer {
|
||||||
ty: wgt::BufferBindingType::Storage { .. },
|
ty: wgt::BufferBindingType::Storage { read_only },
|
||||||
has_dynamic_offset: false,
|
has_dynamic_offset,
|
||||||
min_binding_size: _,
|
min_binding_size: _,
|
||||||
} => (
|
} => (
|
||||||
&mut desc_count.storage_buffer,
|
if has_dynamic_offset {
|
||||||
|
&mut desc_count.storage_buffer_dynamic
|
||||||
|
} else {
|
||||||
|
&mut desc_count.storage_buffer
|
||||||
|
},
|
||||||
Some(wgt::Features::BUFFER_BINDING_ARRAY),
|
Some(wgt::Features::BUFFER_BINDING_ARRAY),
|
||||||
|
!read_only,
|
||||||
),
|
),
|
||||||
Bt::Buffer {
|
Bt::Sampler { .. } => (&mut desc_count.sampler, None, false),
|
||||||
ty: wgt::BufferBindingType::Storage { .. },
|
|
||||||
has_dynamic_offset: true,
|
|
||||||
min_binding_size: _,
|
|
||||||
} => (
|
|
||||||
&mut desc_count.storage_buffer_dynamic,
|
|
||||||
Some(wgt::Features::BUFFER_BINDING_ARRAY),
|
|
||||||
),
|
|
||||||
Bt::Sampler { .. } => (&mut desc_count.sampler, None),
|
|
||||||
Bt::Texture { .. } => (
|
Bt::Texture { .. } => (
|
||||||
&mut desc_count.sampled_image,
|
&mut desc_count.sampled_image,
|
||||||
Some(wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY),
|
Some(wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY),
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
Bt::StorageTexture { access, .. } => (
|
||||||
|
&mut desc_count.storage_image,
|
||||||
|
None,
|
||||||
|
match access {
|
||||||
|
wgt::StorageTextureAccess::ReadOnly => false,
|
||||||
|
wgt::StorageTextureAccess::WriteOnly => true,
|
||||||
|
wgt::StorageTextureAccess::ReadWrite => {
|
||||||
|
required_features |=
|
||||||
|
wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
Bt::StorageTexture { .. } => (&mut desc_count.storage_image, None),
|
|
||||||
};
|
};
|
||||||
*counter += match binding.count {
|
|
||||||
|
*counter += match entry.count {
|
||||||
// Validate the count parameter
|
// Validate the count parameter
|
||||||
Some(count) => {
|
Some(count) => {
|
||||||
let feature = array_feature
|
required_features |= array_feature
|
||||||
.ok_or(binding_model::CreateBindGroupLayoutError::ArrayUnsupported)?;
|
.ok_or(binding_model::BindGroupLayoutEntryError::ArrayUnsupported)
|
||||||
if !self.features.contains(feature) {
|
.map_err(|error| binding_model::CreateBindGroupLayoutError::Entry {
|
||||||
return Err(binding_model::CreateBindGroupLayoutError::MissingFeature(
|
binding: entry.binding,
|
||||||
feature,
|
error,
|
||||||
));
|
})?;
|
||||||
}
|
|
||||||
count.get()
|
count.get()
|
||||||
}
|
}
|
||||||
None => 1,
|
None => 1,
|
||||||
};
|
};
|
||||||
|
if is_writable_storage && entry.visibility.contains(wgt::ShaderStage::VERTEX) {
|
||||||
|
required_features |= wgt::Features::VERTEX_WRITABLE_STORAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.require_features(required_features)
|
||||||
|
.map_err(binding_model::BindGroupLayoutEntryError::MissingFeatures)
|
||||||
|
.map_err(|error| binding_model::CreateBindGroupLayoutError::Entry {
|
||||||
|
binding: entry.binding,
|
||||||
|
error,
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let raw_bindings = entry_map
|
let raw_bindings = entry_map
|
||||||
@ -1478,11 +1499,6 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
SmallVec::from([buffer_desc])
|
SmallVec::from([buffer_desc])
|
||||||
}
|
}
|
||||||
Br::BufferArray(ref bindings_array) => {
|
Br::BufferArray(ref bindings_array) => {
|
||||||
let required_feats = wgt::Features::BUFFER_BINDING_ARRAY;
|
|
||||||
if !self.features.contains(required_feats) {
|
|
||||||
return Err(Error::MissingFeatures(required_feats));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(count) = decl.count {
|
if let Some(count) = decl.count {
|
||||||
let count = count.get() as usize;
|
let count = count.get() as usize;
|
||||||
let num_bindings = bindings_array.len();
|
let num_bindings = bindings_array.len();
|
||||||
@ -1631,13 +1647,9 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
if !view.format_features.flags.contains(
|
if !view.format_features.flags.contains(
|
||||||
wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE,
|
wgt::TextureFormatFeatureFlags::STORAGE_READ_WRITE,
|
||||||
) {
|
) {
|
||||||
return Err(if self.features.contains(
|
return Err(Error::StorageReadWriteNotSupported(
|
||||||
wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
|
view.format,
|
||||||
) {
|
));
|
||||||
Error::StorageReadWriteNotSupported(view.format)
|
|
||||||
} else {
|
|
||||||
Error::MissingFeatures(wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resource::TextureUse::STORAGE_STORE
|
resource::TextureUse::STORAGE_STORE
|
||||||
@ -1686,11 +1698,6 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Br::TextureViewArray(ref bindings_array) => {
|
Br::TextureViewArray(ref bindings_array) => {
|
||||||
let required_feats = wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY;
|
|
||||||
if !self.features.contains(required_feats) {
|
|
||||||
return Err(Error::MissingFeatures(required_feats));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(count) = decl.count {
|
if let Some(count) = decl.count {
|
||||||
let count = count.get() as usize;
|
let count = count.get() as usize;
|
||||||
let num_bindings = bindings_array.len();
|
let num_bindings = bindings_array.len();
|
||||||
@ -1814,11 +1821,10 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if !desc.push_constant_ranges.is_empty()
|
if !desc.push_constant_ranges.is_empty() {
|
||||||
&& !self.features.contains(wgt::Features::PUSH_CONSTANTS)
|
self.require_features(wgt::Features::PUSH_CONSTANTS)?;
|
||||||
{
|
|
||||||
return Err(Error::MissingFeature(wgt::Features::PUSH_CONSTANTS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut used_stages = wgt::ShaderStage::empty();
|
let mut used_stages = wgt::ShaderStage::empty();
|
||||||
for (index, pc) in desc.push_constant_ranges.iter().enumerate() {
|
for (index, pc) in desc.push_constant_ranges.iter().enumerate() {
|
||||||
if pc.stages.intersects(used_stages) {
|
if pc.stages.intersects(used_stages) {
|
||||||
@ -2169,14 +2175,7 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
| wgt::VertexFormat::Float64x3
|
| wgt::VertexFormat::Float64x3
|
||||||
| wgt::VertexFormat::Float64x4 = attribute.format
|
| wgt::VertexFormat::Float64x4 = attribute.format
|
||||||
{
|
{
|
||||||
if !self
|
self.require_features(wgt::Features::VERTEX_ATTRIBUTE_64BIT)?;
|
||||||
.features
|
|
||||||
.contains(wgt::Features::VERTEX_ATTRIBUTE_64BIT)
|
|
||||||
{
|
|
||||||
return Err(pipeline::CreateRenderPipelineError::MissingFeature(
|
|
||||||
wgt::Features::VERTEX_ATTRIBUTE_64BIT,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes.alloc().init(hal::pso::AttributeDesc {
|
attributes.alloc().init(hal::pso::AttributeDesc {
|
||||||
@ -2221,27 +2220,15 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc.primitive.clamp_depth && !self.features.contains(wgt::Features::DEPTH_CLAMPING) {
|
if desc.primitive.clamp_depth {
|
||||||
return Err(pipeline::CreateRenderPipelineError::MissingFeature(
|
self.require_features(wgt::Features::DEPTH_CLAMPING)?;
|
||||||
wgt::Features::DEPTH_CLAMPING,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
if desc.primitive.polygon_mode != wgt::PolygonMode::Fill
|
if desc.primitive.polygon_mode != wgt::PolygonMode::Fill {
|
||||||
&& !self.features.contains(wgt::Features::NON_FILL_POLYGON_MODE)
|
self.require_features(wgt::Features::NON_FILL_POLYGON_MODE)?;
|
||||||
{
|
|
||||||
return Err(pipeline::CreateRenderPipelineError::MissingFeature(
|
|
||||||
wgt::Features::NON_FILL_POLYGON_MODE,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc.primitive.conservative
|
if desc.primitive.conservative {
|
||||||
&& !self
|
self.require_features(wgt::Features::CONSERVATIVE_RASTERIZATION)?;
|
||||||
.features
|
|
||||||
.contains(wgt::Features::CONSERVATIVE_RASTERIZATION)
|
|
||||||
{
|
|
||||||
return Err(pipeline::CreateRenderPipelineError::MissingFeature(
|
|
||||||
wgt::Features::CONSERVATIVE_RASTERIZATION,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc.primitive.conservative && desc.primitive.polygon_mode != wgt::PolygonMode::Fill {
|
if desc.primitive.conservative && desc.primitive.polygon_mode != wgt::PolygonMode::Fill {
|
||||||
@ -2596,6 +2583,47 @@ impl<B: GfxBackend> Device<B> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create_query_set(
|
||||||
|
&self,
|
||||||
|
self_id: id::DeviceId,
|
||||||
|
desc: &wgt::QuerySetDescriptor,
|
||||||
|
) -> Result<resource::QuerySet<B>, resource::CreateQuerySetError> {
|
||||||
|
use resource::CreateQuerySetError as Error;
|
||||||
|
|
||||||
|
match desc.ty {
|
||||||
|
wgt::QueryType::Timestamp => {
|
||||||
|
self.require_features(wgt::Features::TIMESTAMP_QUERY)?;
|
||||||
|
}
|
||||||
|
wgt::QueryType::PipelineStatistics(..) => {
|
||||||
|
self.require_features(wgt::Features::PIPELINE_STATISTICS_QUERY)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if desc.count == 0 {
|
||||||
|
return Err(Error::ZeroCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if desc.count >= wgt::QUERY_SET_MAX_QUERIES {
|
||||||
|
return Err(Error::TooManyQueries {
|
||||||
|
count: desc.count,
|
||||||
|
maximum: wgt::QUERY_SET_MAX_QUERIES,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let (hal_type, elements) = conv::map_query_type(&desc.ty);
|
||||||
|
|
||||||
|
Ok(resource::QuerySet {
|
||||||
|
raw: unsafe { self.raw.create_query_pool(hal_type, desc.count).unwrap() },
|
||||||
|
device_id: Stored {
|
||||||
|
value: id::Valid(self_id),
|
||||||
|
ref_count: self.life_guard.add_ref(),
|
||||||
|
},
|
||||||
|
life_guard: LifeGuard::new(""),
|
||||||
|
desc: desc.clone(),
|
||||||
|
elements,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: hal::Backend> Device<B> {
|
impl<B: hal::Backend> Device<B> {
|
||||||
@ -2703,6 +2731,10 @@ impl DeviceError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Error)]
|
||||||
|
#[error("Features {0:?} are required but not enabled on the device")]
|
||||||
|
pub struct MissingFeatures(pub wgt::Features);
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
#[cfg_attr(feature = "trace", derive(serde::Serialize))]
|
||||||
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
#[cfg_attr(feature = "replay", derive(serde::Deserialize))]
|
||||||
@ -4017,50 +4049,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
match desc.ty {
|
let query_set = match device.create_query_set(device_id, desc) {
|
||||||
wgt::QueryType::Timestamp => {
|
Ok(query_set) => query_set,
|
||||||
if !device.features.contains(wgt::Features::TIMESTAMP_QUERY) {
|
Err(err) => break err,
|
||||||
break resource::CreateQuerySetError::MissingFeature(
|
|
||||||
wgt::Features::TIMESTAMP_QUERY,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wgt::QueryType::PipelineStatistics(..) => {
|
|
||||||
if !device
|
|
||||||
.features
|
|
||||||
.contains(wgt::Features::PIPELINE_STATISTICS_QUERY)
|
|
||||||
{
|
|
||||||
break resource::CreateQuerySetError::MissingFeature(
|
|
||||||
wgt::Features::PIPELINE_STATISTICS_QUERY,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if desc.count == 0 {
|
|
||||||
break resource::CreateQuerySetError::ZeroCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if desc.count >= wgt::QUERY_SET_MAX_QUERIES {
|
|
||||||
break resource::CreateQuerySetError::TooManyQueries {
|
|
||||||
count: desc.count,
|
|
||||||
maximum: wgt::QUERY_SET_MAX_QUERIES,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let query_set = {
|
|
||||||
let (hal_type, elements) = conv::map_query_type(&desc.ty);
|
|
||||||
|
|
||||||
resource::QuerySet {
|
|
||||||
raw: unsafe { device.raw.create_query_pool(hal_type, desc.count).unwrap() },
|
|
||||||
device_id: Stored {
|
|
||||||
value: id::Valid(device_id),
|
|
||||||
ref_count: device.life_guard.add_ref(),
|
|
||||||
},
|
|
||||||
life_guard: LifeGuard::new(""),
|
|
||||||
desc: desc.clone(),
|
|
||||||
elements,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let ref_count = query_set.life_guard.add_ref();
|
let ref_count = query_set.life_guard.add_ref();
|
||||||
|
@ -116,6 +116,87 @@ impl crate::hub::Resource for Surface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FEATURE_MAP: &[(wgt::Features, hal::Features)] = &[
|
||||||
|
(wgt::Features::DEPTH_CLAMPING, hal::Features::DEPTH_CLAMP),
|
||||||
|
(
|
||||||
|
wgt::Features::TEXTURE_COMPRESSION_BC,
|
||||||
|
hal::Features::FORMAT_BC,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::TEXTURE_COMPRESSION_ETC2,
|
||||||
|
hal::Features::FORMAT_ETC2,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::TEXTURE_COMPRESSION_ASTC_LDR,
|
||||||
|
hal::Features::FORMAT_ASTC_LDR,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY,
|
||||||
|
hal::Features::TEXTURE_DESCRIPTOR_ARRAY,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING,
|
||||||
|
hal::Features::SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
||||||
|
hal::Features::SAMPLED_TEXTURE_DESCRIPTOR_INDEXING,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::UNSIZED_BINDING_ARRAY,
|
||||||
|
hal::Features::UNSIZED_DESCRIPTOR_ARRAY,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::MULTI_DRAW_INDIRECT,
|
||||||
|
hal::Features::MULTI_DRAW_INDIRECT,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::MULTI_DRAW_INDIRECT_COUNT,
|
||||||
|
hal::Features::DRAW_INDIRECT_COUNT,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::NON_FILL_POLYGON_MODE,
|
||||||
|
hal::Features::NON_FILL_POLYGON_MODE,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::PIPELINE_STATISTICS_QUERY,
|
||||||
|
hal::Features::PIPELINE_STATISTICS_QUERY,
|
||||||
|
),
|
||||||
|
(wgt::Features::SHADER_FLOAT64, hal::Features::SHADER_FLOAT64),
|
||||||
|
(
|
||||||
|
wgt::Features::CONSERVATIVE_RASTERIZATION,
|
||||||
|
hal::Features::CONSERVATIVE_RASTERIZATION,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::BUFFER_BINDING_ARRAY,
|
||||||
|
hal::Features::BUFFER_DESCRIPTOR_ARRAY,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
||||||
|
hal::Features::SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
||||||
|
hal::Features::UNIFORM_BUFFER_DESCRIPTOR_INDEXING,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
||||||
|
hal::Features::SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
||||||
|
hal::Features::STORAGE_BUFFER_DESCRIPTOR_INDEXING,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::VERTEX_WRITABLE_STORAGE,
|
||||||
|
hal::Features::VERTEX_STORES_AND_ATOMICS,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER,
|
||||||
|
hal::Features::SAMPLER_BORDER_COLOR,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Adapter<B: hal::Backend> {
|
pub struct Adapter<B: hal::Backend> {
|
||||||
pub(crate) raw: hal::adapter::Adapter<B>,
|
pub(crate) raw: hal::adapter::Adapter<B>,
|
||||||
@ -137,89 +218,13 @@ impl<B: GfxBackend> Adapter<B> {
|
|||||||
| wgt::Features::MAPPABLE_PRIMARY_BUFFERS
|
| wgt::Features::MAPPABLE_PRIMARY_BUFFERS
|
||||||
| wgt::Features::PUSH_CONSTANTS
|
| wgt::Features::PUSH_CONSTANTS
|
||||||
| wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES;
|
| wgt::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES;
|
||||||
features.set(
|
for &(hi, lo) in FEATURE_MAP.iter() {
|
||||||
wgt::Features::DEPTH_CLAMPING,
|
features.set(hi, adapter_features.contains(lo));
|
||||||
adapter_features.contains(hal::Features::DEPTH_CLAMP),
|
}
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::TEXTURE_COMPRESSION_BC,
|
|
||||||
adapter_features.contains(hal::Features::FORMAT_BC),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::TEXTURE_COMPRESSION_ETC2,
|
|
||||||
adapter_features.contains(hal::Features::FORMAT_ETC2),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::TEXTURE_COMPRESSION_ASTC_LDR,
|
|
||||||
adapter_features.contains(hal::Features::FORMAT_ASTC_LDR),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY,
|
|
||||||
adapter_features.contains(hal::Features::TEXTURE_DESCRIPTOR_ARRAY),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING,
|
|
||||||
adapter_features.contains(hal::Features::SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING,
|
|
||||||
adapter_features.contains(hal::Features::SAMPLED_TEXTURE_DESCRIPTOR_INDEXING),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::UNSIZED_BINDING_ARRAY,
|
|
||||||
adapter_features.contains(hal::Features::UNSIZED_DESCRIPTOR_ARRAY),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::MULTI_DRAW_INDIRECT,
|
|
||||||
adapter_features.contains(hal::Features::MULTI_DRAW_INDIRECT),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::MULTI_DRAW_INDIRECT_COUNT,
|
|
||||||
adapter_features.contains(hal::Features::DRAW_INDIRECT_COUNT),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::NON_FILL_POLYGON_MODE,
|
|
||||||
adapter_features.contains(hal::Features::NON_FILL_POLYGON_MODE),
|
|
||||||
);
|
|
||||||
features.set(
|
features.set(
|
||||||
wgt::Features::TIMESTAMP_QUERY,
|
wgt::Features::TIMESTAMP_QUERY,
|
||||||
properties.limits.timestamp_compute_and_graphics,
|
properties.limits.timestamp_compute_and_graphics,
|
||||||
);
|
);
|
||||||
features.set(
|
|
||||||
wgt::Features::PIPELINE_STATISTICS_QUERY,
|
|
||||||
adapter_features.contains(hal::Features::PIPELINE_STATISTICS_QUERY),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::SHADER_FLOAT64,
|
|
||||||
adapter_features.contains(hal::Features::SHADER_FLOAT64),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::CONSERVATIVE_RASTERIZATION,
|
|
||||||
adapter_features.contains(hal::Features::CONSERVATIVE_RASTERIZATION),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::BUFFER_BINDING_ARRAY,
|
|
||||||
adapter_features.contains(hal::Features::BUFFER_DESCRIPTOR_ARRAY),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
|
||||||
adapter_features.contains(hal::Features::SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
|
||||||
adapter_features.contains(hal::Features::UNIFORM_BUFFER_DESCRIPTOR_INDEXING),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
|
||||||
adapter_features.contains(hal::Features::SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING),
|
|
||||||
);
|
|
||||||
features.set(
|
|
||||||
wgt::Features::STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING,
|
|
||||||
adapter_features.contains(hal::Features::STORAGE_BUFFER_DESCRIPTOR_INDEXING),
|
|
||||||
);
|
|
||||||
#[cfg(not(target_os = "ios"))]
|
|
||||||
//TODO: https://github.com/gfx-rs/gfx/issues/3346
|
|
||||||
features.set(wgt::Features::ADDRESS_MODE_CLAMP_TO_BORDER, true);
|
|
||||||
|
|
||||||
let private_features = PrivateFeatures {
|
let private_features = PrivateFeatures {
|
||||||
anisotropic_filtering: adapter_features.contains(hal::Features::SAMPLER_ANISOTROPY),
|
anisotropic_filtering: adapter_features.contains(hal::Features::SAMPLER_ANISOTROPY),
|
||||||
@ -452,12 +457,12 @@ impl<B: GfxBackend> Adapter<B> {
|
|||||||
|
|
||||||
// Check features that are always needed
|
// Check features that are always needed
|
||||||
let wishful_features = hal::Features::ROBUST_BUFFER_ACCESS
|
let wishful_features = hal::Features::ROBUST_BUFFER_ACCESS
|
||||||
| hal::Features::VERTEX_STORES_AND_ATOMICS
|
|
||||||
| hal::Features::FRAGMENT_STORES_AND_ATOMICS
|
| hal::Features::FRAGMENT_STORES_AND_ATOMICS
|
||||||
| hal::Features::NDC_Y_UP
|
| hal::Features::NDC_Y_UP
|
||||||
| hal::Features::INDEPENDENT_BLENDING
|
| hal::Features::INDEPENDENT_BLENDING
|
||||||
| hal::Features::SAMPLER_ANISOTROPY
|
| hal::Features::SAMPLER_ANISOTROPY
|
||||||
| hal::Features::IMAGE_CUBE_ARRAY;
|
| hal::Features::IMAGE_CUBE_ARRAY
|
||||||
|
| hal::Features::SAMPLE_RATE_SHADING;
|
||||||
let mut enabled_features = available_features & wishful_features;
|
let mut enabled_features = available_features & wishful_features;
|
||||||
if enabled_features != wishful_features {
|
if enabled_features != wishful_features {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
@ -466,96 +471,10 @@ impl<B: GfxBackend> Adapter<B> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Features
|
// Enable low-level features
|
||||||
enabled_features.set(
|
for &(hi, lo) in FEATURE_MAP.iter() {
|
||||||
hal::Features::DEPTH_CLAMP,
|
enabled_features.set(lo, desc.features.contains(hi));
|
||||||
desc.features.contains(wgt::Features::DEPTH_CLAMPING),
|
}
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::FORMAT_BC,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::TEXTURE_COMPRESSION_BC),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::FORMAT_ETC2,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::TEXTURE_COMPRESSION_ETC2),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::FORMAT_ASTC_LDR,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::TEXTURE_COMPRESSION_ASTC_LDR),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::TEXTURE_DESCRIPTOR_ARRAY,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::SAMPLED_TEXTURE_BINDING_ARRAY),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::SAMPLED_TEXTURE_ARRAY_DYNAMIC_INDEXING),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::SAMPLED_TEXTURE_DESCRIPTOR_INDEXING,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::SAMPLED_TEXTURE_ARRAY_NON_UNIFORM_INDEXING),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::UNSIZED_DESCRIPTOR_ARRAY,
|
|
||||||
desc.features.contains(wgt::Features::UNSIZED_BINDING_ARRAY),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::MULTI_DRAW_INDIRECT,
|
|
||||||
desc.features.contains(wgt::Features::MULTI_DRAW_INDIRECT),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::DRAW_INDIRECT_COUNT,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::MULTI_DRAW_INDIRECT_COUNT),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::NON_FILL_POLYGON_MODE,
|
|
||||||
desc.features.contains(wgt::Features::NON_FILL_POLYGON_MODE),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::PIPELINE_STATISTICS_QUERY,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::PIPELINE_STATISTICS_QUERY),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::SHADER_FLOAT64,
|
|
||||||
desc.features.contains(wgt::Features::SHADER_FLOAT64),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::CONSERVATIVE_RASTERIZATION,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::CONSERVATIVE_RASTERIZATION),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::BUFFER_DESCRIPTOR_ARRAY,
|
|
||||||
desc.features.contains(wgt::Features::BUFFER_BINDING_ARRAY),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::UNIFORM_BUFFER_DESCRIPTOR_INDEXING,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::UNIFORM_BUFFER_ARRAY_NON_UNIFORM_INDEXING),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING),
|
|
||||||
);
|
|
||||||
enabled_features.set(
|
|
||||||
hal::Features::STORAGE_BUFFER_DESCRIPTOR_INDEXING,
|
|
||||||
desc.features
|
|
||||||
.contains(wgt::Features::STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING),
|
|
||||||
);
|
|
||||||
|
|
||||||
let family = self
|
let family = self
|
||||||
.raw
|
.raw
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
binding_model::{CreateBindGroupLayoutError, CreatePipelineLayoutError},
|
binding_model::{CreateBindGroupLayoutError, CreatePipelineLayoutError},
|
||||||
device::{DeviceError, RenderPassContext},
|
device::{DeviceError, MissingFeatures, RenderPassContext},
|
||||||
hub::Resource,
|
hub::Resource,
|
||||||
id::{DeviceId, PipelineLayoutId, ShaderModuleId},
|
id::{DeviceId, PipelineLayoutId, ShaderModuleId},
|
||||||
validation, Label, LifeGuard, Stored, DOWNLEVEL_ERROR_WARNING_MESSAGE,
|
validation, Label, LifeGuard, Stored, DOWNLEVEL_ERROR_WARNING_MESSAGE,
|
||||||
@ -62,8 +62,8 @@ pub enum CreateShaderModuleError {
|
|||||||
Device(#[from] DeviceError),
|
Device(#[from] DeviceError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Validation(#[from] naga::valid::ValidationError),
|
Validation(#[from] naga::valid::ValidationError),
|
||||||
#[error("missing required device features {0:?}")]
|
#[error(transparent)]
|
||||||
MissingFeature(wgt::Features),
|
MissingFeatures(#[from] MissingFeatures),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes a programmable pipeline stage.
|
/// Describes a programmable pipeline stage.
|
||||||
@ -246,8 +246,8 @@ pub enum CreateRenderPipelineError {
|
|||||||
},
|
},
|
||||||
#[error("Conservative Rasterization is only supported for wgt::PolygonMode::Fill")]
|
#[error("Conservative Rasterization is only supported for wgt::PolygonMode::Fill")]
|
||||||
ConservativeRasterizationNonFillPolygonMode,
|
ConservativeRasterizationNonFillPolygonMode,
|
||||||
#[error("missing required device features {0:?}")]
|
#[error(transparent)]
|
||||||
MissingFeature(wgt::Features),
|
MissingFeatures(#[from] MissingFeatures),
|
||||||
#[error("error matching {stage:?} shader requirements against the pipeline")]
|
#[error("error matching {stage:?} shader requirements against the pipeline")]
|
||||||
Stage {
|
Stage {
|
||||||
stage: wgt::ShaderStage,
|
stage: wgt::ShaderStage,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{alloc::MemoryBlock, DeviceError, HostMap},
|
device::{alloc::MemoryBlock, DeviceError, HostMap, MissingFeatures},
|
||||||
hub::Resource,
|
hub::Resource,
|
||||||
id::{DeviceId, SwapChainId, TextureId},
|
id::{DeviceId, SwapChainId, TextureId},
|
||||||
memory_init_tracker::MemoryInitTracker,
|
memory_init_tracker::MemoryInitTracker,
|
||||||
@ -266,8 +266,8 @@ pub enum CreateTextureError {
|
|||||||
InvalidMipLevelCount(u32),
|
InvalidMipLevelCount(u32),
|
||||||
#[error("The texture usages {0:?} are not allowed on a texture of type {1:?}")]
|
#[error("The texture usages {0:?} are not allowed on a texture of type {1:?}")]
|
||||||
InvalidUsages(wgt::TextureUsage, wgt::TextureFormat),
|
InvalidUsages(wgt::TextureUsage, wgt::TextureFormat),
|
||||||
#[error("Feature {0:?} must be enabled to create a texture of type {1:?}")]
|
#[error("Texture format {0:?} can't be used")]
|
||||||
MissingFeature(wgt::Features, wgt::TextureFormat),
|
MissingFeatures(wgt::TextureFormat, #[source] MissingFeatures),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: hal::Backend> Resource for Texture<B> {
|
impl<B: hal::Backend> Resource for Texture<B> {
|
||||||
@ -458,9 +458,9 @@ pub enum CreateSamplerError {
|
|||||||
InvalidClamp(u8),
|
InvalidClamp(u8),
|
||||||
#[error("cannot create any more samplers")]
|
#[error("cannot create any more samplers")]
|
||||||
TooManyObjects,
|
TooManyObjects,
|
||||||
/// AddressMode::ClampToBorder requires feature ADDRESS_MODE_CLAMP_TO_BORDER
|
/// AddressMode::ClampToBorder requires feature ADDRESS_MODE_CLAMP_TO_BORDER.
|
||||||
#[error("Feature {0:?} must be enabled")]
|
#[error(transparent)]
|
||||||
MissingFeature(wgt::Features),
|
MissingFeatures(#[from] MissingFeatures),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B: hal::Backend> Resource for Sampler<B> {
|
impl<B: hal::Backend> Resource for Sampler<B> {
|
||||||
@ -484,8 +484,8 @@ pub enum CreateQuerySetError {
|
|||||||
ZeroCount,
|
ZeroCount,
|
||||||
#[error("{count} is too many queries for a single QuerySet. QuerySets cannot be made more than {maximum} queries.")]
|
#[error("{count} is too many queries for a single QuerySet. QuerySets cannot be made more than {maximum} queries.")]
|
||||||
TooManyQueries { count: u32, maximum: u32 },
|
TooManyQueries { count: u32, maximum: u32 },
|
||||||
#[error("Feature {0:?} must be enabled")]
|
#[error(transparent)]
|
||||||
MissingFeature(wgt::Features),
|
MissingFeatures(#[from] MissingFeatures),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -526,6 +526,15 @@ bitflags::bitflags! {
|
|||||||
///
|
///
|
||||||
/// This is a native only feature.
|
/// This is a native only feature.
|
||||||
const STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 0x0000_0010_0000_0000;
|
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.
|
||||||
|
///
|
||||||
|
/// Supported Platforms:
|
||||||
|
/// - All
|
||||||
|
///
|
||||||
|
/// This is a native-only feature.
|
||||||
|
const VERTEX_WRITABLE_STORAGE = 0x0000_0020_0000_0000;
|
||||||
/// Features which are part of the upstream WebGPU standard.
|
/// Features which are part of the upstream WebGPU standard.
|
||||||
const ALL_WEBGPU = 0x0000_0000_0000_FFFF;
|
const ALL_WEBGPU = 0x0000_0000_0000_FFFF;
|
||||||
/// Features that are only available when targeting native (not web).
|
/// Features that are only available when targeting native (not web).
|
||||||
|
Loading…
Reference in New Issue
Block a user