tint: Add f16 support for parts of float built-in, part 1
This patch add f16 support for a major part of numeric built-in, and implement corresponding unittests for resolver and backends. This patch also enable f16 constant evaluation for unary minus operator, `atan2` and `clamp`. The following numeric built-ins are not supported yet: * frexp * modf The end-to-end tests for f16 built-in are not added yet. Bug: tint:1473, tint:1502 Change-Id: If807185617b21c510a1a9c371179a60800c4f875 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/96722 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com>
This commit is contained in:
parent
65dcdcbad0
commit
6fe1f515d4
|
@ -165,6 +165,7 @@ 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_fiu32_f16: fa | ia | f32 | i32 | u32 | f16
|
||||
match fia_fi32_f16: fa | ia | f32 | i32 | f16
|
||||
match fia_fiu32: fa | ia | f32 | i32 | u32
|
||||
match fa_f32: fa | f32
|
||||
|
@ -386,48 +387,48 @@ match storage
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#builtin-functions
|
||||
fn abs<T: fiu32>(T) -> T
|
||||
fn abs<N: num, T: fiu32>(vec<N, T>) -> vec<N, T>
|
||||
fn acos(f32) -> f32
|
||||
fn acos<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn acosh(f32) -> f32
|
||||
fn acosh<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn abs<T: fiu32_f16>(T) -> T
|
||||
fn abs<N: num, T: fiu32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn acos<T: f32_f16>(T) -> T
|
||||
fn acos<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn acosh<T: f32_f16>(T) -> T
|
||||
fn acosh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn all(bool) -> bool
|
||||
fn all<N: num>(vec<N, bool>) -> bool
|
||||
fn any(bool) -> bool
|
||||
fn any<N: num>(vec<N, bool>) -> bool
|
||||
fn arrayLength<T, A: access>(ptr<storage, array<T>, A>) -> u32
|
||||
fn asin(f32) -> f32
|
||||
fn asin<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn asinh(f32) -> f32
|
||||
fn asinh<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn atan(f32) -> f32
|
||||
fn atan<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
@const fn atan2<T: fa_f32>(T, T) -> T
|
||||
@const fn atan2<N: num, T: fa_f32>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn atanh(f32) -> f32
|
||||
fn atanh<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn ceil(f32) -> f32
|
||||
fn ceil<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
@const fn clamp<T: fia_fiu32>(T, T, T) -> T
|
||||
@const fn clamp<N: num, T: fia_fiu32>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn cos(f32) -> f32
|
||||
fn cos<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn cosh(f32) -> f32
|
||||
fn cosh<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn asin<T: f32_f16>(T) -> T
|
||||
fn asin<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn asinh<T: f32_f16>(T) -> T
|
||||
fn asinh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn atan<T: f32_f16>(T) -> T
|
||||
fn atan<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
@const fn atan2<T: fa_f32_f16>(T, T) -> T
|
||||
@const fn atan2<T: fa_f32_f16, N: num>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn atanh<T: f32_f16>(T) -> T
|
||||
fn atanh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn ceil<T: f32_f16>(T) -> T
|
||||
fn ceil<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
@const fn clamp<T: fia_fiu32_f16>(T, T, T) -> T
|
||||
@const fn clamp<T: fia_fiu32_f16, N: num>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn cos<T: f32_f16>(T) -> T
|
||||
fn cos<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn cosh<T: f32_f16>(T) -> T
|
||||
fn cosh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn countLeadingZeros<T: iu32>(T) -> T
|
||||
fn countLeadingZeros<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
|
||||
fn countOneBits<T: iu32>(T) -> T
|
||||
fn countOneBits<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
|
||||
fn countTrailingZeros<T: iu32>(T) -> T
|
||||
fn countTrailingZeros<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
|
||||
fn cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
fn degrees(f32) -> f32
|
||||
fn degrees<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn determinant<N: num>(mat<N, N, f32>) -> f32
|
||||
fn distance(f32, f32) -> f32
|
||||
fn distance<N: num>(vec<N, f32>, vec<N, f32>) -> f32
|
||||
fn dot<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> T
|
||||
fn cross<T: f32_f16>(vec3<T>, vec3<T>) -> vec3<T>
|
||||
fn degrees<T: f32_f16>(T) -> T
|
||||
fn degrees<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn determinant<N: num, T: f32_f16>(mat<N, N, T>) -> T
|
||||
fn distance<T: f32_f16>(T, T) -> T
|
||||
fn distance<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> T
|
||||
fn dot<N: num, T: fiu32_f16>(vec<N, T>, vec<N, T>) -> T
|
||||
fn dot4I8Packed(u32, u32) -> i32
|
||||
fn dot4U8Packed(u32, u32) -> u32
|
||||
@stage("fragment") fn dpdx(f32) -> f32
|
||||
|
@ -442,23 +443,23 @@ fn dot4U8Packed(u32, u32) -> u32
|
|||
@stage("fragment") fn dpdyCoarse<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
@stage("fragment") fn dpdyFine(f32) -> f32
|
||||
@stage("fragment") fn dpdyFine<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn exp(f32) -> f32
|
||||
fn exp<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn exp2(f32) -> f32
|
||||
fn exp2<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn exp<T: f32_f16>(T) -> T
|
||||
fn exp<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn exp2<T: f32_f16>(T) -> T
|
||||
fn exp2<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn extractBits<T: iu32>(T, u32, u32) -> T
|
||||
fn extractBits<N: num, T: iu32>(vec<N, T>, u32, u32) -> vec<N, T>
|
||||
fn faceForward<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn faceForward<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn firstLeadingBit<T: iu32>(T) -> T
|
||||
fn firstLeadingBit<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
|
||||
fn firstTrailingBit<T: iu32>(T) -> T
|
||||
fn firstTrailingBit<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
|
||||
fn floor(f32) -> f32
|
||||
fn floor<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn fma(f32, f32, f32) -> f32
|
||||
fn fma<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn fract(f32) -> f32
|
||||
fn fract<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn floor<T: f32_f16>(T) -> T
|
||||
fn floor<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn fma<T: f32_f16>(T, T, T) -> T
|
||||
fn fma<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn fract<T: f32_f16>(T) -> T
|
||||
fn fract<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn frexp(f32) -> __frexp_result
|
||||
fn frexp<N: num>(vec<N, f32>) -> __frexp_result_vec<N>
|
||||
@stage("fragment") fn fwidth(f32) -> f32
|
||||
|
@ -469,64 +470,64 @@ fn frexp<N: num>(vec<N, f32>) -> __frexp_result_vec<N>
|
|||
@stage("fragment") fn fwidthFine<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn insertBits<T: iu32>(T, T, u32, u32) -> T
|
||||
fn insertBits<N: num, T: iu32>(vec<N, T>, vec<N, T>, u32, u32) -> vec<N, T>
|
||||
fn inverseSqrt(f32) -> f32
|
||||
fn inverseSqrt<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn ldexp(f32, i32) -> f32
|
||||
fn ldexp<N: num>(vec<N, f32>, vec<N, i32>) -> vec<N, f32>
|
||||
fn length(f32) -> f32
|
||||
fn length<N: num>(vec<N, f32>) -> f32
|
||||
fn log(f32) -> f32
|
||||
fn log<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn log2(f32) -> f32
|
||||
fn log2<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn max<T: fiu32>(T, T) -> T
|
||||
fn max<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn min<T: fiu32>(T, T) -> T
|
||||
fn min<N: num, T: fiu32>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn mix(f32, f32, f32) -> f32
|
||||
fn mix<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn mix<N: num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32>
|
||||
fn inverseSqrt<T: f32_f16>(T) -> T
|
||||
fn inverseSqrt<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn ldexp<T: f32_f16>(T, i32) -> T
|
||||
fn ldexp<N: num, T: f32_f16>(vec<N, T>, vec<N, i32>) -> vec<N, T>
|
||||
fn length<T: f32_f16>(T) -> T
|
||||
fn length<N: num, T: f32_f16>(vec<N, T>) -> T
|
||||
fn log<T: f32_f16>(T) -> T
|
||||
fn log<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn log2<T: f32_f16>(T) -> T
|
||||
fn log2<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn max<T: fiu32_f16>(T, T) -> T
|
||||
fn max<N: num, T: fiu32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn min<T: fiu32_f16>(T, T) -> T
|
||||
fn min<N: num, T: fiu32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn mix<T: f32_f16>(T, T, T) -> T
|
||||
fn mix<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn mix<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T>
|
||||
fn modf(f32) -> __modf_result
|
||||
fn modf<N: num>(vec<N, f32>) -> __modf_result_vec<N>
|
||||
fn normalize<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn normalize<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn pack2x16float(vec2<f32>) -> u32
|
||||
fn pack2x16snorm(vec2<f32>) -> u32
|
||||
fn pack2x16unorm(vec2<f32>) -> u32
|
||||
fn pack4x8snorm(vec4<f32>) -> u32
|
||||
fn pack4x8unorm(vec4<f32>) -> u32
|
||||
fn pow(f32, f32) -> f32
|
||||
fn pow<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn radians(f32) -> f32
|
||||
fn radians<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn reflect<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn refract<N: num>(vec<N, f32>, vec<N, f32>, f32) -> vec<N, f32>
|
||||
fn pow<T: f32_f16>(T, T) -> T
|
||||
fn pow<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn radians<T: f32_f16>(T) -> T
|
||||
fn radians<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn reflect<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn refract<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T>
|
||||
fn reverseBits<T: iu32>(T) -> T
|
||||
fn reverseBits<N: num, T: iu32>(vec<N, T>) -> vec<N, T>
|
||||
fn round(f32) -> f32
|
||||
fn round<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn select<T: scalar_no_f16>(T, T, bool) -> T
|
||||
fn select<T: scalar_no_f16, N: num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T>
|
||||
fn select<N: num, T: scalar_no_f16>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T>
|
||||
fn sign(f32) -> f32
|
||||
fn sign<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn sin(f32) -> f32
|
||||
fn sin<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn sinh(f32) -> f32
|
||||
fn sinh<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn smoothstep(f32, f32, f32) -> f32
|
||||
fn smoothstep<N: num>(vec<N, f32>, vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn sqrt(f32) -> f32
|
||||
fn sqrt<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn step(f32, f32) -> f32
|
||||
fn step<N: num>(vec<N, f32>, vec<N, f32>) -> vec<N, f32>
|
||||
fn round<T: f32_f16>(T) -> T
|
||||
fn round<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn select<T: scalar>(T, T, bool) -> T
|
||||
fn select<T: scalar, N: num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T>
|
||||
fn select<N: num, T: scalar>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T>
|
||||
fn sign<T: f32_f16>(T) -> T
|
||||
fn sign<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn sin<T: f32_f16>(T) -> T
|
||||
fn sin<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn sinh<T: f32_f16>(T) -> T
|
||||
fn sinh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn smoothstep<T: f32_f16>(T, T, T) -> T
|
||||
fn smoothstep<N: num, T: f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
fn sqrt<T: f32_f16>(T) -> T
|
||||
fn sqrt<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn step<T: f32_f16>(T, T) -> T
|
||||
fn step<N: num, T: f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T>
|
||||
@stage("compute") fn storageBarrier()
|
||||
fn tan(f32) -> f32
|
||||
fn tan<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn tanh(f32) -> f32
|
||||
fn tanh<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn transpose<M: num, N: num>(mat<M, N, f32>) -> mat<N, M, f32>
|
||||
fn trunc(f32) -> f32
|
||||
fn trunc<N: num>(vec<N, f32>) -> vec<N, f32>
|
||||
fn tan<T: f32_f16>(T) -> T
|
||||
fn tan<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn tanh<T: f32_f16>(T) -> T
|
||||
fn tanh<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn transpose<M: num, N: num, T: f32_f16>(mat<M, N, T>) -> mat<N, M, T>
|
||||
fn trunc<T: f32_f16>(T) -> T
|
||||
fn trunc<N: num, T: f32_f16>(vec<N, T>) -> vec<N, T>
|
||||
fn unpack2x16float(u32) -> vec2<f32>
|
||||
fn unpack2x16snorm(u32) -> vec2<f32>
|
||||
fn unpack2x16unorm(u32) -> vec2<f32>
|
||||
|
|
|
@ -129,9 +129,9 @@ TEST_F(ResolverBuiltinTest, Select_Error_NoParams) {
|
|||
R"(error: no matching call to select()
|
||||
|
||||
3 candidate functions:
|
||||
select(T, T, bool) -> T where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(T, T, bool) -> T where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -145,9 +145,9 @@ TEST_F(ResolverBuiltinTest, Select_Error_SelectorInt) {
|
|||
R"(error: no matching call to select(i32, i32, i32)
|
||||
|
||||
3 candidate functions:
|
||||
select(T, T, bool) -> T where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(T, T, bool) -> T where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -162,9 +162,9 @@ TEST_F(ResolverBuiltinTest, Select_Error_Matrix) {
|
|||
R"(error: no matching call to select(mat2x2<f32>, mat2x2<f32>, bool)
|
||||
|
||||
3 candidate functions:
|
||||
select(T, T, bool) -> T where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(T, T, bool) -> T where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -178,9 +178,9 @@ TEST_F(ResolverBuiltinTest, Select_Error_MismatchTypes) {
|
|||
R"(error: no matching call to select(f32, vec2<f32>, bool)
|
||||
|
||||
3 candidate functions:
|
||||
select(T, T, bool) -> T where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(T, T, bool) -> T where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -194,9 +194,9 @@ TEST_F(ResolverBuiltinTest, Select_Error_MismatchVectorSize) {
|
|||
R"(error: no matching call to select(vec2<f32>, vec3<f32>, bool)
|
||||
|
||||
3 candidate functions:
|
||||
select(T, T, bool) -> T where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, i32, u32 or bool
|
||||
select(T, T, bool) -> T where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, bool) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
select(vecN<T>, vecN<T>, vecN<bool>) -> vecN<T> where: T is f32, f16, i32, u32 or bool
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -458,6 +458,206 @@ TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, FourParams_Vector_f32) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, OneParam_Scalar_f16) {
|
||||
auto param = GetParam();
|
||||
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call(param.name, 1_h);
|
||||
WrapInFunction(call);
|
||||
|
||||
if (param.args_number == 1u) {
|
||||
// Parameter count matched.
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
} else {
|
||||
// Invalid parameter count.
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("error: no matching call to " + std::string(param.name) + "(f16)"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, OneParam_Vector_f16) {
|
||||
auto param = GetParam();
|
||||
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h));
|
||||
WrapInFunction(call);
|
||||
|
||||
if (param.args_number == 1u) {
|
||||
// Parameter count matched.
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->is_float_vector());
|
||||
EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
|
||||
ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
|
||||
} else {
|
||||
// Invalid parameter count.
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
|
||||
std::string(param.name) + "(vec3<f16>)"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, TwoParams_Scalar_f16) {
|
||||
auto param = GetParam();
|
||||
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call(param.name, 1_h, 1_h);
|
||||
WrapInFunction(call);
|
||||
|
||||
if (param.args_number == 2u) {
|
||||
// Parameter count matched.
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
} else {
|
||||
// Invalid parameter count.
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
|
||||
std::string(param.name) + "(f16, f16)"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, TwoParams_Vector_f16) {
|
||||
auto param = GetParam();
|
||||
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h));
|
||||
WrapInFunction(call);
|
||||
|
||||
if (param.args_number == 2u) {
|
||||
// Parameter count matched.
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->is_float_vector());
|
||||
EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
|
||||
ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
|
||||
} else {
|
||||
// Invalid parameter count.
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
|
||||
std::string(param.name) + "(vec3<f16>, vec3<f16>)"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Scalar_f16) {
|
||||
auto param = GetParam();
|
||||
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call(param.name, 1_h, 1_h, 1_h);
|
||||
WrapInFunction(call);
|
||||
|
||||
if (param.args_number == 3u) {
|
||||
// Parameter count matched.
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
} else {
|
||||
// Invalid parameter count.
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
|
||||
std::string(param.name) + "(f16, f16, f16)"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, ThreeParams_Vector_f16) {
|
||||
auto param = GetParam();
|
||||
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h),
|
||||
vec3<f16>(1_h, 1_h, 3_h));
|
||||
WrapInFunction(call);
|
||||
|
||||
if (param.args_number == 3u) {
|
||||
// Parameter count matched.
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->is_float_vector());
|
||||
EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
|
||||
ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
|
||||
} else {
|
||||
// Invalid parameter count.
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("error: no matching call to " + std::string(param.name) +
|
||||
"(vec3<f16>, vec3<f16>, vec3<f16>)"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, FourParams_Scalar_f16) {
|
||||
auto param = GetParam();
|
||||
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call(param.name, 1_h, 1_h, 1_h, 1_h);
|
||||
WrapInFunction(call);
|
||||
|
||||
if (param.args_number == 4u) {
|
||||
// Parameter count matched.
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
} else {
|
||||
// Invalid parameter count.
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_THAT(r()->error(), HasSubstr("error: no matching call to " +
|
||||
std::string(param.name) + "(f16, f16, f16, f16)"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(ResolverBuiltinTest_FloatBuiltin_IdenticalType, FourParams_Vector_f16) {
|
||||
auto param = GetParam();
|
||||
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call(param.name, vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h),
|
||||
vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h));
|
||||
WrapInFunction(call);
|
||||
|
||||
if (param.args_number == 4u) {
|
||||
// Parameter count matched.
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->is_float_vector());
|
||||
EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
|
||||
ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
|
||||
} else {
|
||||
// Invalid parameter count.
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_THAT(r()->error(),
|
||||
HasSubstr("error: no matching call to " + std::string(param.name) +
|
||||
"(vec3<f16>, vec3<f16>, vec3<f16>, vec3<f16>)"));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
ResolverTest,
|
||||
ResolverBuiltinTest_FloatBuiltin_IdenticalType,
|
||||
|
@ -526,6 +726,20 @@ TEST_F(ResolverBuiltinFloatTest, Cross_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Cross_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call("cross", vec3<f16>(1_h, 2_h, 3_h), vec3<f16>(1_h, 2_h, 3_h));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->is_float_vector());
|
||||
EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Cross_Error_NoArgs) {
|
||||
auto* call = Call("cross");
|
||||
WrapInFunction(call);
|
||||
|
@ -535,7 +749,7 @@ TEST_F(ResolverBuiltinFloatTest, Cross_Error_NoArgs) {
|
|||
EXPECT_EQ(r()->error(), R"(error: no matching call to cross()
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
cross(vec3<T>, vec3<T>) -> vec3<T> where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -548,7 +762,7 @@ TEST_F(ResolverBuiltinFloatTest, Cross_Error_Scalar) {
|
|||
EXPECT_EQ(r()->error(), R"(error: no matching call to cross(f32, f32)
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
cross(vec3<T>, vec3<T>) -> vec3<T> where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -562,7 +776,7 @@ TEST_F(ResolverBuiltinFloatTest, Cross_Error_Vec3Int) {
|
|||
R"(error: no matching call to cross(vec3<i32>, vec3<i32>)
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
cross(vec3<T>, vec3<T>) -> vec3<T> where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -577,7 +791,7 @@ TEST_F(ResolverBuiltinFloatTest, Cross_Error_Vec4) {
|
|||
R"(error: no matching call to cross(vec4<f32>, vec4<f32>)
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
cross(vec3<T>, vec3<T>) -> vec3<T> where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -593,7 +807,7 @@ TEST_F(ResolverBuiltinFloatTest, Cross_Error_TooManyParams) {
|
|||
R"(error: no matching call to cross(vec3<f32>, vec3<f32>, vec3<f32>)
|
||||
|
||||
1 candidate function:
|
||||
cross(vec3<f32>, vec3<f32>) -> vec3<f32>
|
||||
cross(vec3<T>, vec3<T>) -> vec3<T> where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -608,6 +822,18 @@ TEST_F(ResolverBuiltinFloatTest, Distance_Scalar_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Distance_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call("distance", 1_h, 1_h);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Distance_Vector_f32) {
|
||||
auto* call = Call("distance", vec3<f32>(1_f, 1_f, 3_f), vec3<f32>(1_f, 1_f, 3_f));
|
||||
WrapInFunction(call);
|
||||
|
@ -618,31 +844,44 @@ TEST_F(ResolverBuiltinFloatTest, Distance_Vector_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Distance_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call("distance", vec3<f16>(1_h, 1_h, 3_h), vec3<f16>(1_h, 1_h, 3_h));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Distance_TooManyParams) {
|
||||
auto* call = Call("distance", 1_f, 1_f, 3_f);
|
||||
auto* call = Call("distance", vec3<f32>(1_f, 1_f, 3_f), vec3<f32>(1_f, 1_f, 3_f),
|
||||
vec3<f32>(1_f, 1_f, 3_f));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(r()->error(), R"(error: no matching call to distance(f32, f32, f32)
|
||||
EXPECT_EQ(r()->error(), R"(error: no matching call to distance(vec3<f32>, vec3<f32>, vec3<f32>)
|
||||
|
||||
2 candidate functions:
|
||||
distance(f32, f32) -> f32
|
||||
distance(vecN<f32>, vecN<f32>) -> f32
|
||||
distance(T, T) -> T where: T is f32 or f16
|
||||
distance(vecN<T>, vecN<T>) -> T where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Distance_TooFewParams) {
|
||||
auto* call = Call("distance", 1_f);
|
||||
auto* call = Call("distance", vec3<f32>(1_f, 1_f, 3_f));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
|
||||
EXPECT_EQ(r()->error(), R"(error: no matching call to distance(f32)
|
||||
EXPECT_EQ(r()->error(), R"(error: no matching call to distance(vec3<f32>)
|
||||
|
||||
2 candidate functions:
|
||||
distance(f32, f32) -> f32
|
||||
distance(vecN<f32>, vecN<f32>) -> f32
|
||||
distance(T, T) -> T where: T is f32 or f16
|
||||
distance(vecN<T>, vecN<T>) -> T where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -655,8 +894,8 @@ TEST_F(ResolverBuiltinFloatTest, Distance_NoParams) {
|
|||
EXPECT_EQ(r()->error(), R"(error: no matching call to distance()
|
||||
|
||||
2 candidate functions:
|
||||
distance(f32, f32) -> f32
|
||||
distance(vecN<f32>, vecN<f32>) -> f32
|
||||
distance(T, T) -> T where: T is f32 or f16
|
||||
distance(vecN<T>, vecN<T>) -> T where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -796,6 +1035,18 @@ TEST_F(ResolverBuiltinFloatTest, Length_Scalar_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Length_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call("length", 1_h);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Length_FloatVector_f32) {
|
||||
auto* call = Call("length", vec3<f32>(1_f, 1_f, 3_f));
|
||||
WrapInFunction(call);
|
||||
|
@ -806,6 +1057,18 @@ TEST_F(ResolverBuiltinFloatTest, Length_FloatVector_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Length_FloatVector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call("length", vec3<f16>(1_h, 1_h, 3_h));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Length_NoParams) {
|
||||
auto* call = Call("length");
|
||||
WrapInFunction(call);
|
||||
|
@ -815,8 +1078,8 @@ TEST_F(ResolverBuiltinFloatTest, Length_NoParams) {
|
|||
EXPECT_EQ(r()->error(), R"(error: no matching call to length()
|
||||
|
||||
2 candidate functions:
|
||||
length(f32) -> f32
|
||||
length(vecN<f32>) -> f32
|
||||
length(T) -> T where: T is f32 or f16
|
||||
length(vecN<T>) -> T where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -829,8 +1092,8 @@ TEST_F(ResolverBuiltinFloatTest, Length_TooManyParams) {
|
|||
EXPECT_EQ(r()->error(), R"(error: no matching call to length(f32, f32)
|
||||
|
||||
2 candidate functions:
|
||||
length(f32) -> f32
|
||||
length(vecN<f32>) -> f32
|
||||
length(T) -> T where: T is f32 or f16
|
||||
length(vecN<T>) -> T where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -849,6 +1112,21 @@ TEST_F(ResolverBuiltinFloatTest, Mix_VectorScalar_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Mix_VectorScalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call("mix", vec3<f16>(1_h, 1_h, 1_h), vec3<f16>(1_h, 1_h, 1_h), 4_h);
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->is_float_vector());
|
||||
EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
|
||||
ASSERT_NE(TypeOf(call)->As<sem::Vector>()->type(), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
|
||||
}
|
||||
|
||||
// modf: (f32) -> __modf_result, (vecN<f32>) -> __modf_result_vecN
|
||||
TEST_F(ResolverBuiltinFloatTest, ModfScalar) {
|
||||
auto* call = Call("modf", 1_f);
|
||||
|
@ -987,6 +1265,20 @@ TEST_F(ResolverBuiltinFloatTest, Normalize_Vector_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Normalize_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* call = Call("normalize", vec3<f16>(1_h, 1_h, 3_h));
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->is_float_vector());
|
||||
EXPECT_EQ(TypeOf(call)->As<sem::Vector>()->Width(), 3u);
|
||||
EXPECT_TRUE(TypeOf(call)->As<sem::Vector>()->type()->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinFloatTest, Normalize_Error_NoParams) {
|
||||
auto* call = Call("normalize");
|
||||
WrapInFunction(call);
|
||||
|
@ -996,7 +1288,7 @@ TEST_F(ResolverBuiltinFloatTest, Normalize_Error_NoParams) {
|
|||
EXPECT_EQ(r()->error(), R"(error: no matching call to normalize()
|
||||
|
||||
1 candidate function:
|
||||
normalize(vecN<f32>) -> vecN<f32>
|
||||
normalize(vecN<T>) -> vecN<T> where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1436,6 +1728,20 @@ TEST_F(ResolverBuiltinTest, Determinant_2x2_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, Determinant_2x2_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
GlobalVar("var", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* call = Call("determinant", "var");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, Determinant_3x3_f32) {
|
||||
GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
|
||||
|
||||
|
@ -1448,6 +1754,20 @@ TEST_F(ResolverBuiltinTest, Determinant_3x3_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, Determinant_3x3_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
GlobalVar("var", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* call = Call("determinant", "var");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, Determinant_4x4_f32) {
|
||||
GlobalVar("var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
|
||||
|
||||
|
@ -1460,6 +1780,20 @@ TEST_F(ResolverBuiltinTest, Determinant_4x4_f32) {
|
|||
EXPECT_TRUE(TypeOf(call)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, Determinant_4x4_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
GlobalVar("var", ty.mat4x4<f16>(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* call = Call("determinant", "var");
|
||||
WrapInFunction(call);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(call), nullptr);
|
||||
EXPECT_TRUE(TypeOf(call)->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, Determinant_NotSquare) {
|
||||
GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
||||
|
||||
|
@ -1471,7 +1805,7 @@ TEST_F(ResolverBuiltinTest, Determinant_NotSquare) {
|
|||
EXPECT_EQ(r()->error(), R"(error: no matching call to determinant(mat2x3<f32>)
|
||||
|
||||
1 candidate function:
|
||||
determinant(matNxN<f32>) -> f32
|
||||
determinant(matNxN<T>) -> T where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1486,7 +1820,7 @@ TEST_F(ResolverBuiltinTest, Determinant_NotMatrix) {
|
|||
EXPECT_EQ(r()->error(), R"(error: no matching call to determinant(f32)
|
||||
|
||||
1 candidate function:
|
||||
determinant(matNxN<f32>) -> f32
|
||||
determinant(matNxN<T>) -> T where: T is f32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
@ -1507,6 +1841,20 @@ TEST_F(ResolverBuiltinTest, Dot_Vec2_f32) {
|
|||
EXPECT_TRUE(TypeOf(expr)->Is<sem::F32>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, Dot_Vec2_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
GlobalVar("my_var", ty.vec2<f16>(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* expr = Call("dot", "my_var", "my_var");
|
||||
WrapInFunction(expr);
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
ASSERT_NE(TypeOf(expr), nullptr);
|
||||
EXPECT_TRUE(TypeOf(expr)->Is<sem::F16>());
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinTest, Dot_Vec3_i32) {
|
||||
GlobalVar("my_var", ty.vec3<i32>(), ast::StorageClass::kPrivate);
|
||||
|
||||
|
@ -1541,7 +1889,7 @@ TEST_F(ResolverBuiltinTest, Dot_Error_Scalar) {
|
|||
R"(error: no matching call to dot(f32, f32)
|
||||
|
||||
1 candidate function:
|
||||
dot(vecN<T>, vecN<T>) -> T where: T is f32, i32 or u32
|
||||
dot(vecN<T>, vecN<T>) -> T where: T is f32, i32, u32 or f16
|
||||
)");
|
||||
}
|
||||
|
||||
|
|
|
@ -73,33 +73,32 @@ auto Dispatch_fia_fi32_f16(F&& f, CONSTANTS&&... cs) {
|
|||
[&](const sem::AbstractFloat*) { return f(cs->template As<AFloat>()...); },
|
||||
[&](const sem::F32*) { return f(cs->template As<f32>()...); },
|
||||
[&](const sem::I32*) { return f(cs->template As<i32>()...); },
|
||||
[&](const sem::F16*) {
|
||||
// TODO(crbug.com/tint/1502): Support const eval for f16
|
||||
return nullptr;
|
||||
});
|
||||
[&](const sem::F16*) { return f(cs->template As<f16>()...); });
|
||||
}
|
||||
|
||||
/// Helper that calls `f` passing in the value of all `cs`.
|
||||
/// Assumes all `cs` are of the same type.
|
||||
template <typename F, typename... CONSTANTS>
|
||||
auto Dispatch_fia_fiu32(F&& f, CONSTANTS&&... cs) {
|
||||
auto Dispatch_fia_fiu32_f16(F&& f, CONSTANTS&&... cs) {
|
||||
return Switch(
|
||||
First(cs...)->Type(), //
|
||||
[&](const sem::AbstractInt*) { return f(cs->template As<AInt>()...); },
|
||||
[&](const sem::AbstractFloat*) { return f(cs->template As<AFloat>()...); },
|
||||
[&](const sem::F32*) { return f(cs->template As<f32>()...); },
|
||||
[&](const sem::I32*) { return f(cs->template As<i32>()...); },
|
||||
[&](const sem::U32*) { return f(cs->template As<u32>()...); });
|
||||
[&](const sem::U32*) { return f(cs->template As<u32>()...); },
|
||||
[&](const sem::F16*) { return f(cs->template As<f16>()...); });
|
||||
}
|
||||
|
||||
/// Helper that calls `f` passing in the value of all `cs`.
|
||||
/// Assumes all `cs` are of the same type.
|
||||
template <typename F, typename... CONSTANTS>
|
||||
auto Dispatch_fa_f32(F&& f, CONSTANTS&&... cs) {
|
||||
auto Dispatch_fa_f32_f16(F&& f, CONSTANTS&&... cs) {
|
||||
return Switch(
|
||||
First(cs...)->Type(), //
|
||||
[&](const sem::AbstractFloat*) { return f(cs->template As<AFloat>()...); },
|
||||
[&](const sem::F32*) { return f(cs->template As<f32>()...); });
|
||||
[&](const sem::F32*) { return f(cs->template As<f32>()...); },
|
||||
[&](const sem::F16*) { return f(cs->template As<f16>()...); });
|
||||
}
|
||||
|
||||
/// ZeroTypeDispatch is a helper for calling the function `f`, passing a single zero-value argument
|
||||
|
@ -730,7 +729,7 @@ const sem::Constant* ConstEval::atan2(const sem::Type*,
|
|||
auto create = [&](auto i, auto j) {
|
||||
return CreateElement(builder, c0->Type(), decltype(i)(std::atan2(i.value, j.value)));
|
||||
};
|
||||
return Dispatch_fa_f32(create, c0, c1);
|
||||
return Dispatch_fa_f32_f16(create, c0, c1);
|
||||
};
|
||||
return TransformElements(builder, transform, args[0]->ConstantValue(),
|
||||
args[1]->ConstantValue());
|
||||
|
@ -744,7 +743,7 @@ const sem::Constant* ConstEval::clamp(const sem::Type*,
|
|||
return CreateElement(builder, c0->Type(),
|
||||
decltype(e)(std::min(std::max(e, low), high)));
|
||||
};
|
||||
return Dispatch_fia_fiu32(create, c0, c1, c2);
|
||||
return Dispatch_fia_fiu32_f16(create, c0, c1, c2);
|
||||
};
|
||||
return TransformElements(builder, transform, args[0]->ConstantValue(), args[1]->ConstantValue(),
|
||||
args[2]->ConstantValue());
|
||||
|
|
|
@ -2994,7 +2994,8 @@ struct Values {
|
|||
};
|
||||
|
||||
struct Case {
|
||||
std::variant<Values<AInt>, Values<AFloat>, Values<u32>, Values<i32>, Values<f32>> values;
|
||||
std::variant<Values<AInt>, Values<AFloat>, Values<u32>, Values<i32>, Values<f32>, Values<f16>>
|
||||
values;
|
||||
};
|
||||
|
||||
static std::ostream& operator<<(std::ostream& o, const Case& c) {
|
||||
|
@ -3101,6 +3102,15 @@ INSTANTIATE_TEST_SUITE_P(Negation,
|
|||
C(-kHighest<f32>, kHighest<f32>),
|
||||
C(kLowest<f32>, Negate(kLowest<f32>)),
|
||||
C(Negate(kLowest<f32>), kLowest<f32>),
|
||||
// f16
|
||||
C(0.0_h, -0.0_h),
|
||||
C(-0.0_h, 0.0_h),
|
||||
C(1.0_h, -1.0_h),
|
||||
C(-1.0_h, 1.0_h),
|
||||
C(kHighest<f16>, -kHighest<f16>),
|
||||
C(-kHighest<f16>, kHighest<f16>),
|
||||
C(kLowest<f16>, Negate(kLowest<f16>)),
|
||||
C(Negate(kLowest<f16>), kLowest<f16>),
|
||||
})));
|
||||
|
||||
// Make sure UBSan doesn't trip on C++'s undefined behaviour of negating the smallest negative
|
||||
|
@ -3252,7 +3262,8 @@ INSTANTIATE_TEST_SUITE_P( //
|
|||
ResolverConstEvalBuiltinTest,
|
||||
testing::Combine(testing::Values(sem::BuiltinType::kAtan2),
|
||||
testing::ValuesIn(Concat(Atan2Cases<AFloat, true>(), //
|
||||
Atan2Cases<f32, false>()))));
|
||||
Atan2Cases<f32, false>(),
|
||||
Atan2Cases<f16, false>()))));
|
||||
|
||||
template <typename T>
|
||||
std::vector<Case> ClampCases() {
|
||||
|
@ -3277,7 +3288,8 @@ INSTANTIATE_TEST_SUITE_P( //
|
|||
ClampCases<i32>(),
|
||||
ClampCases<u32>(),
|
||||
ClampCases<AFloat>(),
|
||||
ClampCases<f32>()))));
|
||||
ClampCases<f32>(),
|
||||
ClampCases<f16>()))));
|
||||
|
||||
} // namespace builtin
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1302,10 +1302,12 @@ bool GeneratorImpl::EmitFrexpCall(std::ostream& out,
|
|||
bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
|
||||
const ast::CallExpression* expr,
|
||||
const sem::Builtin* builtin) {
|
||||
auto* return_elem_type = sem::Type::DeepestElementOf(builtin->ReturnType());
|
||||
const std::string suffix = Is<sem::F16>(return_elem_type) ? "hf" : "f";
|
||||
return CallBuiltinHelper(out, expr, builtin,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
line(b) << "return " << params[0] << " * " << std::setprecision(20)
|
||||
<< sem::kRadToDeg << ";";
|
||||
<< sem::kRadToDeg << suffix << ";";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -1313,10 +1315,12 @@ bool GeneratorImpl::EmitDegreesCall(std::ostream& out,
|
|||
bool GeneratorImpl::EmitRadiansCall(std::ostream& out,
|
||||
const ast::CallExpression* expr,
|
||||
const sem::Builtin* builtin) {
|
||||
auto* return_elem_type = sem::Type::DeepestElementOf(builtin->ReturnType());
|
||||
const std::string suffix = Is<sem::F16>(return_elem_type) ? "hf" : "f";
|
||||
return CallBuiltinHelper(out, expr, builtin,
|
||||
[&](TextBuffer* b, const std::vector<std::string>& params) {
|
||||
line(b) << "return " << params[0] << " * " << std::setprecision(20)
|
||||
<< sem::kDegToRad << ";";
|
||||
<< sem::kDegToRad << suffix << ";";
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -29,36 +29,40 @@ using BuiltinType = sem::BuiltinType;
|
|||
|
||||
using GlslGeneratorImplTest_Builtin = TestHelper;
|
||||
|
||||
enum class ParamType {
|
||||
enum class CallParamType {
|
||||
kF32,
|
||||
kU32,
|
||||
kBool,
|
||||
kF16,
|
||||
};
|
||||
|
||||
struct BuiltinData {
|
||||
BuiltinType builtin;
|
||||
ParamType type;
|
||||
CallParamType type;
|
||||
const char* glsl_name;
|
||||
};
|
||||
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
|
||||
out << data.glsl_name;
|
||||
out << data.glsl_name << "<";
|
||||
switch (data.type) {
|
||||
case ParamType::kF32:
|
||||
case CallParamType::kF32:
|
||||
out << "f32";
|
||||
break;
|
||||
case ParamType::kU32:
|
||||
case CallParamType::kU32:
|
||||
out << "u32";
|
||||
break;
|
||||
case ParamType::kBool:
|
||||
case CallParamType::kBool:
|
||||
out << "bool";
|
||||
break;
|
||||
case CallParamType::kF16:
|
||||
out << "f16";
|
||||
break;
|
||||
}
|
||||
out << ">";
|
||||
return out;
|
||||
}
|
||||
|
||||
const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
||||
ParamType type,
|
||||
CallParamType type,
|
||||
ProgramBuilder* builder) {
|
||||
std::string name;
|
||||
std::ostringstream str(name);
|
||||
|
@ -96,29 +100,51 @@ const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
|||
case BuiltinType::kTanh:
|
||||
case BuiltinType::kTrunc:
|
||||
case BuiltinType::kSign:
|
||||
return builder->Call(str.str(), "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2");
|
||||
}
|
||||
case BuiltinType::kLdexp:
|
||||
return builder->Call(str.str(), "f2", "i2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "i2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "i2");
|
||||
}
|
||||
case BuiltinType::kAtan2:
|
||||
case BuiltinType::kDot:
|
||||
case BuiltinType::kDistance:
|
||||
case BuiltinType::kPow:
|
||||
case BuiltinType::kReflect:
|
||||
case BuiltinType::kStep:
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
}
|
||||
case BuiltinType::kCross:
|
||||
return builder->Call(str.str(), "f3", "f3");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h3", "h3");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f3", "f3");
|
||||
}
|
||||
case BuiltinType::kFma:
|
||||
case BuiltinType::kMix:
|
||||
case BuiltinType::kFaceForward:
|
||||
case BuiltinType::kSmoothstep:
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
}
|
||||
case BuiltinType::kAll:
|
||||
case BuiltinType::kAny:
|
||||
return builder->Call(str.str(), "b2");
|
||||
case BuiltinType::kAbs:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2");
|
||||
}
|
||||
|
@ -127,23 +153,39 @@ const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
|||
return builder->Call(str.str(), "u2");
|
||||
case BuiltinType::kMax:
|
||||
case BuiltinType::kMin:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2", "u2");
|
||||
}
|
||||
case BuiltinType::kClamp:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2", "u2", "u2");
|
||||
}
|
||||
case BuiltinType::kSelect:
|
||||
return builder->Call(str.str(), "f2", "f2", "b2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "b2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2", "b2");
|
||||
}
|
||||
case BuiltinType::kDeterminant:
|
||||
return builder->Call(str.str(), "m2x2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "hm2x2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "m2x2");
|
||||
}
|
||||
case BuiltinType::kTranspose:
|
||||
return builder->Call(str.str(), "m3x2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "hm3x2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "m3x2");
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -153,6 +195,15 @@ using GlslBuiltinTest = TestParamHelper<BuiltinData>;
|
|||
TEST_P(GlslBuiltinTest, Emit) {
|
||||
auto param = GetParam();
|
||||
|
||||
if (param.type == CallParamType::kF16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
|
||||
}
|
||||
|
||||
GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
|
||||
|
@ -180,64 +231,110 @@ TEST_P(GlslBuiltinTest, Emit) {
|
|||
INSTANTIATE_TEST_SUITE_P(
|
||||
GlslGeneratorImplTest_Builtin,
|
||||
GlslBuiltinTest,
|
||||
testing::Values(BuiltinData{BuiltinType::kAbs, ParamType::kF32, "abs"},
|
||||
BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
|
||||
BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
|
||||
BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
|
||||
BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
|
||||
BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
|
||||
BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan"},
|
||||
BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
|
||||
BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
|
||||
BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
|
||||
BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
|
||||
BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
|
||||
BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "bitCount"},
|
||||
BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
|
||||
BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
|
||||
BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
|
||||
BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
|
||||
BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "dFdx"},
|
||||
BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "dFdx"},
|
||||
BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "dFdx"},
|
||||
BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "dFdy"},
|
||||
BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "dFdy"},
|
||||
BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "dFdy"},
|
||||
BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
|
||||
BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
|
||||
BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
|
||||
BuiltinData{BuiltinType::kFma, ParamType::kF32, "fma"},
|
||||
BuiltinData{BuiltinType::kFract, ParamType::kF32, "fract"},
|
||||
BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "inversesqrt"},
|
||||
BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
|
||||
BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
|
||||
BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
|
||||
BuiltinData{BuiltinType::kMax, ParamType::kF32, "max"},
|
||||
BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
|
||||
BuiltinData{BuiltinType::kMin, ParamType::kF32, "min"},
|
||||
BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
|
||||
BuiltinData{BuiltinType::kMix, ParamType::kF32, "mix"},
|
||||
BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
|
||||
BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
|
||||
BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
|
||||
BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "bitfieldReverse"},
|
||||
BuiltinData{BuiltinType::kRound, ParamType::kU32, "round"},
|
||||
BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
|
||||
BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
|
||||
BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, ParamType::kF32, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
|
||||
BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
|
||||
BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
|
||||
BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
|
||||
BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
|
||||
BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"}));
|
||||
testing::Values(/* Logical built-in */
|
||||
BuiltinData{BuiltinType::kAll, CallParamType::kBool, "all"},
|
||||
BuiltinData{BuiltinType::kAny, CallParamType::kBool, "any"},
|
||||
/* Float built-in */
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kF32, "abs"},
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kF16, "abs"},
|
||||
BuiltinData{BuiltinType::kAcos, CallParamType::kF32, "acos"},
|
||||
BuiltinData{BuiltinType::kAcos, CallParamType::kF16, "acos"},
|
||||
BuiltinData{BuiltinType::kAsin, CallParamType::kF32, "asin"},
|
||||
BuiltinData{BuiltinType::kAsin, CallParamType::kF16, "asin"},
|
||||
BuiltinData{BuiltinType::kAtan, CallParamType::kF32, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan, CallParamType::kF16, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan2, CallParamType::kF32, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan2, CallParamType::kF16, "atan"},
|
||||
BuiltinData{BuiltinType::kCeil, CallParamType::kF32, "ceil"},
|
||||
BuiltinData{BuiltinType::kCeil, CallParamType::kF16, "ceil"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kF32, "clamp"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kF16, "clamp"},
|
||||
BuiltinData{BuiltinType::kCos, CallParamType::kF32, "cos"},
|
||||
BuiltinData{BuiltinType::kCos, CallParamType::kF16, "cos"},
|
||||
BuiltinData{BuiltinType::kCosh, CallParamType::kF32, "cosh"},
|
||||
BuiltinData{BuiltinType::kCosh, CallParamType::kF16, "cosh"},
|
||||
BuiltinData{BuiltinType::kCross, CallParamType::kF32, "cross"},
|
||||
BuiltinData{BuiltinType::kCross, CallParamType::kF16, "cross"},
|
||||
BuiltinData{BuiltinType::kDistance, CallParamType::kF32, "distance"},
|
||||
BuiltinData{BuiltinType::kDistance, CallParamType::kF16, "distance"},
|
||||
BuiltinData{BuiltinType::kExp, CallParamType::kF32, "exp"},
|
||||
BuiltinData{BuiltinType::kExp, CallParamType::kF16, "exp"},
|
||||
BuiltinData{BuiltinType::kExp2, CallParamType::kF32, "exp2"},
|
||||
BuiltinData{BuiltinType::kExp2, CallParamType::kF16, "exp2"},
|
||||
BuiltinData{BuiltinType::kFaceForward, CallParamType::kF32, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFaceForward, CallParamType::kF16, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFloor, CallParamType::kF32, "floor"},
|
||||
BuiltinData{BuiltinType::kFloor, CallParamType::kF16, "floor"},
|
||||
BuiltinData{BuiltinType::kFma, CallParamType::kF32, "fma"},
|
||||
BuiltinData{BuiltinType::kFma, CallParamType::kF16, "fma"},
|
||||
BuiltinData{BuiltinType::kFract, CallParamType::kF32, "fract"},
|
||||
BuiltinData{BuiltinType::kFract, CallParamType::kF16, "fract"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF32, "inversesqrt"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF16, "inversesqrt"},
|
||||
BuiltinData{BuiltinType::kLdexp, CallParamType::kF32, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLdexp, CallParamType::kF16, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLength, CallParamType::kF32, "length"},
|
||||
BuiltinData{BuiltinType::kLength, CallParamType::kF16, "length"},
|
||||
BuiltinData{BuiltinType::kLog, CallParamType::kF32, "log"},
|
||||
BuiltinData{BuiltinType::kLog, CallParamType::kF16, "log"},
|
||||
BuiltinData{BuiltinType::kLog2, CallParamType::kF32, "log2"},
|
||||
BuiltinData{BuiltinType::kLog2, CallParamType::kF16, "log2"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kF32, "max"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kF16, "max"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kF32, "min"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kF16, "min"},
|
||||
BuiltinData{BuiltinType::kMix, CallParamType::kF32, "mix"},
|
||||
BuiltinData{BuiltinType::kMix, CallParamType::kF16, "mix"},
|
||||
BuiltinData{BuiltinType::kNormalize, CallParamType::kF32, "normalize"},
|
||||
BuiltinData{BuiltinType::kNormalize, CallParamType::kF16, "normalize"},
|
||||
BuiltinData{BuiltinType::kPow, CallParamType::kF32, "pow"},
|
||||
BuiltinData{BuiltinType::kPow, CallParamType::kF16, "pow"},
|
||||
BuiltinData{BuiltinType::kReflect, CallParamType::kF32, "reflect"},
|
||||
BuiltinData{BuiltinType::kReflect, CallParamType::kF16, "reflect"},
|
||||
BuiltinData{BuiltinType::kSign, CallParamType::kF32, "sign"},
|
||||
BuiltinData{BuiltinType::kSign, CallParamType::kF16, "sign"},
|
||||
BuiltinData{BuiltinType::kSin, CallParamType::kF32, "sin"},
|
||||
BuiltinData{BuiltinType::kSin, CallParamType::kF16, "sin"},
|
||||
BuiltinData{BuiltinType::kSinh, CallParamType::kF32, "sinh"},
|
||||
BuiltinData{BuiltinType::kSinh, CallParamType::kF16, "sinh"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF32, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF16, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSqrt, CallParamType::kF32, "sqrt"},
|
||||
BuiltinData{BuiltinType::kSqrt, CallParamType::kF16, "sqrt"},
|
||||
BuiltinData{BuiltinType::kStep, CallParamType::kF32, "step"},
|
||||
BuiltinData{BuiltinType::kStep, CallParamType::kF16, "step"},
|
||||
BuiltinData{BuiltinType::kTan, CallParamType::kF32, "tan"},
|
||||
BuiltinData{BuiltinType::kTan, CallParamType::kF16, "tan"},
|
||||
BuiltinData{BuiltinType::kTanh, CallParamType::kF32, "tanh"},
|
||||
BuiltinData{BuiltinType::kTanh, CallParamType::kF16, "tanh"},
|
||||
BuiltinData{BuiltinType::kTrunc, CallParamType::kF32, "trunc"},
|
||||
BuiltinData{BuiltinType::kTrunc, CallParamType::kF16, "trunc"},
|
||||
/* Integer built-in */
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kU32, "abs"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kU32, "clamp"},
|
||||
BuiltinData{BuiltinType::kCountOneBits, CallParamType::kU32, "bitCount"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kU32, "max"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kU32, "min"},
|
||||
BuiltinData{BuiltinType::kReverseBits, CallParamType::kU32, "bitfieldReverse"},
|
||||
BuiltinData{BuiltinType::kRound, CallParamType::kU32, "round"},
|
||||
/* Matrix built-in */
|
||||
BuiltinData{BuiltinType::kDeterminant, CallParamType::kF32, "determinant"},
|
||||
BuiltinData{BuiltinType::kDeterminant, CallParamType::kF16, "determinant"},
|
||||
BuiltinData{BuiltinType::kTranspose, CallParamType::kF32, "transpose"},
|
||||
BuiltinData{BuiltinType::kTranspose, CallParamType::kF16, "transpose"},
|
||||
/* Vector built-in */
|
||||
BuiltinData{BuiltinType::kDot, CallParamType::kF32, "dot"},
|
||||
BuiltinData{BuiltinType::kDot, CallParamType::kF16, "dot"},
|
||||
/* Derivate built-in */
|
||||
BuiltinData{BuiltinType::kDpdx, CallParamType::kF32, "dFdx"},
|
||||
BuiltinData{BuiltinType::kDpdxCoarse, CallParamType::kF32, "dFdx"},
|
||||
BuiltinData{BuiltinType::kDpdxFine, CallParamType::kF32, "dFdx"},
|
||||
BuiltinData{BuiltinType::kDpdy, CallParamType::kF32, "dFdy"},
|
||||
BuiltinData{BuiltinType::kDpdyCoarse, CallParamType::kF32, "dFdy"},
|
||||
BuiltinData{BuiltinType::kDpdyFine, CallParamType::kF32, "dFdy"},
|
||||
BuiltinData{BuiltinType::kFwidth, CallParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthCoarse, CallParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthFine, CallParamType::kF32, "fwidth"}));
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Builtin_Call) {
|
||||
auto* call = Call("dot", "param1", "param2");
|
||||
|
@ -277,6 +374,41 @@ TEST_F(GlslGeneratorImplTest_Builtin, Select_Vector) {
|
|||
EXPECT_EQ(out.str(), "mix(ivec2(1, 2), ivec2(3, 4), bvec2(true, false))");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, FMA_f32) {
|
||||
auto* call = Call("fma", "a", "b", "c");
|
||||
|
||||
GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("c", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
|
||||
WrapInFunction(CallStmt(call));
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
gen.increment_indent();
|
||||
std::stringstream out;
|
||||
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
|
||||
EXPECT_EQ(out.str(), "((a) * (b) + (c))");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, FMA_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
GlobalVar("a", ty.vec3<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("b", ty.vec3<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("c", ty.vec3<f16>(), ast::StorageClass::kPrivate);
|
||||
|
||||
auto* call = Call("fma", "a", "b", "c");
|
||||
WrapInFunction(CallStmt(call));
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
gen.increment_indent();
|
||||
std::stringstream out;
|
||||
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
|
||||
EXPECT_EQ(out.str(), "((a) * (b) + (c))");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Modf_Scalar) {
|
||||
auto* call = Call("modf", 1_f);
|
||||
WrapInFunction(CallStmt(call));
|
||||
|
@ -402,7 +534,7 @@ void main() {
|
|||
)"));
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar) {
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar_f32) {
|
||||
auto* val = Var("val", ty.f32());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
@ -413,7 +545,7 @@ TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar) {
|
|||
EXPECT_EQ(gen.result(), R"(#version 310 es
|
||||
|
||||
float tint_degrees(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -430,7 +562,7 @@ void main() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Vector) {
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Vector_f32) {
|
||||
auto* val = Var("val", ty.vec3<f32>());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
@ -441,7 +573,7 @@ TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Vector) {
|
|||
EXPECT_EQ(gen.result(), R"(#version 310 es
|
||||
|
||||
vec3 tint_degrees(vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -458,7 +590,69 @@ void main() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Radians_Scalar) {
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.f16());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#version 310 es
|
||||
#extension GL_AMD_gpu_shader_half_float : require
|
||||
|
||||
float16_t tint_degrees(float16_t param_0) {
|
||||
return param_0 * 57.295779513082322865hf;
|
||||
}
|
||||
|
||||
|
||||
void test_function() {
|
||||
float16_t val = 0.0hf;
|
||||
float16_t tint_symbol = tint_degrees(val);
|
||||
}
|
||||
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
void main() {
|
||||
test_function();
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Degrees_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.vec3<f16>());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#version 310 es
|
||||
#extension GL_AMD_gpu_shader_half_float : require
|
||||
|
||||
f16vec3 tint_degrees(f16vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865hf;
|
||||
}
|
||||
|
||||
|
||||
void test_function() {
|
||||
f16vec3 val = f16vec3(0.0hf, 0.0hf, 0.0hf);
|
||||
f16vec3 tint_symbol = tint_degrees(val);
|
||||
}
|
||||
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
void main() {
|
||||
test_function();
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Radians_Scalar_f32) {
|
||||
auto* val = Var("val", ty.f32());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
@ -469,7 +663,7 @@ TEST_F(GlslGeneratorImplTest_Builtin, Radians_Scalar) {
|
|||
EXPECT_EQ(gen.result(), R"(#version 310 es
|
||||
|
||||
float tint_radians(float param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -486,7 +680,7 @@ void main() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Radians_Vector) {
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Radians_Vector_f32) {
|
||||
auto* val = Var("val", ty.vec3<f32>());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
@ -497,7 +691,7 @@ TEST_F(GlslGeneratorImplTest_Builtin, Radians_Vector) {
|
|||
EXPECT_EQ(gen.result(), R"(#version 310 es
|
||||
|
||||
vec3 tint_radians(vec3 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -514,6 +708,68 @@ void main() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Radians_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.f16());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#version 310 es
|
||||
#extension GL_AMD_gpu_shader_half_float : require
|
||||
|
||||
float16_t tint_radians(float16_t param_0) {
|
||||
return param_0 * 0.017453292519943295474hf;
|
||||
}
|
||||
|
||||
|
||||
void test_function() {
|
||||
float16_t val = 0.0hf;
|
||||
float16_t tint_symbol = tint_radians(val);
|
||||
}
|
||||
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
void main() {
|
||||
test_function();
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, Radians_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.vec3<f16>());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#version 310 es
|
||||
#extension GL_AMD_gpu_shader_half_float : require
|
||||
|
||||
f16vec3 tint_radians(f16vec3 param_0) {
|
||||
return param_0 * 0.017453292519943295474hf;
|
||||
}
|
||||
|
||||
|
||||
void test_function() {
|
||||
f16vec3 val = f16vec3(0.0hf, 0.0hf, 0.0hf);
|
||||
f16vec3 tint_symbol = tint_radians(val);
|
||||
}
|
||||
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
void main() {
|
||||
test_function();
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, ExtractBits) {
|
||||
auto* v = Var("v", ty.vec3<u32>());
|
||||
auto* offset = Var("offset", ty.u32());
|
||||
|
@ -828,23 +1084,6 @@ void main() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, FMA) {
|
||||
auto* call = Call("fma", "a", "b", "c");
|
||||
|
||||
GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("c", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
|
||||
WrapInFunction(CallStmt(call));
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
|
||||
gen.increment_indent();
|
||||
std::stringstream out;
|
||||
ASSERT_TRUE(gen.EmitExpression(out, call)) << gen.error();
|
||||
EXPECT_EQ(out.str(), "((a) * (b) + (c))");
|
||||
}
|
||||
|
||||
TEST_F(GlslGeneratorImplTest_Builtin, DotU32) {
|
||||
GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
|
||||
WrapInFunction(CallStmt(Call("dot", "v", "v")));
|
||||
|
|
|
@ -28,36 +28,40 @@ namespace {
|
|||
using BuiltinType = sem::BuiltinType;
|
||||
using HlslGeneratorImplTest_Builtin = TestHelper;
|
||||
|
||||
enum class ParamType {
|
||||
enum class CallParamType {
|
||||
kF32,
|
||||
kU32,
|
||||
kBool,
|
||||
kF16,
|
||||
};
|
||||
|
||||
struct BuiltinData {
|
||||
BuiltinType builtin;
|
||||
ParamType type;
|
||||
CallParamType type;
|
||||
const char* hlsl_name;
|
||||
};
|
||||
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
|
||||
out << data.hlsl_name;
|
||||
out << data.hlsl_name << "<";
|
||||
switch (data.type) {
|
||||
case ParamType::kF32:
|
||||
case CallParamType::kF32:
|
||||
out << "f32";
|
||||
break;
|
||||
case ParamType::kU32:
|
||||
case CallParamType::kU32:
|
||||
out << "u32";
|
||||
break;
|
||||
case ParamType::kBool:
|
||||
case CallParamType::kBool:
|
||||
out << "bool";
|
||||
break;
|
||||
case CallParamType::kF16:
|
||||
out << "f16";
|
||||
break;
|
||||
}
|
||||
out << ">";
|
||||
return out;
|
||||
}
|
||||
|
||||
const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
||||
ParamType type,
|
||||
CallParamType type,
|
||||
ProgramBuilder* builder) {
|
||||
std::string name;
|
||||
std::ostringstream str(name);
|
||||
|
@ -95,29 +99,51 @@ const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
|||
case BuiltinType::kTanh:
|
||||
case BuiltinType::kTrunc:
|
||||
case BuiltinType::kSign:
|
||||
return builder->Call(str.str(), "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2");
|
||||
}
|
||||
case BuiltinType::kLdexp:
|
||||
return builder->Call(str.str(), "f2", "i2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "i2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "i2");
|
||||
}
|
||||
case BuiltinType::kAtan2:
|
||||
case BuiltinType::kDot:
|
||||
case BuiltinType::kDistance:
|
||||
case BuiltinType::kPow:
|
||||
case BuiltinType::kReflect:
|
||||
case BuiltinType::kStep:
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
}
|
||||
case BuiltinType::kCross:
|
||||
return builder->Call(str.str(), "f3", "f3");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h3", "h3");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f3", "f3");
|
||||
}
|
||||
case BuiltinType::kFma:
|
||||
case BuiltinType::kMix:
|
||||
case BuiltinType::kFaceForward:
|
||||
case BuiltinType::kSmoothstep:
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
}
|
||||
case BuiltinType::kAll:
|
||||
case BuiltinType::kAny:
|
||||
return builder->Call(str.str(), "b2");
|
||||
case BuiltinType::kAbs:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2");
|
||||
}
|
||||
|
@ -126,32 +152,58 @@ const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
|||
return builder->Call(str.str(), "u2");
|
||||
case BuiltinType::kMax:
|
||||
case BuiltinType::kMin:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2", "u2");
|
||||
}
|
||||
case BuiltinType::kClamp:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2", "u2", "u2");
|
||||
}
|
||||
case BuiltinType::kSelect:
|
||||
return builder->Call(str.str(), "f2", "f2", "b2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "b2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2", "b2");
|
||||
}
|
||||
case BuiltinType::kDeterminant:
|
||||
return builder->Call(str.str(), "m2x2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "hm2x2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "m2x2");
|
||||
}
|
||||
case BuiltinType::kTranspose:
|
||||
return builder->Call(str.str(), "m3x2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "hm3x2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "m3x2");
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
using HlslBuiltinTest = TestParamHelper<BuiltinData>;
|
||||
TEST_P(HlslBuiltinTest, Emit) {
|
||||
auto param = GetParam();
|
||||
|
||||
if (param.type == CallParamType::kF16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
|
||||
}
|
||||
|
||||
GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
|
||||
|
@ -179,64 +231,110 @@ TEST_P(HlslBuiltinTest, Emit) {
|
|||
INSTANTIATE_TEST_SUITE_P(
|
||||
HlslGeneratorImplTest_Builtin,
|
||||
HlslBuiltinTest,
|
||||
testing::Values(BuiltinData{BuiltinType::kAbs, ParamType::kF32, "abs"},
|
||||
BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
|
||||
BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
|
||||
BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
|
||||
BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
|
||||
BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
|
||||
BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan2"},
|
||||
BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
|
||||
BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
|
||||
BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
|
||||
BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
|
||||
BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
|
||||
BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "countbits"},
|
||||
BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
|
||||
BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
|
||||
BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
|
||||
BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
|
||||
BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "ddx"},
|
||||
BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "ddx_coarse"},
|
||||
BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "ddx_fine"},
|
||||
BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "ddy"},
|
||||
BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "ddy_coarse"},
|
||||
BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "ddy_fine"},
|
||||
BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
|
||||
BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
|
||||
BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
|
||||
BuiltinData{BuiltinType::kFma, ParamType::kF32, "mad"},
|
||||
BuiltinData{BuiltinType::kFract, ParamType::kF32, "frac"},
|
||||
BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "rsqrt"},
|
||||
BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
|
||||
BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
|
||||
BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
|
||||
BuiltinData{BuiltinType::kMax, ParamType::kF32, "max"},
|
||||
BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
|
||||
BuiltinData{BuiltinType::kMin, ParamType::kF32, "min"},
|
||||
BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
|
||||
BuiltinData{BuiltinType::kMix, ParamType::kF32, "lerp"},
|
||||
BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
|
||||
BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
|
||||
BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
|
||||
BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "reversebits"},
|
||||
BuiltinData{BuiltinType::kRound, ParamType::kU32, "round"},
|
||||
BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
|
||||
BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
|
||||
BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, ParamType::kF32, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
|
||||
BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
|
||||
BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
|
||||
BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
|
||||
BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
|
||||
BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"}));
|
||||
testing::Values(/* Logical built-in */
|
||||
BuiltinData{BuiltinType::kAll, CallParamType::kBool, "all"},
|
||||
BuiltinData{BuiltinType::kAny, CallParamType::kBool, "any"},
|
||||
/* Float built-in */
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kF32, "abs"},
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kF16, "abs"},
|
||||
BuiltinData{BuiltinType::kAcos, CallParamType::kF32, "acos"},
|
||||
BuiltinData{BuiltinType::kAcos, CallParamType::kF16, "acos"},
|
||||
BuiltinData{BuiltinType::kAsin, CallParamType::kF32, "asin"},
|
||||
BuiltinData{BuiltinType::kAsin, CallParamType::kF16, "asin"},
|
||||
BuiltinData{BuiltinType::kAtan, CallParamType::kF32, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan, CallParamType::kF16, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan2, CallParamType::kF32, "atan2"},
|
||||
BuiltinData{BuiltinType::kAtan2, CallParamType::kF16, "atan2"},
|
||||
BuiltinData{BuiltinType::kCeil, CallParamType::kF32, "ceil"},
|
||||
BuiltinData{BuiltinType::kCeil, CallParamType::kF16, "ceil"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kF32, "clamp"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kF16, "clamp"},
|
||||
BuiltinData{BuiltinType::kCos, CallParamType::kF32, "cos"},
|
||||
BuiltinData{BuiltinType::kCos, CallParamType::kF16, "cos"},
|
||||
BuiltinData{BuiltinType::kCosh, CallParamType::kF32, "cosh"},
|
||||
BuiltinData{BuiltinType::kCosh, CallParamType::kF16, "cosh"},
|
||||
BuiltinData{BuiltinType::kCross, CallParamType::kF32, "cross"},
|
||||
BuiltinData{BuiltinType::kCross, CallParamType::kF16, "cross"},
|
||||
BuiltinData{BuiltinType::kDistance, CallParamType::kF32, "distance"},
|
||||
BuiltinData{BuiltinType::kDistance, CallParamType::kF16, "distance"},
|
||||
BuiltinData{BuiltinType::kExp, CallParamType::kF32, "exp"},
|
||||
BuiltinData{BuiltinType::kExp, CallParamType::kF16, "exp"},
|
||||
BuiltinData{BuiltinType::kExp2, CallParamType::kF32, "exp2"},
|
||||
BuiltinData{BuiltinType::kExp2, CallParamType::kF16, "exp2"},
|
||||
BuiltinData{BuiltinType::kFaceForward, CallParamType::kF32, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFaceForward, CallParamType::kF16, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFloor, CallParamType::kF32, "floor"},
|
||||
BuiltinData{BuiltinType::kFloor, CallParamType::kF16, "floor"},
|
||||
BuiltinData{BuiltinType::kFma, CallParamType::kF32, "mad"},
|
||||
BuiltinData{BuiltinType::kFma, CallParamType::kF16, "mad"},
|
||||
BuiltinData{BuiltinType::kFract, CallParamType::kF32, "frac"},
|
||||
BuiltinData{BuiltinType::kFract, CallParamType::kF16, "frac"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF32, "rsqrt"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF16, "rsqrt"},
|
||||
BuiltinData{BuiltinType::kLdexp, CallParamType::kF32, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLdexp, CallParamType::kF16, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLength, CallParamType::kF32, "length"},
|
||||
BuiltinData{BuiltinType::kLength, CallParamType::kF16, "length"},
|
||||
BuiltinData{BuiltinType::kLog, CallParamType::kF32, "log"},
|
||||
BuiltinData{BuiltinType::kLog, CallParamType::kF16, "log"},
|
||||
BuiltinData{BuiltinType::kLog2, CallParamType::kF32, "log2"},
|
||||
BuiltinData{BuiltinType::kLog2, CallParamType::kF16, "log2"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kF32, "max"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kF16, "max"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kF32, "min"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kF16, "min"},
|
||||
BuiltinData{BuiltinType::kMix, CallParamType::kF32, "lerp"},
|
||||
BuiltinData{BuiltinType::kMix, CallParamType::kF16, "lerp"},
|
||||
BuiltinData{BuiltinType::kNormalize, CallParamType::kF32, "normalize"},
|
||||
BuiltinData{BuiltinType::kNormalize, CallParamType::kF16, "normalize"},
|
||||
BuiltinData{BuiltinType::kPow, CallParamType::kF32, "pow"},
|
||||
BuiltinData{BuiltinType::kPow, CallParamType::kF16, "pow"},
|
||||
BuiltinData{BuiltinType::kReflect, CallParamType::kF32, "reflect"},
|
||||
BuiltinData{BuiltinType::kReflect, CallParamType::kF16, "reflect"},
|
||||
BuiltinData{BuiltinType::kSign, CallParamType::kF32, "sign"},
|
||||
BuiltinData{BuiltinType::kSign, CallParamType::kF16, "sign"},
|
||||
BuiltinData{BuiltinType::kSin, CallParamType::kF32, "sin"},
|
||||
BuiltinData{BuiltinType::kSin, CallParamType::kF16, "sin"},
|
||||
BuiltinData{BuiltinType::kSinh, CallParamType::kF32, "sinh"},
|
||||
BuiltinData{BuiltinType::kSinh, CallParamType::kF16, "sinh"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF32, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF16, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSqrt, CallParamType::kF32, "sqrt"},
|
||||
BuiltinData{BuiltinType::kSqrt, CallParamType::kF16, "sqrt"},
|
||||
BuiltinData{BuiltinType::kStep, CallParamType::kF32, "step"},
|
||||
BuiltinData{BuiltinType::kStep, CallParamType::kF16, "step"},
|
||||
BuiltinData{BuiltinType::kTan, CallParamType::kF32, "tan"},
|
||||
BuiltinData{BuiltinType::kTan, CallParamType::kF16, "tan"},
|
||||
BuiltinData{BuiltinType::kTanh, CallParamType::kF32, "tanh"},
|
||||
BuiltinData{BuiltinType::kTanh, CallParamType::kF16, "tanh"},
|
||||
BuiltinData{BuiltinType::kTrunc, CallParamType::kF32, "trunc"},
|
||||
BuiltinData{BuiltinType::kTrunc, CallParamType::kF16, "trunc"},
|
||||
/* Integer built-in */
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kU32, "abs"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kU32, "clamp"},
|
||||
BuiltinData{BuiltinType::kCountOneBits, CallParamType::kU32, "countbits"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kU32, "max"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kU32, "min"},
|
||||
BuiltinData{BuiltinType::kReverseBits, CallParamType::kU32, "reversebits"},
|
||||
BuiltinData{BuiltinType::kRound, CallParamType::kU32, "round"},
|
||||
/* Matrix built-in */
|
||||
BuiltinData{BuiltinType::kDeterminant, CallParamType::kF32, "determinant"},
|
||||
BuiltinData{BuiltinType::kDeterminant, CallParamType::kF16, "determinant"},
|
||||
BuiltinData{BuiltinType::kTranspose, CallParamType::kF32, "transpose"},
|
||||
BuiltinData{BuiltinType::kTranspose, CallParamType::kF16, "transpose"},
|
||||
/* Vector built-in */
|
||||
BuiltinData{BuiltinType::kDot, CallParamType::kF32, "dot"},
|
||||
BuiltinData{BuiltinType::kDot, CallParamType::kF16, "dot"},
|
||||
/* Derivate built-in */
|
||||
BuiltinData{BuiltinType::kDpdx, CallParamType::kF32, "ddx"},
|
||||
BuiltinData{BuiltinType::kDpdxCoarse, CallParamType::kF32, "ddx_coarse"},
|
||||
BuiltinData{BuiltinType::kDpdxFine, CallParamType::kF32, "ddx_fine"},
|
||||
BuiltinData{BuiltinType::kDpdy, CallParamType::kF32, "ddy"},
|
||||
BuiltinData{BuiltinType::kDpdyCoarse, CallParamType::kF32, "ddy_coarse"},
|
||||
BuiltinData{BuiltinType::kDpdyFine, CallParamType::kF32, "ddy_fine"},
|
||||
BuiltinData{BuiltinType::kFwidth, CallParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthCoarse, CallParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthFine, CallParamType::kF32, "fwidth"}));
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Builtin_Call) {
|
||||
auto* call = Call("dot", "param1", "param2");
|
||||
|
@ -380,7 +478,7 @@ void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Scalar) {
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Scalar_f32) {
|
||||
auto* val = Var("val", ty.f32());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
@ -401,7 +499,7 @@ void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Vector) {
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Vector_f32) {
|
||||
auto* val = Var("val", ty.vec3<f32>());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
@ -422,7 +520,53 @@ void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Radians_Scalar) {
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.f16());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(float16_t tint_degrees(float16_t param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void test_function() {
|
||||
float16_t val = float16_t(0.0h);
|
||||
const float16_t tint_symbol = tint_degrees(val);
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Degrees_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.vec3<f16>());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(vector<float16_t, 3> tint_degrees(vector<float16_t, 3> param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void test_function() {
|
||||
vector<float16_t, 3> val = vector<float16_t, 3>(float16_t(0.0h), float16_t(0.0h), float16_t(0.0h));
|
||||
const vector<float16_t, 3> tint_symbol = tint_degrees(val);
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Radians_Scalar_f32) {
|
||||
auto* val = Var("val", ty.f32());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
@ -443,7 +587,7 @@ void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Radians_Vector) {
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Radians_Vector_f32) {
|
||||
auto* val = Var("val", ty.vec3<f32>());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
@ -464,6 +608,52 @@ void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Radians_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.f16());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(float16_t tint_radians(float16_t param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void test_function() {
|
||||
float16_t val = float16_t(0.0h);
|
||||
const float16_t tint_symbol = tint_radians(val);
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Radians_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.vec3<f16>());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(vector<float16_t, 3> tint_radians(vector<float16_t, 3> param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
}
|
||||
|
||||
[numthreads(1, 1, 1)]
|
||||
void test_function() {
|
||||
vector<float16_t, 3> val = vector<float16_t, 3>(float16_t(0.0h), float16_t(0.0h), float16_t(0.0h));
|
||||
const vector<float16_t, 3> tint_symbol = tint_radians(val);
|
||||
return;
|
||||
}
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
|
||||
auto* call = Call("pack4x8snorm", "p1");
|
||||
GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
|
||||
|
|
|
@ -25,36 +25,40 @@ using BuiltinType = sem::BuiltinType;
|
|||
|
||||
using MslGeneratorImplTest = TestHelper;
|
||||
|
||||
enum class ParamType {
|
||||
enum class CallParamType {
|
||||
kF32,
|
||||
kU32,
|
||||
kBool,
|
||||
kF16,
|
||||
};
|
||||
|
||||
struct BuiltinData {
|
||||
BuiltinType builtin;
|
||||
ParamType type;
|
||||
CallParamType type;
|
||||
const char* msl_name;
|
||||
};
|
||||
inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
|
||||
out << data.msl_name << "<";
|
||||
switch (data.type) {
|
||||
case ParamType::kF32:
|
||||
case CallParamType::kF32:
|
||||
out << "f32";
|
||||
break;
|
||||
case ParamType::kU32:
|
||||
case CallParamType::kU32:
|
||||
out << "u32";
|
||||
break;
|
||||
case ParamType::kBool:
|
||||
case CallParamType::kBool:
|
||||
out << "bool";
|
||||
break;
|
||||
case CallParamType::kF16:
|
||||
out << "f16";
|
||||
break;
|
||||
}
|
||||
out << ">";
|
||||
return out;
|
||||
}
|
||||
|
||||
const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
||||
ParamType type,
|
||||
CallParamType type,
|
||||
ProgramBuilder* builder) {
|
||||
std::string name;
|
||||
std::ostringstream str(name);
|
||||
|
@ -92,31 +96,53 @@ const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
|||
case BuiltinType::kTanh:
|
||||
case BuiltinType::kTrunc:
|
||||
case BuiltinType::kSign:
|
||||
return builder->Call(str.str(), "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2");
|
||||
}
|
||||
case BuiltinType::kLdexp:
|
||||
return builder->Call(str.str(), "f2", "i2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "i2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "i2");
|
||||
}
|
||||
case BuiltinType::kAtan2:
|
||||
case BuiltinType::kDot:
|
||||
case BuiltinType::kDistance:
|
||||
case BuiltinType::kPow:
|
||||
case BuiltinType::kReflect:
|
||||
case BuiltinType::kStep:
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
}
|
||||
case BuiltinType::kStorageBarrier:
|
||||
return builder->Call(str.str());
|
||||
case BuiltinType::kCross:
|
||||
return builder->Call(str.str(), "f3", "f3");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h3", "h3");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f3", "f3");
|
||||
}
|
||||
case BuiltinType::kFma:
|
||||
case BuiltinType::kMix:
|
||||
case BuiltinType::kFaceForward:
|
||||
case BuiltinType::kSmoothstep:
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
}
|
||||
case BuiltinType::kAll:
|
||||
case BuiltinType::kAny:
|
||||
return builder->Call(str.str(), "b2");
|
||||
case BuiltinType::kAbs:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2");
|
||||
}
|
||||
|
@ -131,21 +157,33 @@ const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
|||
return builder->Call(str.str(), "u2", "u2", "u1", "u1");
|
||||
case BuiltinType::kMax:
|
||||
case BuiltinType::kMin:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2", "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2", "u2");
|
||||
}
|
||||
case BuiltinType::kClamp:
|
||||
if (type == ParamType::kF32) {
|
||||
if (type == CallParamType::kF32) {
|
||||
return builder->Call(str.str(), "f2", "f2", "f2");
|
||||
} else if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "h2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "u2", "u2", "u2");
|
||||
}
|
||||
case BuiltinType::kSelect:
|
||||
return builder->Call(str.str(), "f2", "f2", "b2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "h2", "h2", "b2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "f2", "f2", "b2");
|
||||
}
|
||||
case BuiltinType::kDeterminant:
|
||||
return builder->Call(str.str(), "m2x2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "hm2x2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "m2x2");
|
||||
}
|
||||
case BuiltinType::kPack2x16snorm:
|
||||
case BuiltinType::kPack2x16unorm:
|
||||
return builder->Call(str.str(), "f2");
|
||||
|
@ -160,7 +198,11 @@ const ast::CallExpression* GenerateCall(BuiltinType builtin,
|
|||
case BuiltinType::kWorkgroupBarrier:
|
||||
return builder->Call(str.str());
|
||||
case BuiltinType::kTranspose:
|
||||
return builder->Call(str.str(), "m3x2");
|
||||
if (type == CallParamType::kF16) {
|
||||
return builder->Call(str.str(), "hm3x2");
|
||||
} else {
|
||||
return builder->Call(str.str(), "m3x2");
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -171,6 +213,15 @@ using MslBuiltinTest = TestParamHelper<BuiltinData>;
|
|||
TEST_P(MslBuiltinTest, Emit) {
|
||||
auto param = GetParam();
|
||||
|
||||
if (param.type == CallParamType::kF16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
|
||||
}
|
||||
|
||||
GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
|
||||
GlobalVar("f4", ty.vec4<f32>(), ast::StorageClass::kPrivate);
|
||||
|
@ -201,76 +252,122 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
MslGeneratorImplTest,
|
||||
MslBuiltinTest,
|
||||
testing::Values(
|
||||
BuiltinData{BuiltinType::kAbs, ParamType::kF32, "fabs"},
|
||||
BuiltinData{BuiltinType::kAbs, ParamType::kU32, "abs"},
|
||||
BuiltinData{BuiltinType::kAcos, ParamType::kF32, "acos"},
|
||||
BuiltinData{BuiltinType::kAll, ParamType::kBool, "all"},
|
||||
BuiltinData{BuiltinType::kAny, ParamType::kBool, "any"},
|
||||
BuiltinData{BuiltinType::kAsin, ParamType::kF32, "asin"},
|
||||
BuiltinData{BuiltinType::kAtan, ParamType::kF32, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan2, ParamType::kF32, "atan2"},
|
||||
BuiltinData{BuiltinType::kCeil, ParamType::kF32, "ceil"},
|
||||
BuiltinData{BuiltinType::kClamp, ParamType::kF32, "clamp"},
|
||||
BuiltinData{BuiltinType::kClamp, ParamType::kU32, "clamp"},
|
||||
BuiltinData{BuiltinType::kCos, ParamType::kF32, "cos"},
|
||||
BuiltinData{BuiltinType::kCosh, ParamType::kF32, "cosh"},
|
||||
BuiltinData{BuiltinType::kCountLeadingZeros, ParamType::kU32, "clz"},
|
||||
BuiltinData{BuiltinType::kCountOneBits, ParamType::kU32, "popcount"},
|
||||
BuiltinData{BuiltinType::kCountTrailingZeros, ParamType::kU32, "ctz"},
|
||||
BuiltinData{BuiltinType::kCross, ParamType::kF32, "cross"},
|
||||
BuiltinData{BuiltinType::kDeterminant, ParamType::kF32, "determinant"},
|
||||
BuiltinData{BuiltinType::kDistance, ParamType::kF32, "distance"},
|
||||
BuiltinData{BuiltinType::kDot, ParamType::kF32, "dot"},
|
||||
BuiltinData{BuiltinType::kDpdx, ParamType::kF32, "dfdx"},
|
||||
BuiltinData{BuiltinType::kDpdxCoarse, ParamType::kF32, "dfdx"},
|
||||
BuiltinData{BuiltinType::kDpdxFine, ParamType::kF32, "dfdx"},
|
||||
BuiltinData{BuiltinType::kDpdy, ParamType::kF32, "dfdy"},
|
||||
BuiltinData{BuiltinType::kDpdyCoarse, ParamType::kF32, "dfdy"},
|
||||
BuiltinData{BuiltinType::kDpdyFine, ParamType::kF32, "dfdy"},
|
||||
BuiltinData{BuiltinType::kExp, ParamType::kF32, "exp"},
|
||||
BuiltinData{BuiltinType::kExp2, ParamType::kF32, "exp2"},
|
||||
BuiltinData{BuiltinType::kExtractBits, ParamType::kU32, "extract_bits"},
|
||||
BuiltinData{BuiltinType::kFaceForward, ParamType::kF32, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFloor, ParamType::kF32, "floor"},
|
||||
BuiltinData{BuiltinType::kFma, ParamType::kF32, "fma"},
|
||||
BuiltinData{BuiltinType::kFract, ParamType::kF32, "fract"},
|
||||
BuiltinData{BuiltinType::kFwidth, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthCoarse, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthFine, ParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kInsertBits, ParamType::kU32, "insert_bits"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, ParamType::kF32, "rsqrt"},
|
||||
BuiltinData{BuiltinType::kLdexp, ParamType::kF32, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLength, ParamType::kF32, "length"},
|
||||
BuiltinData{BuiltinType::kLog, ParamType::kF32, "log"},
|
||||
BuiltinData{BuiltinType::kLog2, ParamType::kF32, "log2"},
|
||||
BuiltinData{BuiltinType::kMax, ParamType::kF32, "fmax"},
|
||||
BuiltinData{BuiltinType::kMax, ParamType::kU32, "max"},
|
||||
BuiltinData{BuiltinType::kMin, ParamType::kF32, "fmin"},
|
||||
BuiltinData{BuiltinType::kMin, ParamType::kU32, "min"},
|
||||
BuiltinData{BuiltinType::kNormalize, ParamType::kF32, "normalize"},
|
||||
BuiltinData{BuiltinType::kPack4x8snorm, ParamType::kF32, "pack_float_to_snorm4x8"},
|
||||
BuiltinData{BuiltinType::kPack4x8unorm, ParamType::kF32, "pack_float_to_unorm4x8"},
|
||||
BuiltinData{BuiltinType::kPack2x16snorm, ParamType::kF32, "pack_float_to_snorm2x16"},
|
||||
BuiltinData{BuiltinType::kPack2x16unorm, ParamType::kF32, "pack_float_to_unorm2x16"},
|
||||
BuiltinData{BuiltinType::kPow, ParamType::kF32, "pow"},
|
||||
BuiltinData{BuiltinType::kReflect, ParamType::kF32, "reflect"},
|
||||
BuiltinData{BuiltinType::kReverseBits, ParamType::kU32, "reverse_bits"},
|
||||
BuiltinData{BuiltinType::kRound, ParamType::kU32, "rint"},
|
||||
BuiltinData{BuiltinType::kSelect, ParamType::kF32, "select"},
|
||||
BuiltinData{BuiltinType::kSign, ParamType::kF32, "sign"},
|
||||
BuiltinData{BuiltinType::kSin, ParamType::kF32, "sin"},
|
||||
BuiltinData{BuiltinType::kSinh, ParamType::kF32, "sinh"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, ParamType::kF32, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSqrt, ParamType::kF32, "sqrt"},
|
||||
BuiltinData{BuiltinType::kStep, ParamType::kF32, "step"},
|
||||
BuiltinData{BuiltinType::kTan, ParamType::kF32, "tan"},
|
||||
BuiltinData{BuiltinType::kTanh, ParamType::kF32, "tanh"},
|
||||
BuiltinData{BuiltinType::kTranspose, ParamType::kF32, "transpose"},
|
||||
BuiltinData{BuiltinType::kTrunc, ParamType::kF32, "trunc"},
|
||||
BuiltinData{BuiltinType::kUnpack4x8snorm, ParamType::kU32, "unpack_snorm4x8_to_float"},
|
||||
BuiltinData{BuiltinType::kUnpack4x8unorm, ParamType::kU32, "unpack_unorm4x8_to_float"},
|
||||
BuiltinData{BuiltinType::kUnpack2x16snorm, ParamType::kU32, "unpack_snorm2x16_to_float"},
|
||||
BuiltinData{BuiltinType::kUnpack2x16unorm, ParamType::kU32, "unpack_unorm2x16_to_float"}));
|
||||
/* Logical built-in */
|
||||
BuiltinData{BuiltinType::kAll, CallParamType::kBool, "all"},
|
||||
BuiltinData{BuiltinType::kAny, CallParamType::kBool, "any"},
|
||||
BuiltinData{BuiltinType::kSelect, CallParamType::kF32, "select"},
|
||||
/* Float built-in */
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kF32, "fabs"},
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kF16, "fabs"},
|
||||
BuiltinData{BuiltinType::kAcos, CallParamType::kF32, "acos"},
|
||||
BuiltinData{BuiltinType::kAcos, CallParamType::kF16, "acos"},
|
||||
BuiltinData{BuiltinType::kAsin, CallParamType::kF32, "asin"},
|
||||
BuiltinData{BuiltinType::kAsin, CallParamType::kF16, "asin"},
|
||||
BuiltinData{BuiltinType::kAtan, CallParamType::kF32, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan, CallParamType::kF16, "atan"},
|
||||
BuiltinData{BuiltinType::kAtan2, CallParamType::kF32, "atan2"},
|
||||
BuiltinData{BuiltinType::kAtan2, CallParamType::kF16, "atan2"},
|
||||
BuiltinData{BuiltinType::kCeil, CallParamType::kF32, "ceil"},
|
||||
BuiltinData{BuiltinType::kCeil, CallParamType::kF16, "ceil"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kF32, "clamp"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kF16, "clamp"},
|
||||
BuiltinData{BuiltinType::kCos, CallParamType::kF32, "cos"},
|
||||
BuiltinData{BuiltinType::kCos, CallParamType::kF16, "cos"},
|
||||
BuiltinData{BuiltinType::kCosh, CallParamType::kF32, "cosh"},
|
||||
BuiltinData{BuiltinType::kCosh, CallParamType::kF16, "cosh"},
|
||||
BuiltinData{BuiltinType::kCross, CallParamType::kF32, "cross"},
|
||||
BuiltinData{BuiltinType::kCross, CallParamType::kF16, "cross"},
|
||||
BuiltinData{BuiltinType::kDistance, CallParamType::kF32, "distance"},
|
||||
BuiltinData{BuiltinType::kDistance, CallParamType::kF16, "distance"},
|
||||
BuiltinData{BuiltinType::kExp, CallParamType::kF32, "exp"},
|
||||
BuiltinData{BuiltinType::kExp, CallParamType::kF16, "exp"},
|
||||
BuiltinData{BuiltinType::kExp2, CallParamType::kF32, "exp2"},
|
||||
BuiltinData{BuiltinType::kExp2, CallParamType::kF16, "exp2"},
|
||||
BuiltinData{BuiltinType::kFaceForward, CallParamType::kF32, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFaceForward, CallParamType::kF16, "faceforward"},
|
||||
BuiltinData{BuiltinType::kFloor, CallParamType::kF32, "floor"},
|
||||
BuiltinData{BuiltinType::kFloor, CallParamType::kF16, "floor"},
|
||||
BuiltinData{BuiltinType::kFma, CallParamType::kF32, "fma"},
|
||||
BuiltinData{BuiltinType::kFma, CallParamType::kF16, "fma"},
|
||||
BuiltinData{BuiltinType::kFract, CallParamType::kF32, "fract"},
|
||||
BuiltinData{BuiltinType::kFract, CallParamType::kF16, "fract"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF32, "rsqrt"},
|
||||
BuiltinData{BuiltinType::kInverseSqrt, CallParamType::kF16, "rsqrt"},
|
||||
BuiltinData{BuiltinType::kLdexp, CallParamType::kF32, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLdexp, CallParamType::kF16, "ldexp"},
|
||||
BuiltinData{BuiltinType::kLength, CallParamType::kF32, "length"},
|
||||
BuiltinData{BuiltinType::kLength, CallParamType::kF16, "length"},
|
||||
BuiltinData{BuiltinType::kLog, CallParamType::kF32, "log"},
|
||||
BuiltinData{BuiltinType::kLog, CallParamType::kF16, "log"},
|
||||
BuiltinData{BuiltinType::kLog2, CallParamType::kF32, "log2"},
|
||||
BuiltinData{BuiltinType::kLog2, CallParamType::kF16, "log2"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kF32, "fmax"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kF16, "fmax"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kF32, "fmin"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kF16, "fmin"},
|
||||
BuiltinData{BuiltinType::kNormalize, CallParamType::kF32, "normalize"},
|
||||
BuiltinData{BuiltinType::kNormalize, CallParamType::kF16, "normalize"},
|
||||
BuiltinData{BuiltinType::kPow, CallParamType::kF32, "pow"},
|
||||
BuiltinData{BuiltinType::kPow, CallParamType::kF16, "pow"},
|
||||
BuiltinData{BuiltinType::kReflect, CallParamType::kF32, "reflect"},
|
||||
BuiltinData{BuiltinType::kReflect, CallParamType::kF16, "reflect"},
|
||||
BuiltinData{BuiltinType::kSign, CallParamType::kF32, "sign"},
|
||||
BuiltinData{BuiltinType::kSign, CallParamType::kF16, "sign"},
|
||||
BuiltinData{BuiltinType::kSin, CallParamType::kF32, "sin"},
|
||||
BuiltinData{BuiltinType::kSin, CallParamType::kF16, "sin"},
|
||||
BuiltinData{BuiltinType::kSinh, CallParamType::kF32, "sinh"},
|
||||
BuiltinData{BuiltinType::kSinh, CallParamType::kF16, "sinh"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF32, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSmoothstep, CallParamType::kF16, "smoothstep"},
|
||||
BuiltinData{BuiltinType::kSqrt, CallParamType::kF32, "sqrt"},
|
||||
BuiltinData{BuiltinType::kSqrt, CallParamType::kF16, "sqrt"},
|
||||
BuiltinData{BuiltinType::kStep, CallParamType::kF32, "step"},
|
||||
BuiltinData{BuiltinType::kStep, CallParamType::kF16, "step"},
|
||||
BuiltinData{BuiltinType::kTan, CallParamType::kF32, "tan"},
|
||||
BuiltinData{BuiltinType::kTan, CallParamType::kF16, "tan"},
|
||||
BuiltinData{BuiltinType::kTanh, CallParamType::kF32, "tanh"},
|
||||
BuiltinData{BuiltinType::kTanh, CallParamType::kF16, "tanh"},
|
||||
BuiltinData{BuiltinType::kTrunc, CallParamType::kF32, "trunc"},
|
||||
BuiltinData{BuiltinType::kTrunc, CallParamType::kF16, "trunc"},
|
||||
/* Integer built-in */
|
||||
BuiltinData{BuiltinType::kAbs, CallParamType::kU32, "abs"},
|
||||
BuiltinData{BuiltinType::kClamp, CallParamType::kU32, "clamp"},
|
||||
BuiltinData{BuiltinType::kCountLeadingZeros, CallParamType::kU32, "clz"},
|
||||
BuiltinData{BuiltinType::kCountOneBits, CallParamType::kU32, "popcount"},
|
||||
BuiltinData{BuiltinType::kCountTrailingZeros, CallParamType::kU32, "ctz"},
|
||||
BuiltinData{BuiltinType::kExtractBits, CallParamType::kU32, "extract_bits"},
|
||||
BuiltinData{BuiltinType::kInsertBits, CallParamType::kU32, "insert_bits"},
|
||||
BuiltinData{BuiltinType::kMax, CallParamType::kU32, "max"},
|
||||
BuiltinData{BuiltinType::kMin, CallParamType::kU32, "min"},
|
||||
BuiltinData{BuiltinType::kReverseBits, CallParamType::kU32, "reverse_bits"},
|
||||
BuiltinData{BuiltinType::kRound, CallParamType::kU32, "rint"},
|
||||
/* Matrix built-in */
|
||||
BuiltinData{BuiltinType::kDeterminant, CallParamType::kF32, "determinant"},
|
||||
BuiltinData{BuiltinType::kTranspose, CallParamType::kF32, "transpose"},
|
||||
/* Vector built-in */
|
||||
BuiltinData{BuiltinType::kDot, CallParamType::kF32, "dot"},
|
||||
/* Derivate built-in */
|
||||
BuiltinData{BuiltinType::kDpdx, CallParamType::kF32, "dfdx"},
|
||||
BuiltinData{BuiltinType::kDpdxCoarse, CallParamType::kF32, "dfdx"},
|
||||
BuiltinData{BuiltinType::kDpdxFine, CallParamType::kF32, "dfdx"},
|
||||
BuiltinData{BuiltinType::kDpdy, CallParamType::kF32, "dfdy"},
|
||||
BuiltinData{BuiltinType::kDpdyCoarse, CallParamType::kF32, "dfdy"},
|
||||
BuiltinData{BuiltinType::kDpdyFine, CallParamType::kF32, "dfdy"},
|
||||
BuiltinData{BuiltinType::kFwidth, CallParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthCoarse, CallParamType::kF32, "fwidth"},
|
||||
BuiltinData{BuiltinType::kFwidthFine, CallParamType::kF32, "fwidth"},
|
||||
/* Data packing builtin */
|
||||
BuiltinData{BuiltinType::kPack4x8snorm, CallParamType::kF32, "pack_float_to_snorm4x8"},
|
||||
BuiltinData{BuiltinType::kPack4x8unorm, CallParamType::kF32, "pack_float_to_unorm4x8"},
|
||||
BuiltinData{BuiltinType::kPack2x16snorm, CallParamType::kF32, "pack_float_to_snorm2x16"},
|
||||
BuiltinData{BuiltinType::kPack2x16unorm, CallParamType::kF32, "pack_float_to_unorm2x16"},
|
||||
/* Data unpacking builtin */
|
||||
BuiltinData{BuiltinType::kUnpack4x8snorm, CallParamType::kU32, "unpack_snorm4x8_to_float"},
|
||||
BuiltinData{BuiltinType::kUnpack4x8unorm, CallParamType::kU32, "unpack_unorm4x8_to_float"},
|
||||
BuiltinData{BuiltinType::kUnpack2x16snorm, CallParamType::kU32,
|
||||
"unpack_snorm2x16_to_float"},
|
||||
BuiltinData{BuiltinType::kUnpack2x16unorm, CallParamType::kU32,
|
||||
"unpack_unorm2x16_to_float"}));
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Builtin_Call) {
|
||||
GlobalVar("param1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
|
||||
|
@ -308,12 +405,12 @@ TEST_F(MslGeneratorImplTest, WorkgroupBarrier) {
|
|||
EXPECT_EQ(out.str(), "threadgroup_barrier(mem_flags::mem_threadgroup)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Degrees_Scalar) {
|
||||
TEST_F(MslGeneratorImplTest, Degrees_Scalar_f32) {
|
||||
auto* val = Var("val", ty.f32());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
@ -333,12 +430,12 @@ kernel void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Degrees_Vector) {
|
||||
TEST_F(MslGeneratorImplTest, Degrees_Vector_f32) {
|
||||
auto* val = Var("val", ty.vec3<f32>());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
@ -358,12 +455,66 @@ kernel void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Radians_Scalar) {
|
||||
TEST_F(MslGeneratorImplTest, Degrees_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.f16());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
half tint_degrees(half param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
}
|
||||
|
||||
kernel void test_function() {
|
||||
half val = 0.0h;
|
||||
half const tint_symbol = tint_degrees(val);
|
||||
return;
|
||||
}
|
||||
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Degrees_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.vec3<f16>());
|
||||
auto* call = Call("degrees", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
half3 tint_degrees(half3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
}
|
||||
|
||||
kernel void test_function() {
|
||||
half3 val = 0.0h;
|
||||
half3 const tint_symbol = tint_degrees(val);
|
||||
return;
|
||||
}
|
||||
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Radians_Scalar_f32) {
|
||||
auto* val = Var("val", ty.f32());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
@ -383,12 +534,12 @@ kernel void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Radians_Vector) {
|
||||
TEST_F(MslGeneratorImplTest, Radians_Vector_f32) {
|
||||
auto* val = Var("val", ty.vec3<f32>());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = Build();
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
@ -408,6 +559,60 @@ kernel void test_function() {
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Radians_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.f16());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
half tint_radians(half param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
}
|
||||
|
||||
kernel void test_function() {
|
||||
half val = 0.0h;
|
||||
half const tint_symbol = tint_radians(val);
|
||||
return;
|
||||
}
|
||||
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Radians_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* val = Var("val", ty.vec3<f16>());
|
||||
auto* call = Call("radians", val);
|
||||
WrapInFunction(val, call);
|
||||
|
||||
GeneratorImpl& gen = SanitizeAndBuild();
|
||||
|
||||
ASSERT_TRUE(gen.Generate()) << gen.error();
|
||||
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
half3 tint_radians(half3 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
}
|
||||
|
||||
kernel void test_function() {
|
||||
half3 val = 0.0h;
|
||||
half3 const tint_symbol = tint_radians(val);
|
||||
return;
|
||||
}
|
||||
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(MslGeneratorImplTest, Pack2x16Float) {
|
||||
auto* call = Call("pack2x16float", "p1");
|
||||
GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
|
||||
|
|
|
@ -131,6 +131,42 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* var = GlobalVar("ident", ty.f16(), ast::StorageClass::kPrivate);
|
||||
auto* expr = Call("round", "ident");
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect =
|
||||
R"(%10 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %1 "ident"
|
||||
OpName %7 "a_func"
|
||||
%3 = OpTypeFloat 16
|
||||
%2 = OpTypePointer Private %3
|
||||
%4 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %4
|
||||
%6 = OpTypeVoid
|
||||
%5 = OpTypeFunction %6
|
||||
%7 = OpFunction %6 None %5
|
||||
%8 = OpLabel
|
||||
%11 = OpLoad %3 %1
|
||||
%9 = OpExtInst %3 %10 RoundEven %11
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
// Tests for Logical builtins
|
||||
namespace logical_builtin_tests {
|
||||
|
||||
|
@ -485,6 +521,47 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_SingleParam_Float_Test, Call_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto param = GetParam();
|
||||
// Use a variable to prevent the function being evaluated as constant.
|
||||
auto* scalar = Var("a", nullptr, Expr(1_h));
|
||||
auto* expr = Call(param.name, scalar);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(scalar),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %7 "a"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%5 = OpTypeFloat 16
|
||||
%6 = OpConstant %5 0x1p+0
|
||||
%8 = OpTypePointer Function %5
|
||||
%9 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%7 = OpVariable %8 Function %9
|
||||
OpStore %7 %6
|
||||
%12 = OpLoad %5 %7
|
||||
%10 = OpExtInst %5 %11 )" +
|
||||
param.op +
|
||||
R"( %12
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_SingleParam_Float_Test, Call_Vector_f32) {
|
||||
auto param = GetParam();
|
||||
|
||||
|
@ -527,6 +604,50 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_SingleParam_Float_Test, Call_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto param = GetParam();
|
||||
|
||||
// Use a variable to prevent the function being evaluated as constant.
|
||||
auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
|
||||
auto* expr = Call(param.name, vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "a"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 2
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%12 = OpExtInst %5 %13 )" +
|
||||
param.op +
|
||||
R"( %14
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
|
||||
Builtin_Builder_SingleParam_Float_Test,
|
||||
testing::Values(BuiltinData{"abs", "FAbs"},
|
||||
|
@ -589,6 +710,43 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Length_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* scalar = Var("a", nullptr, Expr(1_h));
|
||||
auto* expr = Call("length", scalar);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(scalar),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %7 "a"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%5 = OpTypeFloat 16
|
||||
%6 = OpConstant %5 0x1p+0
|
||||
%8 = OpTypePointer Function %5
|
||||
%9 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%7 = OpVariable %8 Function %9
|
||||
OpStore %7 %6
|
||||
%12 = OpLoad %5 %7
|
||||
%10 = OpExtInst %5 %11 Length %12
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Length_Vector_f32) {
|
||||
auto* vec = Var("a", nullptr, vec2<f32>(1_f, 1_f));
|
||||
auto* expr = Call("length", vec);
|
||||
|
@ -626,6 +784,45 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Length_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
|
||||
auto* expr = Call("length", vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "a"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 2
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%12 = OpExtInst %6 %13 Length %14
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Normalize_f32) {
|
||||
auto* vec = Var("a", nullptr, vec2<f32>(1_f, 1_f));
|
||||
auto* expr = Call("normalize", vec);
|
||||
|
@ -663,6 +860,45 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Normalize_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* vec = Var("a", nullptr, vec2<f16>(1_h, 1_h));
|
||||
auto* expr = Call("normalize", vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "a"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 2
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%12 = OpExtInst %5 %13 Normalize %14
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
using Builtin_Builder_DualParam_Float_Test = BuiltinBuilderTestWithParam<BuiltinData>;
|
||||
TEST_P(Builtin_Builder_DualParam_Float_Test, Call_Scalar_f32) {
|
||||
auto param = GetParam();
|
||||
|
@ -703,6 +939,47 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_DualParam_Float_Test, Call_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto param = GetParam();
|
||||
auto* scalar = Var("scalar", nullptr, Expr(1_h));
|
||||
auto* expr = Call(param.name, scalar, scalar);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(scalar),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %7 "scalar"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%5 = OpTypeFloat 16
|
||||
%6 = OpConstant %5 0x1p+0
|
||||
%8 = OpTypePointer Function %5
|
||||
%9 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%7 = OpVariable %8 Function %9
|
||||
OpStore %7 %6
|
||||
%12 = OpLoad %5 %7
|
||||
%13 = OpLoad %5 %7
|
||||
%10 = OpExtInst %5 %11 )" +
|
||||
param.op +
|
||||
R"( %12 %13
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_DualParam_Float_Test, Call_Vector_f32) {
|
||||
auto param = GetParam();
|
||||
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
|
||||
|
@ -744,6 +1021,49 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_DualParam_Float_Test, Call_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto param = GetParam();
|
||||
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
|
||||
auto* expr = Call(param.name, vec, vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "vec"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 2
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%15 = OpLoad %5 %9
|
||||
%12 = OpExtInst %5 %13 )" +
|
||||
param.op +
|
||||
R"( %14 %15
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
|
||||
Builtin_Builder_DualParam_Float_Test,
|
||||
testing::Values(BuiltinData{"atan2", "Atan2"},
|
||||
|
@ -790,6 +1110,46 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Reflect_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
|
||||
auto* expr = Call("reflect", vec, vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "vec"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 2
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%15 = OpLoad %5 %9
|
||||
%12 = OpExtInst %5 %13 Reflect %14 %15
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Distance_Scalar_f32) {
|
||||
auto* scalar = Var("scalar", nullptr, Expr(1_f));
|
||||
auto* expr = Call("distance", scalar, scalar);
|
||||
|
@ -826,6 +1186,44 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Distance_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* scalar = Var("scalar", nullptr, Expr(1_h));
|
||||
auto* expr = Call("distance", scalar, scalar);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(scalar),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %7 "scalar"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%5 = OpTypeFloat 16
|
||||
%6 = OpConstant %5 0x1p+0
|
||||
%8 = OpTypePointer Function %5
|
||||
%9 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%7 = OpVariable %8 Function %9
|
||||
OpStore %7 %6
|
||||
%12 = OpLoad %5 %7
|
||||
%13 = OpLoad %5 %7
|
||||
%10 = OpExtInst %5 %11 Distance %12 %13
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Distance_Vector_f32) {
|
||||
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
|
||||
auto* expr = Call("distance", vec, vec);
|
||||
|
@ -864,6 +1262,46 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Distance_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
|
||||
auto* expr = Call("distance", vec, vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "vec"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 2
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%15 = OpLoad %5 %9
|
||||
%12 = OpExtInst %6 %13 Distance %14 %15
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Cross_f32) {
|
||||
auto* vec = Var("vec", nullptr, vec3<f32>(1_f, 1_f, 1_f));
|
||||
auto* expr = Call("cross", vec, vec);
|
||||
|
@ -902,6 +1340,46 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Cross_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* vec = Var("vec", nullptr, vec3<f16>(1_h, 1_h, 1_h));
|
||||
auto* expr = Call("cross", vec, vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "vec"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 3
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%15 = OpLoad %5 %9
|
||||
%12 = OpExtInst %5 %13 Cross %14 %15
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
using Builtin_Builder_ThreeParam_Float_Test = BuiltinBuilderTestWithParam<BuiltinData>;
|
||||
TEST_P(Builtin_Builder_ThreeParam_Float_Test, Call_Scalar_f32) {
|
||||
auto param = GetParam();
|
||||
|
@ -943,6 +1421,48 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_ThreeParam_Float_Test, Call_Scalar_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto param = GetParam();
|
||||
auto* scalar = Var("scalar", nullptr, Expr(1_h));
|
||||
auto* expr = Call(param.name, scalar, scalar, scalar);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(scalar),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%11 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %7 "scalar"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%5 = OpTypeFloat 16
|
||||
%6 = OpConstant %5 0x1p+0
|
||||
%8 = OpTypePointer Function %5
|
||||
%9 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%7 = OpVariable %8 Function %9
|
||||
OpStore %7 %6
|
||||
%12 = OpLoad %5 %7
|
||||
%13 = OpLoad %5 %7
|
||||
%14 = OpLoad %5 %7
|
||||
%10 = OpExtInst %5 %11 )" +
|
||||
param.op +
|
||||
R"( %12 %13 %14
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_ThreeParam_Float_Test, Call_Vector_f32) {
|
||||
auto param = GetParam();
|
||||
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 1_f));
|
||||
|
@ -985,6 +1505,50 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_P(Builtin_Builder_ThreeParam_Float_Test, Call_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto param = GetParam();
|
||||
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
|
||||
auto* expr = Call(param.name, vec, vec, vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "vec"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 2
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%15 = OpLoad %5 %9
|
||||
%16 = OpLoad %5 %9
|
||||
%12 = OpExtInst %5 %13 )" +
|
||||
param.op +
|
||||
R"( %14 %15 %16
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(BuiltinBuilderTest,
|
||||
Builtin_Builder_ThreeParam_Float_Test,
|
||||
testing::Values(BuiltinData{"clamp", "NClamp"},
|
||||
|
@ -1032,6 +1596,47 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_FaceForward_Vector_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* vec = Var("vec", nullptr, vec2<f16>(1_h, 1_h));
|
||||
auto* expr = Call("faceForward", vec, vec, vec);
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Decl(vec),
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%13 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %3 "a_func"
|
||||
OpName %9 "vec"
|
||||
%2 = OpTypeVoid
|
||||
%1 = OpTypeFunction %2
|
||||
%6 = OpTypeFloat 16
|
||||
%5 = OpTypeVector %6 2
|
||||
%7 = OpConstant %6 0x1p+0
|
||||
%8 = OpConstantComposite %5 %7 %7
|
||||
%10 = OpTypePointer Function %5
|
||||
%11 = OpConstantNull %5
|
||||
%3 = OpFunction %2 None %1
|
||||
%4 = OpLabel
|
||||
%9 = OpVariable %10 Function %11
|
||||
OpStore %9 %8
|
||||
%14 = OpLoad %5 %9
|
||||
%15 = OpLoad %5 %9
|
||||
%16 = OpLoad %5 %9
|
||||
%12 = OpExtInst %5 %13 FaceForward %14 %15 %16
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Modf) {
|
||||
auto* vec = Var("vec", nullptr, vec2<f32>(1_f, 2_f));
|
||||
auto* expr = Call("modf", vec);
|
||||
|
@ -2130,6 +2735,43 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Determinant_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* var = GlobalVar("var", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
|
||||
auto* expr = Call("determinant", "var");
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(%12 = OpExtInstImport "GLSL.std.450"
|
||||
OpName %1 "var"
|
||||
OpName %9 "a_func"
|
||||
%5 = OpTypeFloat 16
|
||||
%4 = OpTypeVector %5 3
|
||||
%3 = OpTypeMatrix %4 3
|
||||
%2 = OpTypePointer Private %3
|
||||
%6 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %6
|
||||
%8 = OpTypeVoid
|
||||
%7 = OpTypeFunction %8
|
||||
%9 = OpFunction %8 None %7
|
||||
%10 = OpLabel
|
||||
%13 = OpLoad %3 %1
|
||||
%11 = OpExtInst %5 %12 Determinant %13
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Transpose_f32) {
|
||||
auto* var = GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
|
||||
auto* expr = Call("transpose", "var");
|
||||
|
@ -2166,6 +2808,44 @@ OpFunctionEnd
|
|||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Transpose_f16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* var = GlobalVar("var", ty.mat2x3<f16>(), ast::StorageClass::kPrivate);
|
||||
auto* expr = Call("transpose", "var");
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
auto got = DumpBuilder(b);
|
||||
auto expect = R"(OpName %1 "var"
|
||||
OpName %9 "a_func"
|
||||
%5 = OpTypeFloat 16
|
||||
%4 = OpTypeVector %5 3
|
||||
%3 = OpTypeMatrix %4 2
|
||||
%2 = OpTypePointer Private %3
|
||||
%6 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %6
|
||||
%8 = OpTypeVoid
|
||||
%7 = OpTypeFunction %8
|
||||
%13 = OpTypeVector %5 2
|
||||
%12 = OpTypeMatrix %13 3
|
||||
%9 = OpFunction %8 None %7
|
||||
%10 = OpLabel
|
||||
%14 = OpLoad %3 %1
|
||||
%11 = OpTranspose %12 %14
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
EXPECT_EQ(got, expect);
|
||||
}
|
||||
|
||||
} // namespace matrix_builtin_tests
|
||||
|
||||
// Tests for Numeric builtins with float and integer vector parameter, i.e. "dot"
|
||||
|
@ -2200,6 +2880,37 @@ OpReturn
|
|||
)");
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Dot_F16) {
|
||||
Enable(ast::Extension::kF16);
|
||||
|
||||
auto* var = GlobalVar("v", ty.vec3<f16>(), ast::StorageClass::kPrivate);
|
||||
auto* expr = Call("dot", "v", "v");
|
||||
auto* func = Func("a_func", {}, ty.void_(),
|
||||
{
|
||||
Assign(Phony(), expr),
|
||||
});
|
||||
|
||||
spirv::Builder& b = Build();
|
||||
|
||||
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
|
||||
ASSERT_TRUE(b.GenerateFunction(func)) << b.error();
|
||||
|
||||
EXPECT_EQ(DumpInstructions(b.types()), R"(%4 = OpTypeFloat 16
|
||||
%3 = OpTypeVector %4 3
|
||||
%2 = OpTypePointer Private %3
|
||||
%5 = OpConstantNull %3
|
||||
%1 = OpVariable %2 Private %5
|
||||
%7 = OpTypeVoid
|
||||
%6 = OpTypeFunction %7
|
||||
)");
|
||||
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
|
||||
R"(%11 = OpLoad %3 %1
|
||||
%12 = OpLoad %3 %1
|
||||
%10 = OpDot %4 %11 %12
|
||||
OpReturn
|
||||
)");
|
||||
}
|
||||
|
||||
TEST_F(BuiltinBuilderTest, Call_Dot_U32) {
|
||||
auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
|
||||
auto* expr = Call("dot", "v", "v");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
float tint_degrees(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,16 +13,20 @@ See:
|
|||
{{- range Sem.Builtins -}}
|
||||
{{- range .Overloads -}}
|
||||
{{- range Permute . -}}
|
||||
{{- /* Generate a ./literal/<function>/<permuataion-hash>.wgsl file using
|
||||
the Permutation macro defined below */ -}}
|
||||
{{- $file := printf "./literal/%v/%v.wgsl" .Intrinsic.Name .Hash -}}
|
||||
{{- $content := Eval "Permutation" "Overload" . "Mode" "literal" -}}
|
||||
{{- WriteFile $file $content -}}
|
||||
{{- /* Generate a ./var/<function>/<permuataion-hash>.wgsl file using
|
||||
the Permutation macro defined below */ -}}
|
||||
{{- $file := printf "./var/%v/%v.wgsl" .Intrinsic.Name .Hash -}}
|
||||
{{- $content := Eval "Permutation" "Overload" . "Mode" "var" -}}
|
||||
{{- WriteFile $file $content -}}
|
||||
{{- /* TODO(crbug.com/tint/1502): Remove the bodge below and emit "enable f16;" after
|
||||
getting ready for F16 end-to-end tests. */ -}}
|
||||
{{- if not (OverloadUsesF16 .Overload) -}}
|
||||
{{- /* Generate a ./literal/<function>/<permuataion-hash>.wgsl file using
|
||||
the Permutation macro defined below */ -}}
|
||||
{{- $file := printf "./literal/%v/%v.wgsl" .Intrinsic.Name .Hash -}}
|
||||
{{- $content := Eval "Permutation" "Overload" . "Mode" "literal" -}}
|
||||
{{- WriteFile $file $content -}}
|
||||
{{- /* Generate a ./var/<function>/<permuataion-hash>.wgsl file using
|
||||
the Permutation macro defined below */ -}}
|
||||
{{- $file := printf "./var/%v/%v.wgsl" .Intrinsic.Name .Hash -}}
|
||||
{{- $content := Eval "Permutation" "Overload" . "Mode" "var" -}}
|
||||
{{- WriteFile $file $content -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
@ -319,4 +323,4 @@ enable chromium_experimental_dp4a;
|
|||
{{- end -}}
|
||||
>
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
|
@ -1,47 +0,0 @@
|
|||
// 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.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// File generated by tools/src/cmd/gen
|
||||
// using the template:
|
||||
// test/tint/builtins/gen/gen.wgsl.tmpl
|
||||
//
|
||||
// Do not modify this file directly
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct SB_RO {
|
||||
arg_0: array<f16>,
|
||||
};
|
||||
@group(0) @binding(1) var<storage, read> sb_ro : SB_RO;
|
||||
|
||||
// fn arrayLength(ptr<storage, array<f16>, read>) -> u32
|
||||
fn arrayLength_8421b9() {
|
||||
var res: u32 = arrayLength(&sb_ro.arg_0);
|
||||
}
|
||||
|
||||
@vertex
|
||||
fn vertex_main() -> @builtin(position) vec4<f32> {
|
||||
arrayLength_8421b9();
|
||||
return vec4<f32>();
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment_main() {
|
||||
arrayLength_8421b9();
|
||||
}
|
||||
|
||||
@compute @workgroup_size(1)
|
||||
fn compute_main() {
|
||||
arrayLength_8421b9();
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// 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.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// File generated by tools/src/cmd/gen
|
||||
// using the template:
|
||||
// test/tint/builtins/gen/gen.wgsl.tmpl
|
||||
//
|
||||
// Do not modify this file directly
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct SB_RW {
|
||||
arg_0: array<f16>,
|
||||
};
|
||||
@group(0) @binding(0) var<storage, read_write> sb_rw : SB_RW;
|
||||
|
||||
// fn arrayLength(ptr<storage, array<f16>, read_write>) -> u32
|
||||
fn arrayLength_cbd6b5() {
|
||||
var res: u32 = arrayLength(&sb_rw.arg_0);
|
||||
}
|
||||
|
||||
@vertex
|
||||
fn vertex_main() -> @builtin(position) vec4<f32> {
|
||||
arrayLength_cbd6b5();
|
||||
return vec4<f32>();
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment_main() {
|
||||
arrayLength_cbd6b5();
|
||||
}
|
||||
|
||||
@compute @workgroup_size(1)
|
||||
fn compute_main() {
|
||||
arrayLength_cbd6b5();
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_degrees(vec4 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec4 tint_degrees(vec4 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_degrees(vec4 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec2 tint_degrees(vec2 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec2 tint_degrees(vec2 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec2 tint_degrees(vec2 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec3 tint_degrees(vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec3 tint_degrees(vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec3 tint_degrees(vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
float tint_degrees(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
float tint_degrees(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
float tint_degrees(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_radians(vec4 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec4 tint_radians(vec4 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_radians(vec4 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec2 tint_radians(vec2 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec2 tint_radians(vec2 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec2 tint_radians(vec2 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
float tint_radians(float param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
float tint_radians(float param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
float tint_radians(float param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec3 tint_radians(vec3 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec3 tint_radians(vec3 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec3 tint_radians(vec3 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
// 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.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// File generated by tools/src/cmd/gen
|
||||
// using the template:
|
||||
// test/tint/builtins/gen/gen.wgsl.tmpl
|
||||
//
|
||||
// Do not modify this file directly
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct SB_RO {
|
||||
arg_0: array<f16>,
|
||||
};
|
||||
@group(0) @binding(1) var<storage, read> sb_ro : SB_RO;
|
||||
|
||||
// fn arrayLength(ptr<storage, array<f16>, read>) -> u32
|
||||
fn arrayLength_8421b9() {
|
||||
var res: u32 = arrayLength(&sb_ro.arg_0);
|
||||
}
|
||||
|
||||
@vertex
|
||||
fn vertex_main() -> @builtin(position) vec4<f32> {
|
||||
arrayLength_8421b9();
|
||||
return vec4<f32>();
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment_main() {
|
||||
arrayLength_8421b9();
|
||||
}
|
||||
|
||||
@compute @workgroup_size(1)
|
||||
fn compute_main() {
|
||||
arrayLength_8421b9();
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/8421b9.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// 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.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// File generated by tools/src/cmd/gen
|
||||
// using the template:
|
||||
// test/tint/builtins/gen/gen.wgsl.tmpl
|
||||
//
|
||||
// Do not modify this file directly
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct SB_RW {
|
||||
arg_0: array<f16>,
|
||||
};
|
||||
@group(0) @binding(0) var<storage, read_write> sb_rw : SB_RW;
|
||||
|
||||
// fn arrayLength(ptr<storage, array<f16>, read_write>) -> u32
|
||||
fn arrayLength_cbd6b5() {
|
||||
var res: u32 = arrayLength(&sb_rw.arg_0);
|
||||
}
|
||||
|
||||
@vertex
|
||||
fn vertex_main() -> @builtin(position) vec4<f32> {
|
||||
arrayLength_cbd6b5();
|
||||
return vec4<f32>();
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment_main() {
|
||||
arrayLength_cbd6b5();
|
||||
}
|
||||
|
||||
@compute @workgroup_size(1)
|
||||
fn compute_main() {
|
||||
arrayLength_cbd6b5();
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
SKIP: FAILED
|
||||
|
||||
builtins/gen/var/arrayLength/cbd6b5.wgsl:26:16 error: f16 used without 'f16' extension enabled
|
||||
arg_0: array<f16>,
|
||||
^^^
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_degrees(vec4 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec4 tint_degrees(vec4 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_degrees(vec4 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec2 tint_degrees(vec2 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec2 tint_degrees(vec2 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec2 tint_degrees(vec2 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec3 tint_degrees(vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec3 tint_degrees(vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec3 tint_degrees(vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
float tint_degrees(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
float tint_degrees(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
float tint_degrees(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_radians(vec4 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec4 tint_radians(vec4 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_radians(vec4 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec2 tint_radians(vec2 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec2 tint_radians(vec2 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec2 tint_radians(vec2 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
float tint_radians(float param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
float tint_radians(float param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
float tint_radians(float param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
vec3 tint_radians(vec3 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@ void main() {
|
|||
precision mediump float;
|
||||
|
||||
vec3 tint_radians(vec3 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ void main() {
|
|||
#version 310 es
|
||||
|
||||
vec3 tint_radians(vec3 param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#version 310 es
|
||||
|
||||
float tint_radians(float param_0) {
|
||||
return param_0 * 0.017453292519943295474;
|
||||
return param_0 * 0.017453292519943295474f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
#version 310 es
|
||||
|
||||
vec4 tint_degrees(vec4 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
vec3 tint_degrees_1(vec3 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
vec2 tint_degrees_2(vec2 param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
float tint_degrees_3(float param_0) {
|
||||
return param_0 * 57.295779513082322865;
|
||||
return param_0 * 57.295779513082322865f;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -448,6 +448,8 @@ func SplitDisplayName(displayName string) []string {
|
|||
// If the type is not a composite type, then the fully qualified name is returned
|
||||
func ElementType(fqn sem.FullyQualifiedName) sem.FullyQualifiedName {
|
||||
switch fqn.Target.GetName() {
|
||||
case "vec2", "vec3", "vec4":
|
||||
return fqn.TemplateArguments[0].(sem.FullyQualifiedName)
|
||||
case "vec":
|
||||
return fqn.TemplateArguments[1].(sem.FullyQualifiedName)
|
||||
case "mat":
|
||||
|
@ -462,12 +464,16 @@ func ElementType(fqn sem.FullyQualifiedName) sem.FullyQualifiedName {
|
|||
// fully qualified name.
|
||||
func DeepestElementType(fqn sem.FullyQualifiedName) sem.FullyQualifiedName {
|
||||
switch fqn.Target.GetName() {
|
||||
case "vec2", "vec3", "vec4":
|
||||
return fqn.TemplateArguments[0].(sem.FullyQualifiedName)
|
||||
case "vec":
|
||||
return fqn.TemplateArguments[1].(sem.FullyQualifiedName)
|
||||
case "mat":
|
||||
return DeepestElementType(fqn.TemplateArguments[2].(sem.FullyQualifiedName))
|
||||
case "array":
|
||||
return DeepestElementType(fqn.TemplateArguments[0].(sem.FullyQualifiedName))
|
||||
case "ptr":
|
||||
return DeepestElementType(fqn.TemplateArguments[1].(sem.FullyQualifiedName))
|
||||
}
|
||||
return fqn
|
||||
}
|
||||
|
@ -489,7 +495,7 @@ func IsDeclarable(fqn sem.FullyQualifiedName) bool {
|
|||
}
|
||||
|
||||
// OverloadUsesF16 returns true if the overload uses the f16 type anywhere in the signature.
|
||||
func OverloadUsesF16(overload *sem.Overload, typename string) bool {
|
||||
func OverloadUsesF16(overload *sem.Overload) bool {
|
||||
for _, param := range overload.Parameters {
|
||||
if DeepestElementType(param.Type).Target.GetName() == "f16" {
|
||||
return true
|
||||
|
|
Loading…
Reference in New Issue