mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Standardize some docs (#1660)
* Rewrite front/back doc summaries - Use line comments instead of block comments - Standardize language for each front/backend - Add reference link for each format - Minor punctuation changes * Add documentation for keywords module * Clarify contents of keywords module in summary * Refer to modules by their type name * Add basic summary for valid module * Adjust EarlyDepthTest and ConservativeDepth docs * Remove "in" from list * Adjust wording * Standardize format of docstrings * Adjust module links to be consistent with other links * Add summary for reserved keywords list * Remove extraneous doc spaces with `cargo fmt` * Correct spelling of whether and rewrite some lines * Fill out GLSL backend docs * Remove unnecessary link targets * Fill out DOT backend docs * Change module line comments to block comments * Remove unnecessary spaces * Fix mistake during rebasing
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
use std::fs;
|
||||
use std::{error::Error, fmt, io::Read, path::Path, str::FromStr};
|
||||
|
||||
/// Translate shaders to different formats
|
||||
/// Translate shaders to different formats.
|
||||
#[derive(argh::FromArgs, Debug, Clone)]
|
||||
struct Args {
|
||||
/// bitmask of the ValidationFlags to be used, use 0 to disable validation
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
/*! GraphViz (DOT) backend
|
||||
*
|
||||
* This backend writes a graph in the DOT format, for the ease
|
||||
* of IR inspection and debugging.
|
||||
!*/
|
||||
/*!
|
||||
Backend for [DOT][dot] (Graphviz).
|
||||
|
||||
This backend writes a graph in the DOT language, for the ease
|
||||
of IR inspection and debugging.
|
||||
|
||||
[dot]: https://graphviz.org/doc/info/lang.html
|
||||
*/
|
||||
|
||||
use crate::{
|
||||
arena::Handle,
|
||||
@@ -470,6 +473,7 @@ fn write_fun(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write shader module to a [`String`].
|
||||
pub fn write(module: &crate::Module, mod_info: Option<&ModuleInfo>) -> Result<String, FmtError> {
|
||||
use std::fmt::Write as _;
|
||||
|
||||
|
||||
@@ -6,56 +6,57 @@ use crate::{
|
||||
use std::fmt::Write;
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Structure used to encode a set of additions to glsl that aren't supported by all versions
|
||||
/// Structure used to encode additions to GLSL that aren't supported by all versions.
|
||||
pub struct Features: u32 {
|
||||
/// Buffer address space support
|
||||
/// Buffer address space support.
|
||||
const BUFFER_STORAGE = 1;
|
||||
const ARRAY_OF_ARRAYS = 1 << 1;
|
||||
/// 8 byte floats
|
||||
/// 8 byte floats.
|
||||
const DOUBLE_TYPE = 1 << 2;
|
||||
/// Includes support for more image formats
|
||||
/// More image formats.
|
||||
const FULL_IMAGE_FORMATS = 1 << 3;
|
||||
const MULTISAMPLED_TEXTURES = 1 << 4;
|
||||
const MULTISAMPLED_TEXTURE_ARRAYS = 1 << 5;
|
||||
const CUBE_TEXTURES_ARRAY = 1 << 6;
|
||||
const COMPUTE_SHADER = 1 << 7;
|
||||
/// Adds support for image load and early depth tests
|
||||
/// Image load and early depth tests.
|
||||
const IMAGE_LOAD_STORE = 1 << 8;
|
||||
const CONSERVATIVE_DEPTH = 1 << 9;
|
||||
/// Interpolation and auxiliary qualifiers. Perspective, Flat, and
|
||||
/// Centroid are available in all GLSL versions we support.
|
||||
/// Interpolation and auxiliary qualifiers.
|
||||
///
|
||||
/// Perspective, Flat, and Centroid are available in all GLSL versions we support.
|
||||
const NOPERSPECTIVE_QUALIFIER = 1 << 11;
|
||||
const SAMPLE_QUALIFIER = 1 << 12;
|
||||
const CLIP_DISTANCE = 1 << 13;
|
||||
const CULL_DISTANCE = 1 << 14;
|
||||
// Sample ID
|
||||
/// Sample ID.
|
||||
const SAMPLE_VARIABLES = 1 << 15;
|
||||
/// Arrays with a dynamic length
|
||||
/// Arrays with a dynamic length.
|
||||
const DYNAMIC_ARRAY_SIZE = 1 << 16;
|
||||
const MULTI_VIEW = 1 << 17;
|
||||
/// Adds support for fused multiply-add
|
||||
/// Fused multiply-add.
|
||||
const FMA = 1 << 18;
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper structure used to store the required [`Features`](Features) needed to output a
|
||||
/// Helper structure used to store the required [`Features`] needed to output a
|
||||
/// [`Module`](crate::Module)
|
||||
///
|
||||
/// Provides helper methods to check for availability and writing required extensions
|
||||
pub struct FeaturesManager(Features);
|
||||
|
||||
impl FeaturesManager {
|
||||
/// Creates a new [`FeaturesManager`](FeaturesManager) instance
|
||||
/// Creates a new [`FeaturesManager`] instance
|
||||
pub fn new() -> Self {
|
||||
Self(Features::empty())
|
||||
}
|
||||
|
||||
/// Adds to the list of required [`Features`](Features)
|
||||
/// Adds to the list of required [`Features`]
|
||||
pub fn request(&mut self, features: Features) {
|
||||
self.0 |= features
|
||||
}
|
||||
|
||||
/// Checks that all required [`Features`](Features) are available for the specified
|
||||
/// Checks that all required [`Features`] are available for the specified
|
||||
/// [`Version`](super::Version) otherwise returns an
|
||||
/// [`Error::MissingFeatures`](super::Error::MissingFeatures)
|
||||
pub fn check_availability(&self, version: Version) -> BackendResult {
|
||||
@@ -214,10 +215,10 @@ impl FeaturesManager {
|
||||
}
|
||||
|
||||
impl<'a, W> Writer<'a, W> {
|
||||
/// Helper method that searches the module for all the needed [`Features`](Features)
|
||||
/// Helper method that searches the module for all the needed [`Features`]
|
||||
///
|
||||
/// # Errors
|
||||
/// If the version doesn't support any of the needed [`Features`](Features) a
|
||||
/// If the version doesn't support any of the needed [`Features`] a
|
||||
/// [`Error::MissingFeatures`](super::Error::MissingFeatures) will be returned
|
||||
pub(super) fn collect_required_features(&mut self) -> BackendResult {
|
||||
let ep_info = self.info.get_entry_point(self.entry_point_idx as usize);
|
||||
@@ -386,7 +387,7 @@ impl<'a, W> Writer<'a, W> {
|
||||
self.features.check_availability(self.options.version)
|
||||
}
|
||||
|
||||
/// Helper method that checks the [`Features`](Features) needed by a scalar
|
||||
/// Helper method that checks the [`Features`] needed by a scalar
|
||||
fn scalar_required_features(&mut self, kind: ScalarKind, width: Bytes) {
|
||||
if kind == ScalarKind::Float && width == 8 {
|
||||
self.features.request(Features::DOUBLE_TYPE);
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
//! OpenGL shading language backend
|
||||
//!
|
||||
//! The main structure is [`Writer`](Writer), it maintains internal state that is used
|
||||
//! to output a [`Module`](crate::Module) into glsl
|
||||
//!
|
||||
//! # Supported versions
|
||||
//! ### Core
|
||||
//! - 330
|
||||
//! - 400
|
||||
//! - 410
|
||||
//! - 420
|
||||
//! - 430
|
||||
//! - 450
|
||||
//! - 460
|
||||
//!
|
||||
//! ### ES
|
||||
//! - 300
|
||||
//! - 310
|
||||
//!
|
||||
/*!
|
||||
Backend for [GLSL][glsl] (OpenGL Shading Language).
|
||||
|
||||
The main structure is [`Writer`], it maintains internal state that is used
|
||||
to output a [`Module`](crate::Module) into glsl
|
||||
|
||||
# Supported versions
|
||||
### Core
|
||||
- 330
|
||||
- 400
|
||||
- 410
|
||||
- 420
|
||||
- 430
|
||||
- 450
|
||||
- 460
|
||||
|
||||
### ES
|
||||
- 300
|
||||
- 310
|
||||
|
||||
[glsl]: https://www.khronos.org/registry/OpenGL/index_gl.php
|
||||
*/
|
||||
|
||||
// GLSL is mostly a superset of C but it also removes some parts of it this is a list of relevant
|
||||
// aspects for this backend.
|
||||
@@ -33,7 +36,7 @@
|
||||
// `#extension name: behaviour`
|
||||
// Extensions provide increased features in a plugin fashion but they aren't required to be
|
||||
// supported hence why they are called extensions, that's why `behaviour` is used it specifies
|
||||
// wether the extension is strictly required or if it should only be enabled if needed. In our case
|
||||
// whether the extension is strictly required or if it should only be enabled if needed. In our case
|
||||
// when we use extensions we set behaviour to `require` always.
|
||||
//
|
||||
// The only thing that glsl removes that makes a difference are pointers.
|
||||
@@ -61,11 +64,12 @@ mod features;
|
||||
/// Contains a constant with a slice of all the reserved keywords RESERVED_KEYWORDS
|
||||
mod keywords;
|
||||
|
||||
/// List of supported core glsl versions
|
||||
/// List of supported `core` GLSL versions.
|
||||
pub const SUPPORTED_CORE_VERSIONS: &[u16] = &[330, 400, 410, 420, 430, 440, 450];
|
||||
/// List of supported es glsl versions
|
||||
/// List of supported `es` GLSL versions.
|
||||
pub const SUPPORTED_ES_VERSIONS: &[u16] = &[300, 310, 320];
|
||||
|
||||
/// Mapping between resources and bindings.
|
||||
pub type BindingMap = std::collections::BTreeMap<crate::ResourceBinding, u8>;
|
||||
|
||||
impl crate::AtomicFunction {
|
||||
@@ -130,14 +134,14 @@ impl<'a> GlobalTypeKind<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// glsl version
|
||||
/// A GLSL version.
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
pub enum Version {
|
||||
/// `core` glsl
|
||||
/// `core` GLSL.
|
||||
Desktop(u16),
|
||||
/// `es` glsl
|
||||
/// `es` GLSL.
|
||||
Embedded(u16),
|
||||
}
|
||||
|
||||
@@ -206,10 +210,11 @@ impl fmt::Display for Version {
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
/// Configuration flags for the [`Writer`].
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
pub struct WriterFlags: u32 {
|
||||
/// Flip output Y and extend Z from (0,1) to (-1,1).
|
||||
/// Flip output Y and extend Z from (0, 1) to (-1, 1).
|
||||
const ADJUST_COORDINATE_SPACE = 0x1;
|
||||
/// Supports GL_EXT_texture_shadow_lod on the host, which provides
|
||||
/// additional functions on shadows and arrays of shadows.
|
||||
@@ -217,14 +222,14 @@ bitflags::bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
/// Structure that contains the configuration used in the [`Writer`](Writer)
|
||||
/// Configuration used in the [`Writer`].
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
pub struct Options {
|
||||
/// The glsl version to be used
|
||||
/// The GLSL version to be used.
|
||||
pub version: Version,
|
||||
/// Configuration flags for the writer.
|
||||
/// Configuration flags for the [`Writer`].
|
||||
pub writer_flags: WriterFlags,
|
||||
/// Map of resources association to binding locations.
|
||||
pub binding_map: BindingMap,
|
||||
@@ -240,40 +245,41 @@ impl Default for Options {
|
||||
}
|
||||
}
|
||||
|
||||
// A subset of options that are meant to be changed per pipeline.
|
||||
/// A subset of options meant to be changed per pipeline.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
pub struct PipelineOptions {
|
||||
/// The stage of the entry point
|
||||
/// The stage of the entry point.
|
||||
pub shader_stage: ShaderStage,
|
||||
/// The name of the entry point
|
||||
/// The name of the entry point.
|
||||
///
|
||||
/// If no entry point that matches is found a error will be thrown while creating a new instance
|
||||
/// of [`Writer`](struct.Writer.html)
|
||||
/// If no entry point that matches is found while creating a [`Writer`], a error will be thrown.
|
||||
pub entry_point: String,
|
||||
}
|
||||
|
||||
/// Structure that contains a reflection info
|
||||
/// Reflection info for texture mappings and uniforms.
|
||||
pub struct ReflectionInfo {
|
||||
/// Mapping between texture names and variables/samplers.
|
||||
pub texture_mapping: crate::FastHashMap<String, TextureMapping>,
|
||||
/// Mapping between uniform variables and names.
|
||||
pub uniforms: crate::FastHashMap<Handle<crate::GlobalVariable>, String>,
|
||||
}
|
||||
|
||||
/// Structure that connects a texture to a sampler or not
|
||||
/// Mapping between a texture and its sampler, if it exists.
|
||||
///
|
||||
/// glsl pre vulkan has no concept of separate textures and samplers instead everything is a
|
||||
/// `gsamplerN` where `g` is the scalar type and `N` is the dimension, but naga uses separate textures
|
||||
/// and samplers in the IR so the backend produces a [`HashMap`](crate::FastHashMap) with the texture name
|
||||
/// as a key and a [`TextureMapping`](TextureMapping) as a value this way the user knows where to bind.
|
||||
/// GLSL pre-Vulkan has no concept of separate textures and samplers. Instead, everything is a
|
||||
/// `gsamplerN` where `g` is the scalar type and `N` is the dimension. But naga uses separate textures
|
||||
/// and samplers in the IR, so the backend produces a [`FastHashMap`](crate::FastHashMap) with the texture name
|
||||
/// as a key and a [`TextureMapping`] as a value. This way, the user knows where to bind.
|
||||
///
|
||||
/// [`Storage`](crate::ImageClass::Storage) images produce `gimageN` and don't have an associated sampler
|
||||
/// so the [`sampler`](Self::sampler) field will be [`None`](std::option::Option::None)
|
||||
/// [`Storage`](crate::ImageClass::Storage) images produce `gimageN` and don't have an associated sampler,
|
||||
/// so the [`sampler`](Self::sampler) field will be [`None`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TextureMapping {
|
||||
/// Handle to the image global variable
|
||||
/// Handle to the image global variable.
|
||||
pub texture: Handle<crate::GlobalVariable>,
|
||||
/// Handle to the associated sampler global variable if it exists
|
||||
/// Handle to the associated sampler global variable, if it exists.
|
||||
pub sampler: Option<Handle<crate::GlobalVariable>>,
|
||||
}
|
||||
|
||||
@@ -338,88 +344,88 @@ impl ShaderStage {
|
||||
/// Shorthand result used internally by the backend
|
||||
type BackendResult<T = ()> = Result<T, Error>;
|
||||
|
||||
/// A glsl compilation error.
|
||||
/// A GLSL compilation error.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
/// A error occurred while writing to the output
|
||||
/// A error occurred while writing to the output.
|
||||
#[error("Format error")]
|
||||
FmtError(#[from] FmtError),
|
||||
/// The specified [`Version`](Version) doesn't have all required [`Features`](super)
|
||||
/// The specified [`Version`] doesn't have all required [`Features`].
|
||||
///
|
||||
/// Contains the missing [`Features`](Features)
|
||||
/// Contains the missing [`Features`].
|
||||
#[error("The selected version doesn't support {0:?}")]
|
||||
MissingFeatures(Features),
|
||||
/// [`AddressSpace::PushConstant`](crate::AddressSpace::PushConstant) was used more than
|
||||
/// once in the entry point which isn't supported
|
||||
/// once in the entry point, which isn't supported.
|
||||
#[error("Multiple push constants aren't supported")]
|
||||
MultiplePushConstants,
|
||||
/// The specified [`Version`](Version) isn't supported
|
||||
/// The specified [`Version`] isn't supported.
|
||||
#[error("The specified version isn't supported")]
|
||||
VersionNotSupported,
|
||||
/// The entry point couldn't be found
|
||||
/// The entry point couldn't be found.
|
||||
#[error("The requested entry point couldn't be found")]
|
||||
EntryPointNotFound,
|
||||
/// A call was made to an unsupported external
|
||||
/// A call was made to an unsupported external.
|
||||
#[error("A call was made to an unsupported external: {0}")]
|
||||
UnsupportedExternal(String),
|
||||
/// A scalar with an unsupported width was requested
|
||||
/// A scalar with an unsupported width was requested.
|
||||
#[error("A scalar with an unsupported width was requested: {0:?} {1:?}")]
|
||||
UnsupportedScalar(crate::ScalarKind, crate::Bytes),
|
||||
/// A image was used with multiple samplers, this isn't supported
|
||||
/// A image was used with multiple samplers, which isn't supported.
|
||||
#[error("A image was used with multiple samplers")]
|
||||
ImageMultipleSamplers,
|
||||
#[error("{0}")]
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
/// Binary operation with a different logic on the GLSL side
|
||||
/// Binary operation with a different logic on the GLSL side.
|
||||
enum BinaryOperation {
|
||||
/// Vector comparison should use the function like `greaterThan()`, etc.
|
||||
VectorCompare,
|
||||
/// GLSL `%` is SPIR-V `OpUMod/OpSMod` and `mod()` is `OpFMod`, but [`BinaryOperator::Modulo`](crate::BinaryOperator::Modulo) is `OpFRem`
|
||||
/// GLSL `%` is SPIR-V `OpUMod/OpSMod` and `mod()` is `OpFMod`, but [`BinaryOperator::Modulo`](crate::BinaryOperator::Modulo) is `OpFRem`.
|
||||
Modulo,
|
||||
/// Any plain operation. No additional logic required
|
||||
/// Any plain operation. No additional logic required.
|
||||
Other,
|
||||
}
|
||||
|
||||
/// Main structure of the glsl backend responsible for all code generation
|
||||
/// Writer responsible for all code generation.
|
||||
pub struct Writer<'a, W> {
|
||||
// Inputs
|
||||
/// The module being written
|
||||
/// The module being written.
|
||||
module: &'a crate::Module,
|
||||
/// The module analysis.
|
||||
info: &'a valid::ModuleInfo,
|
||||
/// The output writer
|
||||
/// The output writer.
|
||||
out: W,
|
||||
/// User defined configuration to be used
|
||||
/// User defined configuration to be used.
|
||||
options: &'a Options,
|
||||
|
||||
// Internal State
|
||||
/// Features manager used to store all the needed features and write them
|
||||
/// Features manager used to store all the needed features and write them.
|
||||
features: FeaturesManager,
|
||||
namer: proc::Namer,
|
||||
/// A map with all the names needed for writing the module
|
||||
/// (generated by a [`Namer`](crate::proc::Namer))
|
||||
/// (generated by a [`Namer`](crate::proc::Namer)).
|
||||
names: crate::FastHashMap<NameKey, String>,
|
||||
/// A map with the names of global variables needed for reflections
|
||||
/// A map with the names of global variables needed for reflections.
|
||||
reflection_names_globals: crate::FastHashMap<Handle<crate::GlobalVariable>, String>,
|
||||
/// The selected entry point
|
||||
/// The selected entry point.
|
||||
entry_point: &'a crate::EntryPoint,
|
||||
/// The index of the selected entry point
|
||||
/// The index of the selected entry point.
|
||||
entry_point_idx: proc::EntryPointIndex,
|
||||
/// Used to generate a unique number for blocks
|
||||
/// A generator for unique block numbers.
|
||||
block_id: IdGenerator,
|
||||
/// Set of expressions that have associated temporary variables
|
||||
/// Set of expressions that have associated temporary variables.
|
||||
named_expressions: crate::NamedExpressions,
|
||||
}
|
||||
|
||||
impl<'a, W: Write> Writer<'a, W> {
|
||||
/// Creates a new [`Writer`](Writer) instance
|
||||
/// Creates a new [`Writer`] instance.
|
||||
///
|
||||
/// # Errors
|
||||
/// - If the version specified isn't supported (or invalid)
|
||||
/// - If the entry point couldn't be found on the module
|
||||
/// - If the version specified doesn't support some used features
|
||||
/// - If the version specified is invalid or supported.
|
||||
/// - If the entry point couldn't be found in the module.
|
||||
/// - If the version specified doesn't support some used features.
|
||||
pub fn new(
|
||||
out: W,
|
||||
module: &'a crate::Module,
|
||||
@@ -1988,7 +1994,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
Expression::Load { pointer } => self.write_expr(pointer, ctx)?,
|
||||
// `ImageSample` is a bit complicated compared to the rest of the IR.
|
||||
//
|
||||
// First there are three variations depending wether the sample level is explicitly set,
|
||||
// First there are three variations depending whether the sample level is explicitly set,
|
||||
// if it's automatic or it it's bias:
|
||||
// `texture(image, coordinate)` - Automatic sample level
|
||||
// `texture(image, coordinate, bias)` - Bias sample level
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
//! Helpers for the hlsl backend
|
||||
//!
|
||||
//! Important note about `Expression::ImageQuery`/`Expression::ArrayLength` and hlsl backend:
|
||||
//!
|
||||
//! Due to implementation of `GetDimensions` function in hlsl (<https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-getdimensions>)
|
||||
//! backend can't work with it as an expression.
|
||||
//! Instead, it generates a unique wrapped function per `Expression::ImageQuery`, based on texure info and query function.
|
||||
//! See `WrappedImageQuery` struct that represents a unique function and will be generated before writing all statements and expressions.
|
||||
//! This allowed to works with `Expression::ImageQuery` as expression and write wrapped function.
|
||||
//!
|
||||
//! For example:
|
||||
//! ```wgsl
|
||||
//! let dim_1d = textureDimensions(image_1d);
|
||||
//! ```
|
||||
//!
|
||||
//! ```hlsl
|
||||
//! int NagaDimensions1D(Texture1D<float4>)
|
||||
//! {
|
||||
//! uint4 ret;
|
||||
//! image_1d.GetDimensions(ret.x);
|
||||
//! return ret.x;
|
||||
//! }
|
||||
//!
|
||||
//! int dim_1d = NagaDimensions1D(image_1d);
|
||||
//! ```
|
||||
/*!
|
||||
Helpers for the hlsl backend
|
||||
|
||||
Important note about `Expression::ImageQuery`/`Expression::ArrayLength` and hlsl backend:
|
||||
|
||||
Due to implementation of `GetDimensions` function in hlsl (<https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-getdimensions>)
|
||||
backend can't work with it as an expression.
|
||||
Instead, it generates a unique wrapped function per `Expression::ImageQuery`, based on texure info and query function.
|
||||
See `WrappedImageQuery` struct that represents a unique function and will be generated before writing all statements and expressions.
|
||||
This allowed to works with `Expression::ImageQuery` as expression and write wrapped function.
|
||||
|
||||
For example:
|
||||
```wgsl
|
||||
let dim_1d = textureDimensions(image_1d);
|
||||
```
|
||||
|
||||
```hlsl
|
||||
int NagaDimensions1D(Texture1D<float4>)
|
||||
{
|
||||
uint4 ret;
|
||||
image_1d.GetDimensions(ret.x);
|
||||
return ret.x;
|
||||
}
|
||||
|
||||
int dim_1d = NagaDimensions1D(image_1d);
|
||||
```
|
||||
*/
|
||||
|
||||
use super::{super::FunctionCtx, BackendResult, Error};
|
||||
use crate::{arena::Handle, proc::NameKey};
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
//! HLSL Reserved Words
|
||||
//! - <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-keywords>
|
||||
//! - <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-reserved-words>
|
||||
/*!
|
||||
HLSL Reserved Words
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-keywords>
|
||||
- <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-reserved-words>
|
||||
*/
|
||||
|
||||
pub const RESERVED: &[&str] = &[
|
||||
"AppendStructuredBuffer",
|
||||
"asm",
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
//! HLSL shading language backend
|
||||
//!
|
||||
//! # Supported shader model versions:
|
||||
//! - 5.0
|
||||
//! - 5.1
|
||||
//! - 6.0
|
||||
//!
|
||||
//! All matrix construction/deconstruction is row based in HLSL. This means that when
|
||||
//! we construct a matrix from column vectors, our matrix will be implicitly transposed.
|
||||
//! The inverse transposition happens when we call `[0]` to get the zeroth column vector.
|
||||
//!
|
||||
//! Because all of our matrices are implicitly transposed, we flip arguments to `mul`. `mat * vec`
|
||||
//! becomes `vec * mat`, etc. This acts as the inverse transpose making the results identical.
|
||||
//!
|
||||
//! The only time we don't get this implicit transposition is when reading matrices from Uniforms/Push Constants.
|
||||
//! To deal with this, we add `row_major` to all declarations of matrices in Uniforms/Push Constants.
|
||||
//!
|
||||
//! Finally because all of our matrices are transposed, if you use `mat3x4`, it'll become `float4x3` in HLSL.
|
||||
/*!
|
||||
Backend for [HLSL][hlsl] (High-Level Shading Language).
|
||||
|
||||
# Supported shader model versions:
|
||||
- 5.0
|
||||
- 5.1
|
||||
- 6.0
|
||||
|
||||
All matrix construction/deconstruction is row based in HLSL. This means that when
|
||||
we construct a matrix from column vectors, our matrix will be implicitly transposed.
|
||||
The inverse transposition happens when we call `[0]` to get the zeroth column vector.
|
||||
|
||||
Because all of our matrices are implicitly transposed, we flip arguments to `mul`. `mat * vec`
|
||||
becomes `vec * mat`, etc. This acts as the inverse transpose making the results identical.
|
||||
|
||||
The only time we don't get this implicit transposition is when reading matrices from Uniforms/Push Constants.
|
||||
To deal with this, we add `row_major` to all declarations of matrices in Uniforms/Push Constants.
|
||||
|
||||
Finally because all of our matrices are transposed, if you use `mat3x4`, it'll become `float4x3` in HLSL.
|
||||
|
||||
[hlsl]: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl
|
||||
*/
|
||||
|
||||
mod conv;
|
||||
mod help;
|
||||
@@ -92,7 +96,7 @@ pub enum EntryPointError {
|
||||
MissingBinding(crate::ResourceBinding),
|
||||
}
|
||||
|
||||
/// Structure that contains the configuration used in the [`Writer`](Writer)
|
||||
/// Configuration used in the [`Writer`].
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
@@ -135,14 +139,15 @@ impl Options {
|
||||
}
|
||||
}
|
||||
|
||||
/// Structure that contains a reflection info
|
||||
/// Reflection info for entry point names.
|
||||
#[derive(Default)]
|
||||
pub struct ReflectionInfo {
|
||||
/// Mapping of the entry point names. Each item in the array
|
||||
/// corresponds to an entry point index. The real entry point name may be different if one of the
|
||||
/// Mapping of the entry point names.
|
||||
///
|
||||
/// Each item in the array corresponds to an entry point index. The real entry point name may be different if one of the
|
||||
/// reserved words are used.
|
||||
///
|
||||
///Note: Some entry points may fail translation because of missing bindings.
|
||||
/// Note: Some entry points may fail translation because of missing bindings.
|
||||
pub entry_point_names: Vec<Result<String, EntryPointError>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
//! Logic related to `ByteAddressBuffer` operations.
|
||||
//!
|
||||
//! HLSL backend uses byte address buffers for all storage buffers in IR.
|
||||
/*!
|
||||
Logic related to `ByteAddressBuffer` operations.
|
||||
|
||||
HLSL backend uses byte address buffers for all storage buffers in IR.
|
||||
*/
|
||||
|
||||
use super::{super::FunctionCtx, BackendResult, Error};
|
||||
use crate::{
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Functions which export shader modules into binary and text formats.
|
||||
/*!
|
||||
Backend functions that export shader [`Module`](super::Module)s into binary and text formats.
|
||||
*/
|
||||
|
||||
#[cfg(feature = "dot-out")]
|
||||
pub mod dot;
|
||||
@@ -202,9 +204,9 @@ impl crate::TypeInner {
|
||||
}
|
||||
|
||||
impl crate::Statement {
|
||||
/// Returns true if the statement directly terminates the current block
|
||||
/// Returns true if the statement directly terminates the current block.
|
||||
///
|
||||
/// Used to decided wether case blocks require a explicit `break`
|
||||
/// Used to decide whether case blocks require a explicit `break`.
|
||||
pub fn is_terminator(&self) -> bool {
|
||||
match *self {
|
||||
crate::Statement::Break
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*! Metal Shading Language (MSL) backend
|
||||
/*!
|
||||
Backend for [MSL][msl] (Metal Shading Language).
|
||||
|
||||
## Binding model
|
||||
|
||||
@@ -21,7 +22,9 @@ pretend that MSL doesn't have all the restrictions it has.
|
||||
|
||||
For the result type, if it's a structure, we re-compose it with a temporary value
|
||||
holding the result.
|
||||
!*/
|
||||
|
||||
[msl]: https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
|
||||
*/
|
||||
|
||||
use crate::{arena::Handle, proc::index, valid::ModuleInfo};
|
||||
use std::{
|
||||
@@ -197,12 +200,13 @@ impl Default for Options {
|
||||
}
|
||||
}
|
||||
|
||||
// A subset of options that are meant to be changed per pipeline.
|
||||
/// A subset of options that are meant to be changed per pipeline.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
pub struct PipelineOptions {
|
||||
/// Allow `BuiltIn::PointSize` in the vertex shader.
|
||||
///
|
||||
/// Metal doesn't like this for non-point primitive topologies.
|
||||
pub allow_point_size: bool,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Implementations for `BlockContext` methods.
|
||||
/*!
|
||||
Implementations for `BlockContext` methods.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
index::BoundsCheckResult, make_local, selection::Selection, Block, BlockContext, Dimension,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Generating SPIR-V for image operations.
|
||||
/*!
|
||||
Generating SPIR-V for image operations.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
selection::{MergeTuple, Selection},
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Bounds-checking for SPIR-V output.
|
||||
/*!
|
||||
Bounds-checking for SPIR-V output.
|
||||
*/
|
||||
|
||||
use super::{selection::Selection, Block, BlockContext, Error, IdGenerator, Instruction, Word};
|
||||
use crate::{arena::Handle, proc::BoundsCheckPolicy};
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/*! Standard Portable Intermediate Representation (SPIR-V) backend
|
||||
!*/
|
||||
/*!
|
||||
Backend for [SPIR-V][spv] (Standard Portable Intermediate Representation).
|
||||
|
||||
[spv]: https://www.khronos.org/registry/SPIR-V/
|
||||
*/
|
||||
|
||||
mod block;
|
||||
mod helpers;
|
||||
@@ -627,17 +630,16 @@ impl Default for Options {
|
||||
}
|
||||
}
|
||||
|
||||
// A subset of options that are meant to be changed per pipeline.
|
||||
// A subset of options meant to be changed per pipeline.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
pub struct PipelineOptions {
|
||||
/// The stage of the entry point
|
||||
/// The stage of the entry point.
|
||||
pub shader_stage: crate::ShaderStage,
|
||||
/// The name of the entry point
|
||||
/// The name of the entry point.
|
||||
///
|
||||
/// If no entry point that matches is found a error will be thrown while creating a new instance
|
||||
/// of [`Writer`](struct.Writer.html)
|
||||
/// If no entry point that matches is found while creating a [`Writer`], a error will be thrown.
|
||||
pub entry_point: String,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Reusing collections' previous allocations.
|
||||
/*!
|
||||
Reusing collections' previous allocations.
|
||||
*/
|
||||
|
||||
/// A value that can be reset to its initial state, retaining its current allocations.
|
||||
///
|
||||
|
||||
@@ -1,59 +1,61 @@
|
||||
//! Generate SPIR-V conditional structures.
|
||||
//!
|
||||
//! Builders for `if` structures with `and`s.
|
||||
//!
|
||||
//! The types in this module track the information needed to emit SPIR-V code
|
||||
//! for complex conditional structures, like those whose conditions involve
|
||||
//! short-circuiting 'and' and 'or' structures. These track labels and can emit
|
||||
//! `OpPhi` instructions to merge values produced along different paths.
|
||||
//!
|
||||
//! This currently only supports exactly the forms Naga uses, so it doesn't
|
||||
//! support `or` or `else`, and only supports zero or one merged values.
|
||||
//!
|
||||
//! Naga needs to emit code roughly like this:
|
||||
//!
|
||||
//! ```ignore
|
||||
//!
|
||||
//! value = DEFAULT;
|
||||
//! if COND1 && COND2 {
|
||||
//! value = THEN_VALUE;
|
||||
//! }
|
||||
//! // use value
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
//! Assuming `ctx` and `block` are a mutable references to a [`BlockContext`]
|
||||
//! and the current [`Block`], and `merge_type` is the SPIR-V type for the
|
||||
//! merged value `value`, we can build SPIR-V for the code above like so:
|
||||
//!
|
||||
//! ```ignore
|
||||
//!
|
||||
//! let cond = Selection::start(block, merge_type);
|
||||
//! // ... compute `cond1` ...
|
||||
//! cond.if_true(ctx, cond1, DEFAULT);
|
||||
//! // ... compute `cond2` ...
|
||||
//! cond.if_true(ctx, cond2, DEFAULT);
|
||||
//! // ... compute THEN_VALUE
|
||||
//! let merged_value = cond.finish(ctx, THEN_VALUE);
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
//! After this, `merged_value` is either `DEFAULT` or `THEN_VALUE`, depending on
|
||||
//! the path by which the merged block was reached.
|
||||
//!
|
||||
//! This takes care of writing all branch instructions, including an
|
||||
//! `OpSelectionMerge` annotation in the header block; starting new blocks and
|
||||
//! assigning them labels; and emitting the `OpPhi` that gathers together the
|
||||
//! right sources for the merged values, for every path through the selection
|
||||
//! construct.
|
||||
//!
|
||||
//! When there is no merged value to produce, you can pass `()` for `merge_type`
|
||||
//! and the merge values. In this case no `OpPhi` instructions are produced, and
|
||||
//! the `finish` method returns `()`.
|
||||
//!
|
||||
//! To enforce proper nesting, a `Selection` takes ownership of the `&mut Block`
|
||||
//! pointer for the duration of its lifetime. To obtain the block for generating
|
||||
//! code in the selection's body, call the `Selection::block` method.
|
||||
/*!
|
||||
Generate SPIR-V conditional structures.
|
||||
|
||||
Builders for `if` structures with `and`s.
|
||||
|
||||
The types in this module track the information needed to emit SPIR-V code
|
||||
for complex conditional structures, like those whose conditions involve
|
||||
short-circuiting 'and' and 'or' structures. These track labels and can emit
|
||||
`OpPhi` instructions to merge values produced along different paths.
|
||||
|
||||
This currently only supports exactly the forms Naga uses, so it doesn't
|
||||
support `or` or `else`, and only supports zero or one merged values.
|
||||
|
||||
Naga needs to emit code roughly like this:
|
||||
|
||||
```ignore
|
||||
|
||||
value = DEFAULT;
|
||||
if COND1 && COND2 {
|
||||
value = THEN_VALUE;
|
||||
}
|
||||
// use value
|
||||
|
||||
```
|
||||
|
||||
Assuming `ctx` and `block` are a mutable references to a [`BlockContext`]
|
||||
and the current [`Block`], and `merge_type` is the SPIR-V type for the
|
||||
merged value `value`, we can build SPIR-V for the code above like so:
|
||||
|
||||
```ignore
|
||||
|
||||
let cond = Selection::start(block, merge_type);
|
||||
// ... compute `cond1` ...
|
||||
cond.if_true(ctx, cond1, DEFAULT);
|
||||
// ... compute `cond2` ...
|
||||
cond.if_true(ctx, cond2, DEFAULT);
|
||||
// ... compute THEN_VALUE
|
||||
let merged_value = cond.finish(ctx, THEN_VALUE);
|
||||
|
||||
```
|
||||
|
||||
After this, `merged_value` is either `DEFAULT` or `THEN_VALUE`, depending on
|
||||
the path by which the merged block was reached.
|
||||
|
||||
This takes care of writing all branch instructions, including an
|
||||
`OpSelectionMerge` annotation in the header block; starting new blocks and
|
||||
assigning them labels; and emitting the `OpPhi` that gathers together the
|
||||
right sources for the merged values, for every path through the selection
|
||||
construct.
|
||||
|
||||
When there is no merged value to produce, you can pass `()` for `merge_type`
|
||||
and the merge values. In this case no `OpPhi` instructions are produced, and
|
||||
the `finish` method returns `()`.
|
||||
|
||||
To enforce proper nesting, a `Selection` takes ownership of the `&mut Block`
|
||||
pointer for the duration of its lifetime. To obtain the block for generating
|
||||
code in the selection's body, call the `Selection::block` method.
|
||||
*/
|
||||
|
||||
use super::{Block, BlockContext, Instruction};
|
||||
use spirv::Word;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*!
|
||||
Backend for [WGSL][wgsl] (WebGPU Shading Language).
|
||||
|
||||
[wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html
|
||||
*/
|
||||
|
||||
mod writer;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -23,8 +23,8 @@ pub struct GlobalLookup {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ParameterInfo {
|
||||
pub qualifier: ParameterQualifier,
|
||||
/// Wether the parameter should be treated as a depth image instead of a
|
||||
/// sampled image
|
||||
/// Whether the parameter should be treated as a depth image instead of a
|
||||
/// sampled image.
|
||||
pub depth: bool,
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ pub struct Overload {
|
||||
#[derive(Debug, Default)]
|
||||
pub struct FunctionDeclaration {
|
||||
pub overloads: Vec<Overload>,
|
||||
/// Wether or not this function has the name of a builtin
|
||||
/// Whether or not this function has the name of a builtin.
|
||||
pub builtin: bool,
|
||||
/// In case [`builtin`](Self::builtin) is true, this field indicates wether
|
||||
/// this function already has double overloads added or not, otherwise is unused
|
||||
/// If [`builtin`](Self::builtin) is true, this field indicates whether
|
||||
/// this function already has double overloads added or not. Otherwise, it is unused.
|
||||
pub double: bool,
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ pub enum StructLayout {
|
||||
}
|
||||
|
||||
// TODO: Encode precision hints in the IR
|
||||
/// A precision hint used in glsl declarations
|
||||
/// A precision hint used in GLSL declarations.
|
||||
///
|
||||
/// Precision hints can be used to either speed up shader execution or control
|
||||
/// the precision of arithmetic operations.
|
||||
@@ -229,7 +229,7 @@ impl ParameterQualifier {
|
||||
}
|
||||
}
|
||||
|
||||
/// The glsl profile used by a shader
|
||||
/// The GLSL profile used by a shader.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Profile {
|
||||
/// The `core` profile, default when no profile is specified.
|
||||
|
||||
@@ -17,22 +17,22 @@ fn join_with_comma(list: &[ExpectedToken]) -> String {
|
||||
string
|
||||
}
|
||||
|
||||
/// One of the expected tokens returned in [`InvalidToken`](ErrorKind::InvalidToken)
|
||||
/// One of the expected tokens returned in [`InvalidToken`](ErrorKind::InvalidToken).
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ExpectedToken {
|
||||
/// A specific token was expected
|
||||
/// A specific token was expected.
|
||||
Token(TokenValue),
|
||||
/// A type was expected
|
||||
/// A type was expected.
|
||||
TypeName,
|
||||
/// An identifier was expected
|
||||
/// An identifier was expected.
|
||||
Identifier,
|
||||
/// An integer literal was expected
|
||||
/// An integer literal was expected.
|
||||
IntLiteral,
|
||||
/// A float literal was expected
|
||||
/// A float literal was expected.
|
||||
FloatLiteral,
|
||||
/// A boolean literal was expected
|
||||
/// A boolean literal was expected.
|
||||
BoolLiteral,
|
||||
/// The end of file was expected
|
||||
/// The end of file was expected.
|
||||
Eof,
|
||||
}
|
||||
impl From<TokenValue> for ExpectedToken {
|
||||
@@ -54,7 +54,7 @@ impl std::fmt::Display for ExpectedToken {
|
||||
}
|
||||
}
|
||||
|
||||
/// Information about the cause of an error
|
||||
/// Information about the cause of an error.
|
||||
#[derive(Debug, Error)]
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
pub enum ErrorKind {
|
||||
@@ -112,7 +112,7 @@ impl From<ConstantSolvingError> for ErrorKind {
|
||||
}
|
||||
}
|
||||
|
||||
/// Error returned during shader parsing
|
||||
/// Error returned during shader parsing.
|
||||
#[derive(Debug, Error)]
|
||||
#[error("{kind}")]
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
//! Front end for consuming the OpenGl Shading language (GLSL).
|
||||
//!
|
||||
//! To begin take a look at the documentation for the [`Parser`](Parser).
|
||||
//!
|
||||
//! # Supported versions
|
||||
//! Currently only the versions 450 and 460 are supported and 440 is partially
|
||||
//! supported, furthermore the vulkan flavor is assumed.
|
||||
/*!
|
||||
Frontend for [GLSL][glsl] (OpenGL Shading Language).
|
||||
|
||||
To begin, take a look at the documentation for the [`Parser`](Parser).
|
||||
|
||||
# Supported versions
|
||||
## Vulkan
|
||||
- 440 (partial)
|
||||
- 450
|
||||
- 460
|
||||
|
||||
[glsl]: https://www.khronos.org/registry/OpenGL/index_gl.php
|
||||
*/
|
||||
|
||||
pub use ast::{Precision, Profile};
|
||||
pub use error::{Error, ErrorKind, ExpectedToken};
|
||||
@@ -31,7 +37,7 @@ mod variables;
|
||||
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// Per shader options passed to [`parse`](Parser::parse)
|
||||
/// Per-shader options passed to [`parse`](Parser::parse).
|
||||
///
|
||||
/// The [`From`](From) trait is implemented for [`ShaderStage`](ShaderStage) to
|
||||
/// provide a quick way to create a Options instance.
|
||||
@@ -61,16 +67,16 @@ impl From<ShaderStage> for Options {
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional information about the glsl shader
|
||||
/// Additional information about the GLSL shader.
|
||||
///
|
||||
/// Stores additional information about the glsl shader which might not be
|
||||
/// Stores additional information about the GLSL shader which might not be
|
||||
/// stored in the shader [`Module`](Module).
|
||||
#[derive(Debug)]
|
||||
pub struct ShaderMetadata {
|
||||
/// The glsl version specified in the shader trought the use of the
|
||||
/// The GLSL version specified in the shader trought the use of the
|
||||
/// `#version` preprocessor directive.
|
||||
pub version: u16,
|
||||
/// The glsl profile specified in the shader trought the use of the
|
||||
/// The GLSL profile specified in the shader trought the use of the
|
||||
/// `#version` preprocessor directive.
|
||||
pub profile: Profile,
|
||||
/// The shader stage in the pipeline, passed to the [`parse`](Parser::parse)
|
||||
@@ -80,8 +86,8 @@ pub struct ShaderMetadata {
|
||||
/// The workgroup size for compute shaders, defaults to `[1; 3]` for
|
||||
/// compute shaders and `[0; 3]` for non compute shaders.
|
||||
pub workgroup_size: [u32; 3],
|
||||
/// Wether or not early fragment tests where requested by the shader,
|
||||
/// defaults to `false`.
|
||||
/// Whether or not early fragment tests where requested by the shader.
|
||||
/// Defaults to `false`.
|
||||
pub early_fragment_tests: bool,
|
||||
|
||||
/// The shader can request extensions via the
|
||||
@@ -118,7 +124,7 @@ impl Default for ShaderMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
/// The `Parser` is the central structure of the glsl frontend.
|
||||
/// The `Parser` is the central structure of the GLSL frontend.
|
||||
///
|
||||
/// To instantiate a new `Parser` the [`Default`](Default) trait is used, so a
|
||||
/// call to the associated function [`Parser::default`](Parser::default) will
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
//! Module responsible for calculating the offset and span for types.
|
||||
//!
|
||||
//! There exists two types of layouts std140 and std430 (there's technically
|
||||
//! two more layouts, shared and packed. Shared is not supported by spirv. Packed is
|
||||
//! implementation dependent and for now it's just implemented as an alias to
|
||||
//! std140).
|
||||
//!
|
||||
//! The OpenGl spec (the layout rules are defined by the OpenGl spec in section
|
||||
//! 7.6.2.2 as opposed to the GLSL spec) uses the term basic machine units which are
|
||||
//! equivalent to bytes.
|
||||
/*!
|
||||
Module responsible for calculating the offset and span for types.
|
||||
|
||||
There exists two types of layouts std140 and std430 (there's technically
|
||||
two more layouts, shared and packed. Shared is not supported by spirv. Packed is
|
||||
implementation dependent and for now it's just implemented as an alias to
|
||||
std140).
|
||||
|
||||
The OpenGl spec (the layout rules are defined by the OpenGl spec in section
|
||||
7.6.2.2 as opposed to the GLSL spec) uses the term basic machine units which are
|
||||
equivalent to bytes.
|
||||
*/
|
||||
|
||||
use super::{
|
||||
ast::StructLayout,
|
||||
error::{Error, ErrorKind},
|
||||
|
||||
@@ -16,7 +16,7 @@ pub struct Token {
|
||||
pub meta: Span,
|
||||
}
|
||||
|
||||
/// A token passed from the lexing used in the parsing
|
||||
/// A token passed from the lexing used in the parsing.
|
||||
///
|
||||
/// This type is exported since it's returned in the
|
||||
/// [`InvalidToken`](super::ErrorKind::InvalidToken) error.
|
||||
|
||||
@@ -31,15 +31,15 @@ pub struct VarDeclaration<'a> {
|
||||
pub meta: Span,
|
||||
}
|
||||
|
||||
/// Information about a builtin used in [`add_builtin`](Parser::add_builtin)
|
||||
/// Information about a builtin used in [`add_builtin`](Parser::add_builtin).
|
||||
struct BuiltInData {
|
||||
/// The type of the builtin
|
||||
/// The type of the builtin.
|
||||
inner: TypeInner,
|
||||
/// The builtin class associated with
|
||||
/// The associated builtin class.
|
||||
builtin: BuiltIn,
|
||||
/// Wether it should be allowed to write to the builtin or not
|
||||
/// Whether the builtin can be written to or not.
|
||||
mutable: bool,
|
||||
/// The storage used for the builtin
|
||||
/// The storage used for the builtin.
|
||||
storage: StorageQualifier,
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Interpolation defaults.
|
||||
/*!
|
||||
Interpolation defaults.
|
||||
*/
|
||||
|
||||
impl crate::Binding {
|
||||
/// Apply the usual default interpolation for `ty` to `binding`.
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Parsers which load shaders into memory.
|
||||
/*!
|
||||
Frontend parsers that consume binary and text shaders and load them into [`Module`](super::Module)s.
|
||||
*/
|
||||
|
||||
mod interpolator;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*! SPIR-V frontend
|
||||
/*!
|
||||
Frontend for [SPIR-V][spv] (Standard Portable Intermediate Representation).
|
||||
|
||||
## ID lookups
|
||||
|
||||
@@ -23,7 +24,9 @@ Instead, we detect when such matrix is accessed in the `OpAccessChain`,
|
||||
and we generate a parallel expression that loads the value, but transposed.
|
||||
This value then gets used instead of `OpLoad` result later on.
|
||||
|
||||
!*/
|
||||
[spv]: https://www.khronos.org/registry/SPIR-V/
|
||||
*/
|
||||
|
||||
mod convert;
|
||||
mod error;
|
||||
mod function;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
//! Front end for consuming [WebGPU Shading Language][wgsl].
|
||||
//!
|
||||
//! [wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html
|
||||
/*!
|
||||
Frontend for [WGSL][wgsl] (WebGPU Shading Language).
|
||||
|
||||
[wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html
|
||||
*/
|
||||
|
||||
mod conv;
|
||||
mod lexer;
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
/*!
|
||||
Lists of reserved keywords for each shading language with a [frontend][crate::front] or [backend][crate::back].
|
||||
*/
|
||||
|
||||
#[cfg(any(feature = "wgsl-in", feature = "wgsl-out"))]
|
||||
pub mod wgsl;
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
/*!
|
||||
Reserved keywords for [WGSL][wgsl] (WebGPU Shading Language).
|
||||
|
||||
[wgsl]: https://gpuweb.github.io/gpuweb/wgsl.html
|
||||
*/
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#keyword-summary
|
||||
/// Reserved keywords.
|
||||
pub const RESERVED: &[&str] = &[
|
||||
// type-defining keywords
|
||||
"array",
|
||||
|
||||
37
src/lib.rs
37
src/lib.rs
@@ -182,8 +182,7 @@ tree.
|
||||
|
||||
[`Validator::validate`]: valid::Validator::validate
|
||||
[`ModuleInfo`]: valid::ModuleInfo
|
||||
|
||||
!*/
|
||||
*/
|
||||
|
||||
// TODO: use `strip_prefix` instead when Rust 1.45 <= MSRV
|
||||
#![allow(
|
||||
@@ -235,18 +234,23 @@ pub type FastHashSet<K> = rustc_hash::FxHashSet<K>;
|
||||
/// Map of expressions that have associated variable names
|
||||
pub(crate) type NamedExpressions = FastHashMap<Handle<Expression>, String>;
|
||||
|
||||
/// Early fragment tests. In a standard situation if a driver determines that it is possible to
|
||||
/// switch on early depth test it will. Typical situations when early depth test is switched off:
|
||||
/// - Calling ```discard``` in a shader.
|
||||
/// Early fragment tests.
|
||||
///
|
||||
/// In a standard situation, if a driver determines that it is possible to switch on early depth test, it will.
|
||||
///
|
||||
/// Typical situations when early depth test is switched off:
|
||||
/// - Calling `discard` in a shader.
|
||||
/// - Writing to the depth buffer, unless ConservativeDepth is enabled.
|
||||
///
|
||||
/// SPIR-V: ExecutionMode EarlyFragmentTests
|
||||
/// In GLSL: layout(early_fragment_tests) in;
|
||||
/// HLSL: Attribute earlydepthstencil
|
||||
/// To use in a shader:
|
||||
/// - GLSL: `layout(early_fragment_tests) in;`
|
||||
/// - HLSL: `Attribute earlydepthstencil`
|
||||
/// - SPIR-V: `ExecutionMode EarlyFragmentTests`
|
||||
///
|
||||
/// For more, see:
|
||||
/// - <https://www.khronos.org/opengl/wiki/Early_Fragment_Test#Explicit_specification>
|
||||
/// - <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-attributes-earlydepthstencil>
|
||||
/// - <https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Execution_Mode>
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
@@ -256,20 +260,22 @@ pub struct EarlyDepthTest {
|
||||
}
|
||||
/// Enables adjusting depth without disabling early Z.
|
||||
///
|
||||
/// SPIR-V: ExecutionMode DepthGreater/DepthLess/DepthUnchanged
|
||||
/// GLSL: layout (depth_<greater/less/unchanged/any>) out float gl_FragDepth;
|
||||
/// - ```depth_any``` option behaves as if the layout qualifier was not present.
|
||||
/// HLSL: SV_Depth/SV_DepthGreaterEqual/SV_DepthLessEqual
|
||||
/// To use in a shader:
|
||||
/// - GLSL: `layout (depth_<greater/less/unchanged/any>) out float gl_FragDepth;`
|
||||
/// - `depth_any` option behaves as if the layout qualifier was not present.
|
||||
/// - HLSL: `SV_DepthGreaterEqual`/`SV_DepthLessEqual`/`SV_Depth`
|
||||
/// - SPIR-V: `ExecutionMode Depth<Greater/Less/Unchanged>`
|
||||
///
|
||||
/// For more, see:
|
||||
/// - <https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_conservative_depth.txt>
|
||||
/// - <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#system-value-semantics>
|
||||
/// - <https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#Execution_Mode>
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
pub enum ConservativeDepth {
|
||||
/// Shader may rewrite depth only with a value greater than calculated;
|
||||
/// Shader may rewrite depth only with a value greater than calculated.
|
||||
GreaterEqual,
|
||||
|
||||
/// Shader may rewrite depth smaller than one that would have been written without the modification.
|
||||
@@ -474,7 +480,7 @@ bitflags::bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
// Storage image format.
|
||||
/// Image storage format.
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
@@ -1333,7 +1339,7 @@ pub enum Expression {
|
||||
|
||||
pub use block::Block;
|
||||
|
||||
/// The value of the switch case
|
||||
/// The value of the switch case.
|
||||
// Clone is used only for error reporting and is not intended for end users
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
@@ -1521,6 +1527,7 @@ pub struct FunctionArgument {
|
||||
pub binding: Option<Binding>,
|
||||
}
|
||||
|
||||
/// A function result.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Definitions for index bounds checking.
|
||||
/*!
|
||||
Definitions for index bounds checking.
|
||||
*/
|
||||
|
||||
use crate::{valid, Handle, UniqueArena};
|
||||
use bit_set::BitSet;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Module processing functionality.
|
||||
/*!
|
||||
[`Module`](super::Module) processing functionality.
|
||||
*/
|
||||
|
||||
pub mod index;
|
||||
mod layouter;
|
||||
|
||||
@@ -55,7 +55,7 @@ impl Span {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check wether `self` was defined or is a default/unknown span
|
||||
/// Check whether `self` was defined or is a default/unknown span
|
||||
pub fn is_defined(&self) -> bool {
|
||||
*self != Self::default()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/*!
|
||||
Shader validator.
|
||||
*/
|
||||
|
||||
mod analyzer;
|
||||
mod compose;
|
||||
mod expression;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Test SPIR-V backend capability checks.
|
||||
/*!
|
||||
Test SPIR-V backend capability checks.
|
||||
*/
|
||||
|
||||
#![cfg(all(feature = "wgsl-in", feature = "spv-out"))]
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Tests for the WGSL front end.
|
||||
/*!
|
||||
Tests for the WGSL front end.
|
||||
*/
|
||||
#![cfg(feature = "wgsl-in")]
|
||||
|
||||
fn check(input: &str, snapshot: &str) {
|
||||
|
||||
Reference in New Issue
Block a user