Skip to content

Commit

Permalink
Document spirv-std, and add warn(missing_docs) (#784)
Browse files Browse the repository at this point in the history
  • Loading branch information
khyperia committed Oct 28, 2021
1 parent 6254813 commit 1517a8b
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 7 deletions.
14 changes: 9 additions & 5 deletions crates/spirv-std/src/byte_addressable_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Container for an untyped blob of data.

use core::mem;

#[spirv(buffer_load_intrinsic)]
Expand All @@ -18,19 +20,21 @@ unsafe extern "unadjusted" fn buffer_store_intrinsic<T>(
unimplemented!()
} // actually implemented in the compiler

#[repr(transparent)]
pub struct ByteAddressableBuffer<'a> {
pub data: &'a mut [u32],
}

/// `ByteAddressableBuffer` is an untyped blob of data, allowing loads and stores of arbitrary
/// basic data types at arbitrary indicies. However, all data must be aligned to size 4, each
/// element within the data (e.g. struct fields) must have a size and alignment of a multiple of 4,
/// and the `byte_index` passed to load and store must be a multiple of 4 (`byte_index` will be
/// rounded down to the nearest multiple of 4). So, it's not technically a *byte* addressable
/// buffer, but rather a *word* buffer, but this naming and behavior was inhereted from HLSL (where
/// it's UB to pass in an index not a multiple of 4).
#[repr(transparent)]
pub struct ByteAddressableBuffer<'a> {
/// The underlying array of bytes, able to be directly accessed.
pub data: &'a mut [u32],
}

impl<'a> ByteAddressableBuffer<'a> {
/// Creates a `ByteAddressableBuffer` from the untyped blob of data.
#[inline]
pub fn new(data: &'a mut [u32]) -> Self {
Self { data }
Expand Down
3 changes: 3 additions & 0 deletions crates/spirv-std/src/float.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Traits and helper functions related to floats.

use crate::vector::Vector;

/// Abstract trait representing a SPIR-V floating point type.
Expand All @@ -6,6 +8,7 @@ use crate::vector::Vector;
/// Implementing this trait on non-primitive-float types breaks assumptions of other unsafe code,
/// and should not be done.
pub unsafe trait Float: num_traits::Float + crate::scalar::Scalar + Default {
/// Width of the float, in bits.
const WIDTH: usize;
}

Expand Down
28 changes: 28 additions & 0 deletions crates/spirv-std/src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,64 @@ pub mod __private {
pub use {f32, f64, i16, i32, i64, i8, u16, u32, u64, u8};
}

/// A 1d image used with a sampler.
pub type Image1d = crate::Image!(1D, type=f32, sampled, __crate_root=crate);
/// A 2d image used with a sampler. This is pretty typical and probably what you want.
pub type Image2d = crate::Image!(2D, type=f32, sampled, __crate_root=crate);
/// A 3d image used with a sampler.
pub type Image3d = crate::Image!(3D, type=f32, sampled, __crate_root=crate);
/// A 1d image used with a sampler, containing unsigned integer data.
pub type Image1dU = crate::Image!(1D, type=u32, sampled, __crate_root=crate);
/// A 2d image used with a sampler, containing unsigned integer data.
pub type Image2dU = crate::Image!(2D, type=u32, sampled, __crate_root=crate);
/// A 3d image used with a sampler, containing unsigned integer data.
pub type Image3dU = crate::Image!(3D, type=u32, sampled, __crate_root=crate);
/// A 1d image used with a sampler, containing signed integer data.
pub type Image1dI = crate::Image!(1D, type=i32, sampled, __crate_root=crate);
/// A 2d image used with a sampler, containing signed integer data.
pub type Image2dI = crate::Image!(2D, type=i32, sampled, __crate_root=crate);
/// A 3d image used with a sampler, containing signed integer data.
pub type Image3dI = crate::Image!(3D, type=i32, sampled, __crate_root=crate);

/// An array of 1d images, used with a sampler.
pub type Image1dArray = crate::Image!(1D, type=f32, sampled, arrayed, __crate_root=crate);
/// An array of 2d images, used with a sampler.
pub type Image2dArray = crate::Image!(2D, type=f32, sampled, arrayed, __crate_root=crate);
/// An array of 3d images, used with a sampler.
pub type Image3dArray = crate::Image!(3D, type=f32, sampled, arrayed, __crate_root=crate);
/// An array of 1d images, used with a sampler, each containing unsigned integer data.
pub type Image1dUArray = crate::Image!(1D, type=u32, sampled, arrayed, __crate_root=crate);
/// An array of 2d images, used with a sampler, each containing unsigned integer data.
pub type Image2dUArray = crate::Image!(2D, type=u32, sampled, arrayed, __crate_root=crate);
/// An array of 3d images, used with a sampler, each containing unsigned integer data.
pub type Image3dUArray = crate::Image!(3D, type=u32, sampled, arrayed, __crate_root=crate);
/// An array of 1d images, used with a sampler, each containing signed integer data.
pub type Image1dIArray = crate::Image!(1D, type=i32, sampled, arrayed, __crate_root=crate);
/// An array of 2d images, used with a sampler, each containing signed integer data.
pub type Image2dIArray = crate::Image!(2D, type=i32, sampled, arrayed, __crate_root=crate);
/// An array of 3d images, used with a sampler, each containing signed integer data.
pub type Image3dIArray = crate::Image!(3D, type=i32, sampled, arrayed, __crate_root=crate);

/// A 1d storage image, directly accessed, without using a sampler.
pub type StorageImage1d = crate::Image!(1D, type=f32, sampled=false, __crate_root=crate);
/// A 2d storage image, directly accessed, without using a sampler.
pub type StorageImage2d = crate::Image!(2D, type=f32, sampled=false, __crate_root=crate);
/// A 3d storage image, directly accessed, without using a sampler.
pub type StorageImage3d = crate::Image!(3D, type=f32, sampled=false, __crate_root=crate);
/// A 1d storage image, directly accessed without a sampler, containing unsigned integer data.
pub type StorageImage1dU = crate::Image!(1D, type=u32, sampled=false, __crate_root=crate);
/// A 2d storage image, directly accessed without a sampler, containing unsigned integer data.
pub type StorageImage2dU = crate::Image!(2D, type=u32, sampled=false, __crate_root=crate);
/// A 3d storage image, directly accessed without a sampler, containing unsigned integer data.
pub type StorageImage3dU = crate::Image!(3D, type=u32, sampled=false, __crate_root=crate);
/// A 1d storage image, directly accessed without a sampler, containing signed integer data.
pub type StorageImage1dI = crate::Image!(1D, type=i32, sampled=false, __crate_root=crate);
/// A 2d storage image, directly accessed without a sampler, containing signed integer data.
pub type StorageImage2dI = crate::Image!(2D, type=i32, sampled=false, __crate_root=crate);
/// A 3d storage image, directly accessed without a sampler, containing signed integer data.
pub type StorageImage3dI = crate::Image!(3D, type=i32, sampled=false, __crate_root=crate);

/// A cubemap, i.e. a cube of 6 textures, sampled using a direction rather than image coordinates.
pub type Cubemap = crate::Image!(cube, type=f32, sampled, __crate_root=crate);

// TODO: Migrate Image parameters back to their enum values once #![feature(adt_const_params)] is
Expand Down
4 changes: 4 additions & 0 deletions crates/spirv-std/src/integer.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
//! Traits related to integers.

/// Abstract trait representing any SPIR-V integer type.
///
/// # Safety
/// Implementing this trait on non-primitive-integer types breaks assumptions of other unsafe code,
/// and should not be done.
pub unsafe trait Integer: num_traits::PrimInt + crate::scalar::Scalar {
/// Width of the integer, in bits.
const WIDTH: usize;
/// If the integer is signed: true means signed, false means unsigned.
const SIGNED: bool;
}

Expand Down
4 changes: 4 additions & 0 deletions crates/spirv-std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@
// The part of `adt_const_params` we're using (C-like enums) is not incomplete.
incomplete_features,
)]
#![warn(missing_docs)]

//! Core functions, traits, and more that make up a "standard library" for SPIR-V for use in
//! rust-gpu.

#[cfg_attr(not(target_arch = "spirv"), macro_use)]
pub extern crate spirv_std_macros as macros;
Expand Down
4 changes: 4 additions & 0 deletions crates/spirv-std/src/memory.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Types for handling memory ordering constraints for concurrent memory access.

/// Specification for how large of a scope some instructions should operate on - used when calling
/// functions that take a configurable scope.
#[derive(Debug, PartialEq, Eq)]
pub enum Scope {
/// Crosses multiple devices.
Expand All @@ -22,6 +24,8 @@ pub enum Scope {
}

bitflags::bitflags! {
/// Memory semantics to determine how some operations should function - used when calling such
/// configurable operations.
pub struct Semantics: u32 {
/// No memory semantics.
const NONE = 0;
Expand Down
9 changes: 9 additions & 0 deletions crates/spirv-std/src/ray_tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,19 +159,28 @@ bitflags::bitflags! {
}
}

/// Describes the type of the intersection which is currently the candidate in a ray query,
/// returned by [`RayQuery::get_candidate_intersection_type`].
#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[allow(clippy::upper_case_acronyms)]
pub enum CandidateIntersection {
/// A potential intersection with a triangle is being considered.
Triangle = 0,
/// A potential intersection with an axis-aligned bounding box is being considered.
AABB = 1,
}

/// Describes the type of the intersection currently committed in a ray query, returned by
/// [`RayQuery::get_committed_intersection_type`].
#[repr(u32)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CommittedIntersection {
/// No intersection is committed.
None = 0,
/// An intersection with a triangle has been committed.
Triangle = 1,
/// A user-generated intersection has been committed.
Generated = 2,
}

Expand Down
17 changes: 17 additions & 0 deletions crates/spirv-std/src/runtime_array.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use core::marker::PhantomData;

/// Dynamically-sized arrays in Rust carry around their length as the second half of a tuple.
/// Unfortunately, sometimes SPIR-V provides an unsized array with no way of obtaining its length.
/// Hence, this type represents something very similar to a slice, but with no way of knowing its
/// length.
#[spirv(runtime_array)]
pub struct RuntimeArray<T> {
// spooky! this field does not exist, so if it's referenced in rust code, things will explode
Expand All @@ -11,6 +15,12 @@ pub struct RuntimeArray<T> {
// the array, it's impossible to make them be safe operations (indexing out of bounds), and
// Index/IndexMut are marked as safe functions.
impl<T> RuntimeArray<T> {
/// Index the array. Unfortunately, because the length of the runtime array cannot be known,
/// this function will happily index outside of the bounds of the array, and so is unsafe.
///
/// # Safety
/// Bounds checking is not performed, and indexing outside the bounds of the array can happen,
/// and lead to UB.
#[spirv_std_macros::gpu_only]
#[allow(clippy::empty_loop)]
pub unsafe fn index(&self, index: usize) -> &T {
Expand All @@ -23,6 +33,13 @@ impl<T> RuntimeArray<T> {
}
}

/// Index the array, returning a mutable reference to an element. Unfortunately, because the
/// length of the runtime array cannot be known, this function will happily index outside of
/// the bounds of the array, and so is unsafe.
///
/// # Safety
/// Bounds checking is not performed, and indexing outside the bounds of the array can happen,
/// and lead to UB.
#[spirv_std_macros::gpu_only]
#[allow(clippy::empty_loop)]
pub unsafe fn index_mut(&mut self, index: usize) -> &mut T {
Expand Down
2 changes: 2 additions & 0 deletions crates/spirv-std/src/scalar.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Traits related to scalars.

/// Abstract trait representing a SPIR-V scalar type.
///
/// # Safety
Expand Down
2 changes: 2 additions & 0 deletions crates/spirv-std/src/vector.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Traits related to vectors.

/// Abstract trait representing a SPIR-V vector type.
///
/// # Safety
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/arch/debug_printf_type_checking.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ error[E0277]: the trait bound `{float}: Vector<f32, 2_usize>` is not satisfied
<DVec2 as Vector<f64, 2_usize>>
and 13 others
note: required by a bound in `debug_printf_assert_is_vector`
--> $SPIRV_STD_SRC/lib.rs:142:8
--> $SPIRV_STD_SRC/lib.rs:146:8
|
142 | V: crate::vector::Vector<TY, SIZE>,
146 | V: crate::vector::Vector<TY, SIZE>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `debug_printf_assert_is_vector`

error[E0308]: mismatched types
Expand Down

0 comments on commit 1517a8b

Please sign in to comment.