Validate texture bindings

This commit is contained in:
Dzmitry Malyshau 2021-02-15 19:59:15 -05:00
parent 6442b947cb
commit 9bf47dd772
4 changed files with 83 additions and 2 deletions

View File

@ -100,6 +100,30 @@ pub enum CreateBindGroupError {
// Human-readable description of expected types
expected: &'static str,
},
#[error("texture binding {binding} expects multisampled = {layout_multisampled}, but given a view with samples = {view_samples}")]
InvalidTextureMultisample {
binding: u32,
layout_multisampled: bool,
view_samples: u32,
},
#[error("texture binding {binding} expects sample type = {layout_sample_type:?}, but given a view with format = {view_format:?}")]
InvalidTextureSampleType {
binding: u32,
layout_sample_type: wgt::TextureSampleType,
view_format: wgt::TextureFormat,
},
#[error("texture binding {binding} expects dimension = {layout_dimension:?}, but given a view with dimension = {view_dimension:?}")]
InvalidTextureDimension {
binding: u32,
layout_dimension: wgt::TextureViewDimension,
view_dimension: wgt::TextureViewDimension,
},
#[error("storage texture binding {binding} expects format = {layout_format:?}, but given a view with format = {view_format:?}")]
InvalidStorageTextureFormat {
binding: u32,
layout_format: wgt::TextureFormat,
view_format: wgt::TextureFormat,
},
#[error("the given sampler is/is not a comparison sampler, while the layout type indicates otherwise")]
WrongSamplerComparison,
#[error("bound texture views can not have both depth and stencil aspects enabled")]

View File

@ -857,6 +857,7 @@ impl<B: GfxBackend> Device<B> {
aspects,
format: texture.format,
format_features: texture.format_features,
dimension: view_dim,
extent: wgt::Extent3d {
width: hal_extent.width,
height: hal_extent.height,
@ -1414,11 +1415,65 @@ impl<B: GfxBackend> Device<B> {
.views
.use_extend(&*texture_view_guard, id, (), ())
.map_err(|_| Error::InvalidTextureView(id))?;
let format_info = view.format.describe();
let (pub_usage, internal_use) = match decl.ty {
wgt::BindingType::Texture { .. } => {
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 as u32,
});
}
match (sample_type, format_info.sample_type) {
(Tst::Uint, Tst::Uint) |
(Tst::Sint, Tst::Sint) |
(Tst::Depth, Tst::Depth) |
// if we expect non-fiterable, accept anything float
(Tst::Float { filterable: false }, Tst::Float { .. }) |
// if we expect fiterable, require it
(Tst::Float { filterable: true }, Tst::Float { filterable: 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.format,
}),
}
if view_dimension != view.dimension {
return Err(Error::InvalidTextureDimension {
binding,
layout_dimension: view_dimension,
view_dimension: view.dimension,
});
}
(wgt::TextureUsage::SAMPLED, view.sampled_internal_use)
}
wgt::BindingType::StorageTexture { access, .. } => {
wgt::BindingType::StorageTexture {
access,
format,
view_dimension,
} => {
if format != view.format {
return Err(Error::InvalidStorageTextureFormat {
binding,
layout_format: format,
view_format: view.format,
});
}
if view_dimension != view.dimension {
return Err(Error::InvalidTextureDimension {
binding,
layout_dimension: view_dimension,
view_dimension: view.dimension,
});
}
let internal_use = match access {
wgt::StorageTextureAccess::ReadOnly => {
resource::TextureUse::STORAGE_LOAD

View File

@ -309,6 +309,7 @@ pub struct TextureView<B: hal::Backend> {
pub(crate) aspects: hal::format::Aspects,
pub(crate) format: wgt::TextureFormat,
pub(crate) format_features: wgt::TextureFormatFeatures,
pub(crate) dimension: wgt::TextureViewDimension,
pub(crate) extent: wgt::Extent3d,
pub(crate) samples: hal::image::NumSamples,
pub(crate) framebuffer_attachment: hal::image::FramebufferAttachment,

View File

@ -188,6 +188,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
allowed_usages: wgt::TextureUsage::RENDER_ATTACHMENT,
flags: wgt::TextureFormatFeatureFlags::empty(),
},
dimension: wgt::TextureViewDimension::D2,
extent: wgt::Extent3d {
width: sc.desc.width,
height: sc.desc.height,