-
-
Notifications
You must be signed in to change notification settings - Fork 14
NZSL Changelog
This changelog is dedicated to the shading language. For library & compiler, see releases.
Beginning with NZSL 1.1, integer and floating-point literals are no longer automatically typed as i32 and f32. They now are categorized into separate types (namely IntLiteral and FloatLiteral) that will be implicitly converted to the appropriate integer or floating-point type.
const VertexLocation: u32 = 0; //< this doesn't compile in NZSL 1.0 but compiles in NZSL 1.1
const VertexLocation: u32 = u32(0); //< this compile in NZSL 1.0 and NZSL 1.1
const VertexLocation: u32 = 0.0; //< this doesn't compile in both NZSL 1.0 and 1.1 (FloatLiteral cannot be cast to integer types)
Literals are resolved based on immediate context (const/variable declarations, function parameters, intrinsic constraints and for-range types). If no such context is available, they are resolved to f32
and i32
by default.
const Foo = 0; //< i32
const Bar: u32 = 1; //< u32
const Baz: u32 = -1; //< error: u32 cannot represent negative values
fn Qux()
{
let x = min(1, u32(2)); //< 1 is resolved to u32 because "min" intrinsic requires that its parameters to be of the same type
let lightCount: u32 = 4;
for x in 0 -> lightCount //< NZSL 1.0 required an explicit cast from 0 to u32, NZSL 1.1 resolves 0 to u32 automatically
{
}
}
This change may break existing code, as attributes taking a u32
value (such as [set(x)]
, [binding(x)]
and [location(x)]
) no longer silently accept a i32
value.
option Loc: i32 = -1;
struct Foo
{
[location(0)] //< valid in both NZSL 1.0 and NZSL 1.1
x: i32,
[location(Loc)] //< valid in NZSL 1.0 (if Loc is set to a positive value), forbidden in NZSL 1.1
y: i32
}
It's now possible to declare a vector of any size without specifying its component type, following rules introduced with literal types.
let x = vec3(1.0, 2.0, 3.0); //< x is a vec3[f32]
let x = vec4(1, 2, u32(3), 4); //< x is a vec4[u32]
let x: vec2[f64] = vec2(1.0, 2.0); //< x is a vec2[f64]
This also works with arrays:
let x = 1.0;
let a = array(x, x, x); //< a is an array[f32, 3]
And you can of course combine those two:
const a = array(vec3(1, 2, 3), vec3(4, 5, 6), vec3(7, 8, 9));
It works for matrices as well:
let x: f32 = 1.0;
let v = vec3[f64](-2.0, -1.0, 0.0);
let m1 = mat4(x); //< mat4[f32]
let m2 = mat3(m1); //< mat3[f32]
let m3 = mat2x3(x, x, x, x, x, x); //< mat2x3[f32]
let m4 = mat3(v, vec3(1.0, 2.0, 3.0), vec3(4.0, 5.0, 6.0)); //< mat3[f64]
Integer and floating-point primitive types support Max
and Min
constants, which are shortcut for their maximum and minimal representable value
Floating-point types additionally support Epsilon
, Infinity
, MinPositive
and NaN
constants.
fn main()
{
let foo = f32.Epsilon; // 1.192092896e-07
let foo = f32.Max; // 3.402823466e+38
let foo = f32.Min; // -3.402823466e+38
let foo = f32.MinPositive; // 1.175494351e-38
let foo = f32.Infinity; // +inf
let foo = f32.NaN; // NaN
let foo = f64.Epsilon; // 2.2204460492503131e-016
let foo = f64.Max; // 1.7976931348623158e+308
let foo = f64.Min; // -1.7976931348623158e+308
let foo = f64.MinPositive; // 2.2250738585072014e-308
let foo = f64.Infinity; // +inf
let foo = f64.NaN; // NaN
let foo = i32.Max; // 2147483647
let foo = i32.Min; // -2147483648
let foo = u32.Max; // 4294967295
let foo = u32.Min; // 0
}
Support for scalar layout
Implemented by @exdal
This layout aligns values only to the scalar components of the block and its composite members.
[layout(scalar)]
struct Foo
{
v0: vec3[f32], //< offset 0
v1: vec3[f32] //< offset 12
}
Lexing block comment (/* */
) has been improved, as ending nested blocks will no longer affect the whole context.
/* We begin a block comment
/* And another one
*/ //< end of block comment in NZSL 1.0
*/ //< end of block comment in NZSL 1.1
Initial release.