Let validation check for more unsupported builtins.

Add `valid::Capabilities` flags for the `ClipDistance` and
`CullDistance` builtins, which are not supported by all back ends.

Have the CLI perform valation with only those capabilities that the
requested back ends support.

Fixes #1961.
This commit is contained in:
Jim Blandy
2022-05-31 17:29:40 -07:00
parent 7f5ec31825
commit 1c21fc02fe
3 changed files with 40 additions and 22 deletions

View File

@@ -317,12 +317,23 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
_ => return Err(CliError("Unknown input file extension").into()),
};
// Decide which capabilities our output formats can support.
let validation_caps =
output_paths
.iter()
.fold(naga::valid::Capabilities::all(), |caps, path| {
use naga::valid::Capabilities as C;
let missing = match Path::new(path).extension().and_then(|ex| ex.to_str()) {
Some("wgsl") => C::CLIP_DISTANCE | C::CULL_DISTANCE,
Some("metal") => C::CULL_DISTANCE,
_ => C::empty(),
};
caps & !missing
});
// validate the IR
let info = match naga::valid::Validator::new(
params.validation_flags,
naga::valid::Capabilities::all(),
)
.validate(&module)
let info = match naga::valid::Validator::new(params.validation_flags, validation_caps)
.validate(&module)
{
Ok(info) => Some(info),
Err(error) => {

View File

@@ -135,6 +135,16 @@ impl VaryingContext<'_> {
}
self.built_ins.insert(canonical);
let required = match built_in {
Bi::ClipDistance => Capabilities::CLIP_DISTANCE,
Bi::CullDistance => Capabilities::CULL_DISTANCE,
Bi::PrimitiveIndex => Capabilities::PRIMITIVE_INDEX,
_ => Capabilities::empty(),
};
if !self.capabilities.contains(required) {
return Err(VaryingError::UnsupportedCapability(required));
}
let width = 4;
let (visible, type_good) = match built_in {
Bi::BaseInstance | Bi::BaseVertex | Bi::InstanceIndex | Bi::VertexIndex => (
@@ -206,21 +216,14 @@ impl VaryingContext<'_> {
width: crate::BOOL_WIDTH,
},
),
Bi::PrimitiveIndex => {
if !self.capabilities.contains(Capabilities::PRIMITIVE_INDEX) {
return Err(VaryingError::UnsupportedCapability(
Capabilities::PRIMITIVE_INDEX,
));
}
(
self.stage == St::Fragment && !self.output,
*ty_inner
== Ti::Scalar {
kind: Sk::Uint,
width,
},
)
}
Bi::PrimitiveIndex => (
self.stage == St::Fragment && !self.output,
*ty_inner
== Ti::Scalar {
kind: Sk::Uint,
width,
},
),
Bi::SampleIndex => (
self.stage == St::Fragment && !self.output,
*ty_inner

View File

@@ -82,11 +82,11 @@ bitflags::bitflags! {
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
pub struct Capabilities: u8 {
/// Support for `AddressSpace:PushConstant`.
/// Support for [`AddressSpace:PushConstant`].
const PUSH_CONSTANT = 0x1;
/// Float values with width = 8.
const FLOAT64 = 0x2;
/// Support for `Builtin:PrimitiveIndex`.
/// Support for [`Builtin:PrimitiveIndex`].
const PRIMITIVE_INDEX = 0x4;
/// Support for non-uniform indexing of sampled textures and storage buffer arrays.
const SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING = 0x8;
@@ -94,6 +94,10 @@ bitflags::bitflags! {
const UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING = 0x10;
/// Support for non-uniform indexing of samplers.
const SAMPLER_NON_UNIFORM_INDEXING = 0x20;
/// Support for [`Builtin::ClipDistance`].
const CLIP_DISTANCE = 0x40;
/// Support for [`Builtin::CullDistance`].
const CULL_DISTANCE = 0x80;
}
}