Improve docs for TypeInner, valid::TypeFlags, and some internal types.

This commit is contained in:
Jim Blandy
2021-06-16 16:54:55 -07:00
committed by Dzmitry Malyshau
parent 70016ce6e3
commit 696ca340e0
3 changed files with 105 additions and 1 deletions

View File

@@ -127,14 +127,26 @@ impl Function {
}
}
/// A SPIR-V type constructed during code generation.
///
/// In the process of writing SPIR-V, we need to synthesize various types for
/// intermediate results and such. However, it's inconvenient to use
/// `crate::Type` or `crate::TypeInner` for these, as the IR module is immutable
/// so we can't ever create a `Handle<Type>` to refer to them. So for local use
/// in the SPIR-V writer, we have this home-grown type enum that covers only the
/// cases we need (for example, it doesn't cover structs).
#[derive(Debug, PartialEq, Hash, Eq, Copy, Clone)]
enum LocalType {
/// A scalar, vector, or pointer to one of those.
Value {
/// If `None`, this represents a scalar type. If `Some`, this represents
/// a vector type of the given size.
vector_size: Option<crate::VectorSize>,
kind: crate::ScalarKind,
width: crate::Bytes,
pointer_class: Option<spirv::StorageClass>,
},
/// A matrix of floating-point values.
Matrix {
columns: crate::VectorSize,
rows: crate::VectorSize,

View File

@@ -476,6 +476,26 @@ pub enum TypeInner {
width: Bytes,
},
/// Pointer to another type.
///
/// ## Pointers to non-`SIZED` types
///
/// The `base` type of a pointer may be a non-[`SIZED`] type like a
/// dynamically-sized [`Array`], or a [`Struct`] whose last member is a
/// dynamically sized array. Such pointers occur as the types of
/// [`GlobalVariable`] or [`AccessIndex`] expressions referring to
/// dynamically-sized arrays.
///
/// However, among pointers to non-`SIZED` types, only pointers to `Struct`s
/// are [`DATA`]. Pointers to dynamically sized `Array`s cannot be passed as
/// arguments, stored in variables, or held in arrays or structures. Their
/// only use is as the types of `AccessIndex` expressions.
///
/// [`SIZED`]: valid::TypeFlags::SIZED
/// [`DATA`]: valid::TypeFlags::DATA
/// [`Array`]: TypeInner::Array
/// [`Struct`]: TypeInner::Struct
/// [`GlobalVariable`]: Expression::GlobalVariable
/// [`AccessIndex`]: Expression::AccessIndex
Pointer {
base: Handle<Type>,
class: StorageClass,
@@ -487,14 +507,57 @@ pub enum TypeInner {
width: Bytes,
class: StorageClass,
},
/// Homogenous list of elements.
///
/// The `base` type must be a [`SIZED`], [`DATA`] type.
///
/// ## Dynamically sized arrays
///
/// An `Array` is [`SIZED`] unless its `size` is [`Dynamic`].
/// Dynamically-sized arrays may only appear in a few situations:
///
/// - They may appear as the last member of a [`Struct`] whose `top_level`
/// flag is set.
///
/// - They may appear as the base type of a [`Pointer`]. An
/// [`AccessIndex`] expression referring to a top-level struct's final
/// unsized array member would have such a pointer type. However, such
/// pointer types may only appear as the types of such intermediate
/// expressions. They are not [`DATA`], and cannot be stored in
/// variables, held in arrays or structs, or passed as parameters.
///
/// [`SIZED`]: crate::valid::TypeFlags::SIZED
/// [`DATA`]: crate::valid::TypeFlags::DATA
/// [`Dynamic`]: ArraySize::Dynamic
/// [`Struct`]: TypeInner::Struct
/// [`Pointer`]: TypeInner::Pointer
/// [`AccessIndex`]: Expression::AccessIndex
Array {
base: Handle<Type>,
size: ArraySize,
stride: u32,
},
/// User-defined structure.
///
/// A `Struct` type is [`DATA`], and the types of its members must be
/// `DATA` as well.
///
/// Member types must be [`SIZED`], except for the final member of a
/// top-level struct, which may be a dynamically sized [`Array`]. The
/// `Struct` type itself is `SIZED` when all its members are `SIZED`.
///
/// When `top_level` is true, this `Struct` represents the contents of a
/// buffer resource occupying a single binding slot in a shader's resource
/// interface. Top-level `Struct`s may not be used as members of any other
/// struct, or as array elements.
///
/// [`DATA`]: crate::valid::TypeFlags::DATA
/// [`SIZED`]: crate::valid::TypeFlags::SIZED
/// [`Array`]: TypeInner::Array
Struct {
/// This struct serves as the type of a binding slot in a shader's resource interface.
top_level: bool,
members: Vec<StructMember>,
//TODO: should this be unaligned?

View File

@@ -5,16 +5,45 @@ use crate::{
};
bitflags::bitflags! {
/// Flags associated with [`Type`]s by [`Validator`].
///
/// [`Type`]: crate::Type
/// [`Validator`]: crate::valid::Validator
#[repr(transparent)]
pub struct TypeFlags: u8 {
/// Can be used for data variables.
///
/// This flag is required on types of local variables, function
/// arguments, array elements, and struct members.
///
/// This includes all types except `Image`, `Sampler`, `ValuePointer`,
/// and some `Pointer` types.
const DATA = 0x1;
/// The data type has known size.
/// The data type has a size known by pipeline creation time.
///
/// Unsized types are quite restricted. The only unsized types permitted
/// by Naga, other than the non-[`DATA`] types like [`Image`] and
/// [`Sampler`], are dynamically-sized [`Array`s], and [`Struct`s] whose
/// last members are such arrays. See the documentation for those types
/// for details.
///
/// [`DATA`]: TypeFlags::DATA
/// [`Image`]: crate::Type::Image
/// [`Sampler`]: crate::Type::Sampler
/// [`Array`]: crate::Type::Array
/// [`Struct`]: crate::Type::struct
const SIZED = 0x2;
/// Can be be used for interfacing between pipeline stages.
///
/// This includes non-bool scalars and vectors, matrices, and structs
/// and arrays containing only interface types.
const INTERFACE = 0x4;
/// Can be used for host-shareable structures.
const HOST_SHARED = 0x8;
/// This is a top-level host-shareable type.
const TOP_LEVEL = 0x10;
}