// Copyright 2021 The Tint Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //////////////////////////////////////////////////////////////////////////////// // WGSL builtin definition file // // // // This file is used to generate parts of the Tint BuiltinTable, various // // enum definition files, as well as test .wgsl files. // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Enumerators // //////////////////////////////////////////////////////////////////////////////// // https://gpuweb.github.io/gpuweb/wgsl/#storage-class enum storage_class { function private workgroup uniform storage @internal handle } // https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode enum access { read write read_write } // https://gpuweb.github.io/gpuweb/wgsl/#texel-formats enum texel_format { rgba8unorm rgba8snorm rgba8uint rgba8sint rgba16uint rgba16sint rgba16float r32uint r32sint r32float rg32uint rg32sint rg32float rgba32uint rgba32sint rgba32float } //////////////////////////////////////////////////////////////////////////////// // WGSL primitive types // // Types may be decorated with @precedence(N) to prioritize which type // // will be picked when multiple types of a matcher match. // // This is used to ensure that abstract numerical types materialize to the // // concrete type with the lowest conversion rank. // // Types with higher the precedence values will be matched first. // //////////////////////////////////////////////////////////////////////////////// // https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section type bool @precedence(5) @display("abstract-float") type fa @precedence(4) @display("abstract-int") type ia @precedence(3) type i32 @precedence(2) type u32 @precedence(1) type f32 @precedence(0) type f16 type vec2 type vec3 type vec4 type mat2x2 type mat2x3 type mat2x4 type mat3x2 type mat3x3 type mat3x4 type mat4x2 type mat4x3 type mat4x4 @display("vec{N}<{T}>") type vec @display("mat{N}x{M}<{T}>") type mat type ptr type atomic type array type sampler type sampler_comparison type texture_1d type texture_2d type texture_2d_array type texture_3d type texture_cube type texture_cube_array type texture_multisampled_2d type texture_depth_2d type texture_depth_2d_array type texture_depth_cube type texture_depth_cube_array type texture_depth_multisampled_2d type texture_storage_1d type texture_storage_2d type texture_storage_2d_array type texture_storage_3d type texture_external type __modf_result @display("__modf_result_vec{N}") type __modf_result_vec type __frexp_result @display("__frexp_result_vec{N}") type __frexp_result_vec type __atomic_compare_exchange_result //////////////////////////////////////////////////////////////////////////////// // Type matchers // // // // A type matcher that can match one or more types. // //////////////////////////////////////////////////////////////////////////////// match abstract_or_scalar: ia | fa | f32 | f16 | i32 | u32 | bool match scalar: f32 | f16 | i32 | u32 | bool match scalar_no_f32: i32 | f16 | u32 | bool match scalar_no_f16: f32 | i32 | u32 | bool match scalar_no_i32: f32 | f16 | u32 | bool match scalar_no_u32: f32 | f16 | i32 | bool match scalar_no_bool: f32 | f16 | i32 | u32 match fia_fi32_f16: fa | ia | f32 | i32 | f16 match fa_f32_f16: fa | f32 | f16 match ia_iu32: ia | i32 | u32 match fiu32_f16: f32 | i32 | u32 | f16 match fiu32: f32 | i32 | u32 match fi32_f16: f32 | i32 | f16 match fi32: f32 | i32 match f32_f16: f32 | f16 match iu32: i32 | u32 //////////////////////////////////////////////////////////////////////////////// // Enum matchers // // // // A number matcher that can match one or more enumerator values. // // All enumerator values listed in the match declaration need to be from the // // same enum. // //////////////////////////////////////////////////////////////////////////////// // https://gpuweb.github.io/gpuweb/wgsl/#texel-formats match f32_texel_format: rgba8unorm | rgba8snorm | rgba16float | r32float | rg32float | rgba32float match i32_texel_format: rgba8sint | rgba16sint | r32sint | rg32sint | rgba32sint match u32_texel_format: rgba8uint | rgba16uint | r32uint | rg32uint | rgba32uint match write_only: write match function_private_workgroup: function | private | workgroup match workgroup_or_storage: workgroup | storage //////////////////////////////////////////////////////////////////////////////// // Builtin Functions // // // // The builtin function declarations below declare all the built-in // // functions supported by the WGSL language. This builtin definition // // language supports simple static-type function declarations, as well as // // single overload declarations that can match a number of different // // argument types via the use of template types and template numbers // // // // * Basic example: // // // // fn isInf(f32) -> bool // // // // Declares an overload of the function 'isInf' that accepts a single // // parameter of type 'f32' and returns a 'bool'. // // // // A template type is a type determined by the arguments to the builtin. // // // // * Template type example without constraint: // // // // fn arrayLength(array) -> u32 // // // // Declares an overload of the function 'arrayLength' that accepts a // // single argument of an array type with no constraints on the array // // element type. This overload will always return a value of the same type // // as its single argument. // // // // * Template type example with constraint: // // // // fn abs(T) -> T // // // // Declares an overload of the function 'abs' that accepts a single // // argument of type 'f32', 'i32' or 'u32', which returns a value of the // // same argument type. // // // // Similarly a template number is a number or enumerator that is determined // // by the arguments to the builtin. // // // // * Template number example: // // // // fn dpdx(vec) -> vec // // // // Declares an overload of the function 'dpdx' that accepts a single // // argument of a variable-sized vector of 'f32', which returns a value of // // the same argument type. // // // // // // Matching algorithm for a single overload: // // ----------------------------------------- // // // // The goal of matching is to compare a function call's arguments and any // // explicitly provided template types in the program source against an // // overload declaration in this file, and determine if the call satisfies // // the form and type constraints of the overload. If the call matches an // // overload, then the overload is added to the list of 'overload candidates' // // used for overload resolution (described below). // // // // Prior to matching an overload, all template types are undefined. // // // // Template types are first defined with the type of the leftmost argument // // that matches against that template type name. Subsequent arguments that // // attempt to match against the template type name will either reject the // // overload or refine the template, in one of 3 ways: // // (a) Fail to match, causing the overload to be immediately rejected. // // (b) Match the existing template type, either exactly or via implicit // // conversion, and overload resolution continues. // // (c) Match via implicit conversion of the currently defined template type // // to the argument type. In this situation, the template type is refined // // with the more constrained argument type, and overload resolution // // continues. // // // // To better understand, let's consider the following hypothetical overload // // declaration: // // // // fn foo(T, T); // // // // T - is the template type name // // scalar - is a matcher for the types 'f32', 'i32', 'u32' or 'bool' // // (declared above) // // - declares the template type T, with the constraint that T // // must match one of 'f32', 'i32', 'u32' or 'bool'. // // // // The process for resolving this overload is as follows: // // // // (1) The overload resolver begins by attempting to match the argument // // types from left to right. // // The first parameter type is compared against the argument type T. // // As the template type T has not been defined yet, T is defined as the // // type of the first argument. // // There's no verification that the T type is a scalar at this stage. // // (2) The second parameter is then compared against the second argument. // // As the template type T is now defined the argument type is compared // // against the value of the defined type of T. Depending on the // // comparison of the argument type to the template type, either the // // actions of (a), (b) or (c) from above will occur. // // (3) If all the parameters matched, constraints on the template types // // need to be checked next. If the defined type does not match the // // 'match' constraint, then the overload is no longer considered. // // // // This algorithm for matching a single overload is less general than the // // algorithm described in the WGSL spec. But it makes the same decisions // // because the overloads defined by WGSL are monotonic in the sense that once // // a template parameter has been refined, there is never a need to backtrack // // and un-refine it to match a later argument. // // // // The algorithm for matching template numbers is similar to matching // // template types, except numbers need to exactly match across all uses - // // there is no implicit conversion. Template numbers may match integer // // numbers or enumerators. // // // // // // Overload resolution for candidate overloads // // ------------------------------------------- // // // // If multiple candidate overloads match a given set of arguments, then a // // final overload resolution pass needs to be performed. The arguments and // // overload parameter types for each candidate overload are compared, // // following the algorithm described at: // // https://www.w3.org/TR/WGSL/#overload-resolution-section // // // // If the candidate list contains a single entry, then that single candidate // // is picked, and no overload resolution needs to be performed. // // // // If the candidate list is empty, then the call fails to resolve and an // // error diagnostic is raised. // // // // // // More examples // // ------------- // // // // fn F() // // - Function called F. // // No template types or numbers, no parameters, no return value // // // // fn F() -> RETURN_TYPE // // - Function with RETURN_TYPE as the return type value // // // // fn F(f32, i32) // // - Two fixed-type, anonymous parameters // // // // fn F(USAGE : f32) // // - Single parameter with name USAGE. // // Note: Parameter names are used by Tint to infer parameter order for // // some builtin functions // // // // fn F(T) // // - Single parameter of unconstrained template type T (any type) // // // // fn F(T) // // - Single parameter of constrained template type T (must be a scalar) // // // // fn F(T) -> T // // - Single parameter of constrained template type T (must be a one of // // fiu32) Return type matches parameter type // // // // fn F(vec) // // - Single parameter of vector type with template number size N and // // element template type T // // // // fn F(texture_storage_1d) // // - Single parameter of texture_storage_1d type with template number // // access-control C, and of a texel format that is listed in // // f32_texel_format // // // //////////////////////////////////////////////////////////////////////////////// // https://gpuweb.github.io/gpuweb/wgsl/#builtin-functions fn abs(T) -> T fn abs(vec) -> vec fn acos(f32) -> f32 fn acos(vec) -> vec fn acosh(f32) -> f32 fn acosh(vec) -> vec fn all(bool) -> bool fn all(vec) -> bool fn any(bool) -> bool fn any(vec) -> bool fn arrayLength(ptr, A>) -> u32 fn asin(f32) -> f32 fn asin(vec) -> vec fn asinh(f32) -> f32 fn asinh(vec) -> vec fn atan(f32) -> f32 fn atan(vec) -> vec fn atan2(f32, f32) -> f32 fn atan2(vec, vec) -> vec fn atanh(f32) -> f32 fn atanh(vec) -> vec fn ceil(f32) -> f32 fn ceil(vec) -> vec fn clamp(T, T, T) -> T fn clamp(vec, vec, vec) -> vec fn cos(f32) -> f32 fn cos(vec) -> vec fn cosh(f32) -> f32 fn cosh(vec) -> vec fn countLeadingZeros(T) -> T fn countLeadingZeros(vec) -> vec fn countOneBits(T) -> T fn countOneBits(vec) -> vec fn countTrailingZeros(T) -> T fn countTrailingZeros(vec) -> vec fn cross(vec3, vec3) -> vec3 fn degrees(f32) -> f32 fn degrees(vec) -> vec fn determinant(mat) -> f32 fn distance(f32, f32) -> f32 fn distance(vec, vec) -> f32 fn dot(vec, vec) -> T fn dot4I8Packed(u32, u32) -> i32 fn dot4U8Packed(u32, u32) -> u32 @stage("fragment") fn dpdx(f32) -> f32 @stage("fragment") fn dpdx(vec) -> vec @stage("fragment") fn dpdxCoarse(f32) -> f32 @stage("fragment") fn dpdxCoarse(vec) -> vec @stage("fragment") fn dpdxFine(f32) -> f32 @stage("fragment") fn dpdxFine(vec) -> vec @stage("fragment") fn dpdy(f32) -> f32 @stage("fragment") fn dpdy(vec) -> vec @stage("fragment") fn dpdyCoarse(f32) -> f32 @stage("fragment") fn dpdyCoarse(vec) -> vec @stage("fragment") fn dpdyFine(f32) -> f32 @stage("fragment") fn dpdyFine(vec) -> vec fn exp(f32) -> f32 fn exp(vec) -> vec fn exp2(f32) -> f32 fn exp2(vec) -> vec fn extractBits(T, u32, u32) -> T fn extractBits(vec, u32, u32) -> vec fn faceForward(vec, vec, vec) -> vec fn firstLeadingBit(T) -> T fn firstLeadingBit(vec) -> vec fn firstTrailingBit(T) -> T fn firstTrailingBit(vec) -> vec fn floor(f32) -> f32 fn floor(vec) -> vec fn fma(f32, f32, f32) -> f32 fn fma(vec, vec, vec) -> vec fn fract(f32) -> f32 fn fract(vec) -> vec fn frexp(f32) -> __frexp_result fn frexp(vec) -> __frexp_result_vec @stage("fragment") fn fwidth(f32) -> f32 @stage("fragment") fn fwidth(vec) -> vec @stage("fragment") fn fwidthCoarse(f32) -> f32 @stage("fragment") fn fwidthCoarse(vec) -> vec @stage("fragment") fn fwidthFine(f32) -> f32 @stage("fragment") fn fwidthFine(vec) -> vec fn insertBits(T, T, u32, u32) -> T fn insertBits(vec, vec, u32, u32) -> vec fn inverseSqrt(f32) -> f32 fn inverseSqrt(vec) -> vec fn ldexp(f32, i32) -> f32 fn ldexp(vec, vec) -> vec fn length(f32) -> f32 fn length(vec) -> f32 fn log(f32) -> f32 fn log(vec) -> vec fn log2(f32) -> f32 fn log2(vec) -> vec fn max(T, T) -> T fn max(vec, vec) -> vec fn min(T, T) -> T fn min(vec, vec) -> vec fn mix(f32, f32, f32) -> f32 fn mix(vec, vec, vec) -> vec fn mix(vec, vec, f32) -> vec fn modf(f32) -> __modf_result fn modf(vec) -> __modf_result_vec fn normalize(vec) -> vec fn pack2x16float(vec2) -> u32 fn pack2x16snorm(vec2) -> u32 fn pack2x16unorm(vec2) -> u32 fn pack4x8snorm(vec4) -> u32 fn pack4x8unorm(vec4) -> u32 fn pow(f32, f32) -> f32 fn pow(vec, vec) -> vec fn radians(f32) -> f32 fn radians(vec) -> vec fn reflect(vec, vec) -> vec fn refract(vec, vec, f32) -> vec fn reverseBits(T) -> T fn reverseBits(vec) -> vec fn round(f32) -> f32 fn round(vec) -> vec fn select(T, T, bool) -> T fn select(vec, vec, bool) -> vec fn select(vec, vec, vec) -> vec fn sign(f32) -> f32 fn sign(vec) -> vec fn sin(f32) -> f32 fn sin(vec) -> vec fn sinh(f32) -> f32 fn sinh(vec) -> vec fn smoothstep(f32, f32, f32) -> f32 fn smoothstep(vec, vec, vec) -> vec fn sqrt(f32) -> f32 fn sqrt(vec) -> vec fn step(f32, f32) -> f32 fn step(vec, vec) -> vec @stage("compute") fn storageBarrier() fn tan(f32) -> f32 fn tan(vec) -> vec fn tanh(f32) -> f32 fn tanh(vec) -> vec fn transpose(mat) -> mat fn trunc(f32) -> f32 fn trunc(vec) -> vec fn unpack2x16float(u32) -> vec2 fn unpack2x16snorm(u32) -> vec2 fn unpack2x16unorm(u32) -> vec2 fn unpack4x8snorm(u32) -> vec4 fn unpack4x8unorm(u32) -> vec4 @stage("compute") fn workgroupBarrier() fn textureDimensions(texture: texture_1d) -> i32 fn textureDimensions(texture: texture_1d, level: i32) -> i32 fn textureDimensions(texture: texture_2d) -> vec2 fn textureDimensions(texture: texture_2d, level: i32) -> vec2 fn textureDimensions(texture: texture_2d_array) -> vec2 fn textureDimensions(texture: texture_2d_array, level: i32) -> vec2 fn textureDimensions(texture: texture_3d) -> vec3 fn textureDimensions(texture: texture_3d, level: i32) -> vec3 fn textureDimensions(texture: texture_cube) -> vec2 fn textureDimensions(texture: texture_cube, level: i32) -> vec2 fn textureDimensions(texture: texture_cube_array) -> vec2 fn textureDimensions(texture: texture_cube_array, level: i32) -> vec2 fn textureDimensions(texture: texture_multisampled_2d) -> vec2 fn textureDimensions(texture: texture_depth_2d) -> vec2 fn textureDimensions(texture: texture_depth_2d, level: i32) -> vec2 fn textureDimensions(texture: texture_depth_2d_array) -> vec2 fn textureDimensions(texture: texture_depth_2d_array, level: i32) -> vec2 fn textureDimensions(texture: texture_depth_cube) -> vec2 fn textureDimensions(texture: texture_depth_cube, level: i32) -> vec2 fn textureDimensions(texture: texture_depth_cube_array) -> vec2 fn textureDimensions(texture: texture_depth_cube_array, level: i32) -> vec2 fn textureDimensions(texture: texture_depth_multisampled_2d) -> vec2 fn textureDimensions(texture: texture_storage_1d) -> i32 fn textureDimensions(texture: texture_storage_2d) -> vec2 fn textureDimensions(texture: texture_storage_2d_array) -> vec2 fn textureDimensions(texture: texture_storage_3d) -> vec3 fn textureDimensions(texture: texture_external) -> vec2 fn textureGather(@const component: i32, texture: texture_2d, sampler: sampler, coords: vec2) -> vec4 fn textureGather(@const component: i32, texture: texture_2d, sampler: sampler, coords: vec2, @const offset: vec2) -> vec4 fn textureGather(@const component: i32, texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32) -> vec4 fn textureGather(@const component: i32, texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, @const offset: vec2) -> vec4 fn textureGather(@const component: i32, texture: texture_cube, sampler: sampler, coords: vec3) -> vec4 fn textureGather(@const component: i32, texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32) -> vec4 fn textureGather(texture: texture_depth_2d, sampler: sampler, coords: vec2) -> vec4 fn textureGather(texture: texture_depth_2d, sampler: sampler, coords: vec2, @const offset: vec2) -> vec4 fn textureGather(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32) -> vec4 fn textureGather(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32, @const offset: vec2) -> vec4 fn textureGather(texture: texture_depth_cube, sampler: sampler, coords: vec3) -> vec4 fn textureGather(texture: texture_depth_cube_array, sampler: sampler, coords: vec3, array_index: i32) -> vec4 fn textureGatherCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32) -> vec4 fn textureGatherCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32, @const offset: vec2) -> vec4 fn textureGatherCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32) -> vec4 fn textureGatherCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32, @const offset: vec2) -> vec4 fn textureGatherCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3, depth_ref: f32) -> vec4 fn textureGatherCompare(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3, array_index: i32, depth_ref: f32) -> vec4 fn textureNumLayers(texture: texture_2d_array) -> i32 fn textureNumLayers(texture: texture_cube_array) -> i32 fn textureNumLayers(texture: texture_depth_2d_array) -> i32 fn textureNumLayers(texture: texture_depth_cube_array) -> i32 fn textureNumLayers(texture: texture_storage_2d_array) -> i32 fn textureNumLevels(texture: texture_1d) -> i32 fn textureNumLevels(texture: texture_2d) -> i32 fn textureNumLevels(texture: texture_2d_array) -> i32 fn textureNumLevels(texture: texture_3d) -> i32 fn textureNumLevels(texture: texture_cube) -> i32 fn textureNumLevels(texture: texture_cube_array) -> i32 fn textureNumLevels(texture: texture_depth_2d) -> i32 fn textureNumLevels(texture: texture_depth_2d_array) -> i32 fn textureNumLevels(texture: texture_depth_cube) -> i32 fn textureNumLevels(texture: texture_depth_cube_array) -> i32 fn textureNumSamples(texture: texture_multisampled_2d) -> i32 fn textureNumSamples(texture: texture_depth_multisampled_2d) -> i32 @stage("fragment") fn textureSample(texture: texture_1d, sampler: sampler, coords: f32) -> vec4 @stage("fragment") fn textureSample(texture: texture_2d, sampler: sampler, coords: vec2) -> vec4 @stage("fragment") fn textureSample(texture: texture_2d, sampler: sampler, coords: vec2, @const offset: vec2) -> vec4 @stage("fragment") fn textureSample(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32) -> vec4 @stage("fragment") fn textureSample(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, @const offset: vec2) -> vec4 @stage("fragment") fn textureSample(texture: texture_3d, sampler: sampler, coords: vec3) -> vec4 @stage("fragment") fn textureSample(texture: texture_3d, sampler: sampler, coords: vec3, @const offset: vec3) -> vec4 @stage("fragment") fn textureSample(texture: texture_cube, sampler: sampler, coords: vec3) -> vec4 @stage("fragment") fn textureSample(texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32) -> vec4 @stage("fragment") fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_2d, sampler: sampler, coords: vec2, @const offset: vec2) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32, @const offset: vec2) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_cube, sampler: sampler, coords: vec3) -> f32 @stage("fragment") fn textureSample(texture: texture_depth_cube_array, sampler: sampler, coords: vec3, array_index: i32) -> f32 @stage("fragment") fn textureSampleBias(texture: texture_2d, sampler: sampler, coords: vec2, bias: f32) -> vec4 @stage("fragment") fn textureSampleBias(texture: texture_2d, sampler: sampler, coords: vec2, bias: f32, @const offset: vec2) -> vec4 @stage("fragment") fn textureSampleBias(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, bias: f32) -> vec4 @stage("fragment") fn textureSampleBias(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, bias: f32, @const offset: vec2) -> vec4 @stage("fragment") fn textureSampleBias(texture: texture_3d, sampler: sampler, coords: vec3, bias: f32) -> vec4 @stage("fragment") fn textureSampleBias(texture: texture_3d, sampler: sampler, coords: vec3, bias: f32, @const offset: vec3) -> vec4 @stage("fragment") fn textureSampleBias(texture: texture_cube, sampler: sampler, coords: vec3, bias: f32) -> vec4 @stage("fragment") fn textureSampleBias(texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32, bias: f32) -> vec4 @stage("fragment") fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32, @const offset: vec2) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32, @const offset: vec2) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3, depth_ref: f32) -> f32 @stage("fragment") fn textureSampleCompare(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3, array_index: i32, depth_ref: f32) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d, sampler: sampler_comparison, coords: vec2, depth_ref: f32, @const offset: vec2) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32) -> f32 fn textureSampleCompareLevel(texture: texture_depth_2d_array, sampler: sampler_comparison, coords: vec2, array_index: i32, depth_ref: f32, @const offset: vec2) -> f32 fn textureSampleCompareLevel(texture: texture_depth_cube, sampler: sampler_comparison, coords: vec3, depth_ref: f32) -> f32 fn textureSampleCompareLevel(texture: texture_depth_cube_array, sampler: sampler_comparison, coords: vec3, array_index: i32, depth_ref: f32) -> f32 fn textureSampleGrad(texture: texture_2d, sampler: sampler, coords: vec2, ddx: vec2, ddy: vec2) -> vec4 fn textureSampleGrad(texture: texture_2d, sampler: sampler, coords: vec2, ddx: vec2, ddy: vec2, @const offset: vec2) -> vec4 fn textureSampleGrad(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, ddx: vec2, ddy: vec2) -> vec4 fn textureSampleGrad(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, ddx: vec2, ddy: vec2, @const offset: vec2) -> vec4 fn textureSampleGrad(texture: texture_3d, sampler: sampler, coords: vec3, ddx: vec3, ddy: vec3) -> vec4 fn textureSampleGrad(texture: texture_3d, sampler: sampler, coords: vec3, ddx: vec3, ddy: vec3, @const offset: vec3) -> vec4 fn textureSampleGrad(texture: texture_cube, sampler: sampler, coords: vec3, ddx: vec3, ddy: vec3) -> vec4 fn textureSampleGrad(texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32, ddx: vec3, ddy: vec3) -> vec4 fn textureSampleLevel(texture: texture_2d, sampler: sampler, coords: vec2, level: f32) -> vec4 fn textureSampleLevel(texture: texture_2d, sampler: sampler, coords: vec2, level: f32, @const offset: vec2) -> vec4 fn textureSampleLevel(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, level: f32) -> vec4 fn textureSampleLevel(texture: texture_2d_array, sampler: sampler, coords: vec2, array_index: i32, level: f32, @const offset: vec2) -> vec4 fn textureSampleLevel(texture: texture_3d, sampler: sampler, coords: vec3, level: f32) -> vec4 fn textureSampleLevel(texture: texture_3d, sampler: sampler, coords: vec3, level: f32, @const offset: vec3) -> vec4 fn textureSampleLevel(texture: texture_cube, sampler: sampler, coords: vec3, level: f32) -> vec4 fn textureSampleLevel(texture: texture_cube_array, sampler: sampler, coords: vec3, array_index: i32, level: f32) -> vec4 fn textureSampleLevel(texture: texture_depth_2d, sampler: sampler, coords: vec2, level: i32) -> f32 fn textureSampleLevel(texture: texture_depth_2d, sampler: sampler, coords: vec2, level: i32, @const offset: vec2) -> f32 fn textureSampleLevel(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32, level: i32) -> f32 fn textureSampleLevel(texture: texture_depth_2d_array, sampler: sampler, coords: vec2, array_index: i32, level: i32, @const offset: vec2) -> f32 fn textureSampleLevel(texture: texture_depth_cube, sampler: sampler, coords: vec3, level: i32) -> f32 fn textureSampleLevel(texture: texture_depth_cube_array,sampler: sampler, coords: vec3, array_index: i32, level: i32) -> f32 fn textureSampleLevel(texture: texture_external, sampler: sampler, coords: vec2) -> vec4 fn textureStore(texture: texture_storage_1d, coords: i32, value: vec4) fn textureStore(texture: texture_storage_2d, coords: vec2, value: vec4) fn textureStore(texture: texture_storage_2d_array, coords: vec2, array_index: i32, value: vec4) fn textureStore(texture: texture_storage_3d, coords: vec3, value: vec4) fn textureStore(texture: texture_storage_1d, coords: i32, value: vec4) fn textureStore(texture: texture_storage_2d, coords: vec2, value: vec4) fn textureStore(texture: texture_storage_2d_array, coords: vec2, array_index: i32, value: vec4) fn textureStore(texture: texture_storage_3d, coords: vec3, value: vec4) fn textureStore(texture: texture_storage_1d, coords: i32, value: vec4) fn textureStore(texture: texture_storage_2d, coords: vec2, value: vec4) fn textureStore(texture: texture_storage_2d_array, coords: vec2, array_index: i32, value: vec4) fn textureStore(texture: texture_storage_3d, coords: vec3, value: vec4) fn textureLoad(texture: texture_1d, coords: i32, level: i32) -> vec4 fn textureLoad(texture: texture_2d, coords: vec2, level: i32) -> vec4 fn textureLoad(texture: texture_2d_array, coords: vec2, array_index: i32, level: i32) -> vec4 fn textureLoad(texture: texture_3d, coords: vec3, level: i32) -> vec4 fn textureLoad(texture: texture_multisampled_2d, coords: vec2, sample_index: i32) -> vec4 fn textureLoad(texture: texture_depth_2d, coords: vec2, level: i32) -> f32 fn textureLoad(texture: texture_depth_2d_array, coords: vec2, array_index: i32, level: i32) -> f32 fn textureLoad(texture: texture_depth_multisampled_2d, coords: vec2, sample_index: i32) -> f32 fn textureLoad(texture: texture_external, coords: vec2) -> vec4 @stage("fragment", "compute") fn atomicLoad(ptr, read_write>) -> T @stage("fragment", "compute") fn atomicStore(ptr, read_write>, T) @stage("fragment", "compute") fn atomicAdd(ptr, read_write>, T) -> T @stage("fragment", "compute") fn atomicSub(ptr, read_write>, T) -> T @stage("fragment", "compute") fn atomicMax(ptr, read_write>, T) -> T @stage("fragment", "compute") fn atomicMin(ptr, read_write>, T) -> T @stage("fragment", "compute") fn atomicAnd(ptr, read_write>, T) -> T @stage("fragment", "compute") fn atomicOr(ptr, read_write>, T) -> T @stage("fragment", "compute") fn atomicXor(ptr, read_write>, T) -> T @stage("fragment", "compute") fn atomicExchange(ptr, read_write>, T) -> T @stage("fragment", "compute") fn atomicCompareExchangeWeak(ptr, read_write>, T, T) -> __atomic_compare_exchange_result //////////////////////////////////////////////////////////////////////////////// // Type constructors // //////////////////////////////////////////////////////////////////////////////// // Zero value constructors @const("Zero") ctor i32() -> i32 @const("Zero") ctor u32() -> u32 @const("Zero") ctor f32() -> f32 @const("Zero") ctor f16() -> f16 @const("Zero") ctor bool() -> bool @const("Zero") ctor vec2() -> vec2 @const("Zero") ctor vec3() -> vec3 @const("Zero") ctor vec4() -> vec4 @const("Zero") ctor mat2x2() -> mat2x2 @const("Zero") ctor mat2x3() -> mat2x3 @const("Zero") ctor mat2x4() -> mat2x4 @const("Zero") ctor mat3x2() -> mat3x2 @const("Zero") ctor mat3x3() -> mat3x3 @const("Zero") ctor mat3x4() -> mat3x4 @const("Zero") ctor mat4x2() -> mat4x2 @const("Zero") ctor mat4x3() -> mat4x3 @const("Zero") ctor mat4x4() -> mat4x4 // Identity constructors @const("Identity") ctor i32(i32) -> i32 @const("Identity") ctor u32(u32) -> u32 @const("Identity") ctor f32(f32) -> f32 @const("Identity") ctor f16(f16) -> f16 @const("Identity") ctor bool(bool) -> bool @const("Identity") ctor vec2(vec2) -> vec2 @const("Identity") ctor vec3(vec3) -> vec3 @const("Identity") ctor vec4(vec4) -> vec4 @const("Identity") ctor mat2x2(mat2x2) -> mat2x2 @const("Identity") ctor mat2x3(mat2x3) -> mat2x3 @const("Identity") ctor mat2x4(mat2x4) -> mat2x4 @const("Identity") ctor mat3x2(mat3x2) -> mat3x2 @const("Identity") ctor mat3x3(mat3x3) -> mat3x3 @const("Identity") ctor mat3x4(mat3x4) -> mat3x4 @const("Identity") ctor mat4x2(mat4x2) -> mat4x2 @const("Identity") ctor mat4x3(mat4x3) -> mat4x3 @const("Identity") ctor mat4x4(mat4x4) -> mat4x4 // Vector constructors (splat) @const("VecSplat") ctor vec2(T) -> vec2 @const("VecSplat") ctor vec3(T) -> vec3 @const("VecSplat") ctor vec4(T) -> vec4 // Vector constructors (scalar) @const("VecCtorS") ctor vec2(x: T, y: T) -> vec2 @const("VecCtorS") ctor vec3(x: T, y: T, z: T) -> vec3 @const("VecCtorS") ctor vec4(x: T, y: T, z: T, w: T) -> vec4 // Vector constructors (mixed) @const("VecCtorM") ctor vec3(xy: vec2, z: T) -> vec3 @const("VecCtorM") ctor vec3(x: T, yz: vec2) -> vec3 @const("VecCtorM") ctor vec4(xy: vec2, z: T, w: T) -> vec4 @const("VecCtorM") ctor vec4(x: T, yz: vec2, w: T) -> vec4 @const("VecCtorM") ctor vec4(x: T, y: T, zw: vec2) -> vec4 @const("VecCtorM") ctor vec4(xy: vec2, zw: vec2) -> vec4 @const("VecCtorM") ctor vec4(xyz: vec3, w: T) -> vec4 @const("VecCtorM") ctor vec4(x: T, zyw: vec3) -> vec4 // Matrix constructors (scalar) @const("MatCtorS") ctor mat2x2(T, T, T, T) -> mat2x2 @const("MatCtorS") ctor mat2x3(T, T, T, T, T, T) -> mat2x3 @const("MatCtorS") ctor mat2x4(T, T, T, T, T, T, T, T) -> mat2x4 @const("MatCtorS") ctor mat3x2(T, T, T, T, T, T) -> mat3x2 @const("MatCtorS") ctor mat3x3(T, T, T, T, T, T, T, T, T) -> mat3x3 @const("MatCtorS") ctor mat3x4(T, T, T, T, T, T, T, T, T, T, T, T) -> mat3x4 @const("MatCtorS") ctor mat4x2(T, T, T, T, T, T, T, T) -> mat4x2 @const("MatCtorS") ctor mat4x3(T, T, T, T, T, T, T, T, T, T, T, T) -> mat4x3 @const("MatCtorS") ctor mat4x4(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T) -> mat4x4 // Matrix constructors (column vectors) @const("MatCtorV") ctor mat2x2(vec2, vec2) -> mat2x2 @const("MatCtorV") ctor mat2x3(vec3, vec3) -> mat2x3 @const("MatCtorV") ctor mat2x4(vec4, vec4) -> mat2x4 @const("MatCtorV") ctor mat3x2(vec2, vec2, vec2) -> mat3x2 @const("MatCtorV") ctor mat3x3(vec3, vec3, vec3) -> mat3x3 @const("MatCtorV") ctor mat3x4(vec4, vec4, vec4) -> mat3x4 @const("MatCtorV") ctor mat4x2(vec2, vec2, vec2, vec2) -> mat4x2 @const("MatCtorV") ctor mat4x3(vec3, vec3, vec3, vec3) -> mat4x3 @const("MatCtorV") ctor mat4x4(vec4, vec4, vec4, vec4) -> mat4x4 //////////////////////////////////////////////////////////////////////////////// // Type conversions // //////////////////////////////////////////////////////////////////////////////// @const conv f32(T) -> f32 @const conv f16(T) -> f16 @const conv i32(T) -> i32 @const conv u32(T) -> u32 @const conv bool(T) -> bool @const conv vec2(vec2) -> vec2 @const conv vec2(vec2) -> vec2 @const conv vec2(vec2) -> vec2 @const conv vec2(vec2) -> vec2 @const conv vec2(vec2) -> vec2 @const conv vec3(vec3) -> vec3 @const conv vec3(vec3) -> vec3 @const conv vec3(vec3) -> vec3 @const conv vec3(vec3) -> vec3 @const conv vec3(vec3) -> vec3 @const conv vec4(vec4) -> vec4 @const conv vec4(vec4) -> vec4 @const conv vec4(vec4) -> vec4 @const conv vec4(vec4) -> vec4 @const conv vec4(vec4) -> vec4 @const conv mat2x2(mat2x2) -> mat2x2 @const conv mat2x2(mat2x2) -> mat2x2 @const conv mat2x3(mat2x3) -> mat2x3 @const conv mat2x3(mat2x3) -> mat2x3 @const conv mat2x4(mat2x4) -> mat2x4 @const conv mat2x4(mat2x4) -> mat2x4 @const conv mat3x2(mat3x2) -> mat3x2 @const conv mat3x2(mat3x2) -> mat3x2 @const conv mat3x3(mat3x3) -> mat3x3 @const conv mat3x3(mat3x3) -> mat3x3 @const conv mat3x4(mat3x4) -> mat3x4 @const conv mat3x4(mat3x4) -> mat3x4 @const conv mat4x2(mat4x2) -> mat4x2 @const conv mat4x2(mat4x2) -> mat4x2 @const conv mat4x3(mat4x3) -> mat4x3 @const conv mat4x3(mat4x3) -> mat4x3 @const conv mat4x4(mat4x4) -> mat4x4 @const conv mat4x4(mat4x4) -> mat4x4 //////////////////////////////////////////////////////////////////////////////// // Operators // // // // The operator declarations below declare all the unary and binary operators // // supported by the WGSL language (with exception for address-of and // // dereference unary operators). // // // // The syntax is almost identical to builtin functions, except we use 'op' // // instead of 'fn'. The resolving rules are identical to builtins, which is // // described in detail above. // // // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Unary Operators // //////////////////////////////////////////////////////////////////////////////// op ! (bool) -> bool op ! (vec) -> vec @const op ~ (T) -> T @const op ~ (vec) -> vec @const op - (T) -> T @const op - (vec) -> vec //////////////////////////////////////////////////////////////////////////////// // Binary Operators // //////////////////////////////////////////////////////////////////////////////// op + (T, T) -> T op + (vec, vec) -> vec op + (vec, T) -> vec op + (T, vec) -> vec op + (mat, mat) -> mat op - (T, T) -> T op - (vec, vec) -> vec op - (vec, T) -> vec op - (T, vec) -> vec op - (mat, mat) -> mat op * (T, T) -> T op * (vec, vec) -> vec op * (vec, T) -> vec op * (T, vec) -> vec op * (T, mat) -> mat op * (mat, T) -> mat op * (mat, vec) -> vec op * (vec, mat) -> vec op * (mat, mat) -> mat op / (T, T) -> T op / (vec, vec) -> vec op / (vec, T) -> vec op / (T, vec) -> vec op % (T, T) -> T op % (vec, vec) -> vec op % (vec, T) -> vec op % (T, vec) -> vec op ^ (T, T) -> T op ^ (vec, vec) -> vec op & (bool, bool) -> bool op & (vec, vec) -> vec op & (T, T) -> T op & (vec, vec) -> vec op | (bool, bool) -> bool op | (vec, vec) -> vec op | (T, T) -> T op | (vec, vec) -> vec op && (bool, bool) -> bool op || (bool, bool) -> bool op == (T, T) -> bool op == (vec, vec) -> vec op != (T, T) -> bool op != (vec, vec) -> vec op < (T, T) -> bool op < (vec, vec) -> vec op > (T, T) -> bool op > (vec, vec) -> vec op <= (T, T) -> bool op <= (vec, vec) -> vec op >= (T, T) -> bool op >= (vec, vec) -> vec op << (T, u32) -> T op << (vec, vec) -> vec op >> (T, u32) -> T op >> (vec, vec) -> vec