Bug 199531

Summary: [WHLSL] Test standard library
Product: WebKit Reporter: Myles C. Maxfield <mmaxfield>
Component: WebGPUAssignee: Nobody <webkit-unassigned>
Status: RESOLVED WONTFIX    
Severity: Normal    
Priority: P2    
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   

Description Myles C. Maxfield 2019-07-05 14:42:05 PDT
We need to do a quick check to make sure the standard library matches HLSL's standard library
Comment 1 Myles C. Maxfield 2019-07-05 15:15:12 PDT
Here's a test from HLSL:

RWStructuredBuffer<float> buffer1 : register(u0);
RWStructuredBuffer<float> buffer2 : register(u1);

[numthreads(1, 1, 1)]
void main()
{
	buffer2[0] = sqrt(0);
	buffer2[1] = sqrt(5.0);
	buffer2[2] = sqrt(-5.0);
	buffer2[3] = log2(5.0);
	buffer2[4] = log2(-5.0);
	buffer2[5] = log10(-5.0);
	buffer2[6] = log10(5.0);
	buffer2[7] = frac(5.4);
	buffer2[8] = frac(-5.4);
	buffer2[9] = exp2(-5.0);
	buffer2[10] = exp2(5.0);
	buffer2[11] = degrees(5.0);
	buffer2[12] = radians(5.0);
	buffer2[13] = rcp(5.0);
	buffer2[14] = rcp(-5.0);
	buffer2[15] = rsqrt(5.0);
	buffer2[16] = rsqrt(-5.0);
	buffer2[17] = saturate(5.4);
	buffer2[18] = saturate(5.7);
	buffer2[19] = saturate(-5.4);
	buffer2[20] = saturate(-5.7);
	buffer2[21] = saturate(-0.7);
	buffer2[22] = saturate(0.7);
	buffer2[23] = cos(5.0);
	buffer2[24] = sin(5.0);
	buffer2[25] = tan(5.0);
	buffer2[26] = acos(1.0);
	buffer2[27] = acos(1.0);
	buffer2[28] = atan(5.0);
	buffer2[29] = sinh(5.0);
	buffer2[30] = cosh(5.0);
	buffer2[31] = tanh(5.0);
	buffer2[32] = ceil(5.4);
	buffer2[33] = ceil(5.7);
	buffer2[34] = ceil(-5.4);
	buffer2[35] = ceil(-5.7);
	buffer2[36] = exp(5.0);
	buffer2[37] = floor(5.4);
	buffer2[38] = floor(5.7);
	buffer2[39] = floor(-5.4);
	buffer2[40] = floor(-5.7);
	buffer2[41] = log(5.0);
	buffer2[42] = round(5.4);
	buffer2[43] = round(5.7);
	buffer2[44] = round(-5.4);
	buffer2[45] = round(-5.7);
	buffer2[46] = trunc(5.4);
	buffer2[47] = trunc(5.7);
	buffer2[48] = trunc(-5.4);
	buffer2[49] = trunc(-5.7);
	buffer2[50] = pow(3.0, 5.0);
	buffer2[51] = step(3.0, 5.0);
	buffer2[52] = step(5.0, 3.0);
	buffer2[53] = ldexp(5.0, 3.0);
	buffer2[54] = ldexp(3.0, 5.0);
	buffer2[55] = fmod(3.0, 5.0);
	buffer2[56] = fmod(21.0, 5.0);
	buffer2[57] = smoothstep(0.0, 1.0, 0.5);
	buffer2[58] = smoothstep(0.0, 1.0, -0.5);
	buffer2[59] = smoothstep(0.0, 1.0, 1.5);
	buffer2[60] = smoothstep(0.0, 1.0, 0.75);
	buffer2[61] = smoothstep(0.0, 1.0, 0.25);
	buffer2[62] = lerp(80.0, 160.0, 0.5);
	buffer2[63] = lerp(80.0, 160.0, -0.5);
	buffer2[64] = lerp(80.0, 160.0, 1.5);
	buffer2[65] = lerp(80.0, 160.0, 0.75);
	buffer2[66] = lerp(80.0, 160.0, 0.25);
	buffer2[67] = mad(2.0, 5.0, 7.0);
	buffer2[68] = isfinite(2.0) ? 1.0 : 0.0;
	buffer2[69] = isinf(2.0) ? 1.0 : 0.0;
	buffer2[70] = isnan(2.0) ? 1.0 : 0.0;
	buffer2[71] = atan2(3.0, 4.0);
	sincos(2.0, buffer2[72], buffer2[73]);
	buffer2[74] = any(bool2(true, true)) ? 1.0 : 0.0;
	buffer2[75] = any(bool2(true, false)) ? 1.0 : 0.0;
	buffer2[76] = any(bool2(false, true)) ? 1.0 : 0.0;
	buffer2[77] = any(bool2(false, false)) ? 1.0 : 0.0;
	buffer2[78] = all(bool2(true, true)) ? 1.0 : 0.0;
	buffer2[79] = all(bool2(true, false)) ? 1.0 : 0.0;
	buffer2[80] = all(bool2(false, true)) ? 1.0 : 0.0;
	buffer2[81] = all(bool2(false, false)) ? 1.0 : 0.0;
	buffer2[82] = abs(5.0);
	buffer2[83] = abs(-5.0);
	buffer2[84] = sign(5.0);
	buffer2[85] = sign(0.0);
	buffer2[86] = sign(-5.0);
	buffer2[87] = min(4.0, 5.0);
	buffer2[88] = min(5.0, 4.0);
	buffer2[89] = max(4.0, 5.0);
	buffer2[90] = max(5.0, 4.0);
	buffer2[91] = clamp(100.0, 80.0, 160.0);
	buffer2[92] = clamp(90.0, 80.0, 160.0);
	buffer2[93] = clamp(150.0, 80.0, 160.0);
	buffer2[94] = clamp(200.0, 80.0, 160.0);
	buffer2[95] = modf(3.4, buffer2[96]);
	buffer2[97] = modf(-3.4, buffer2[98]);
	buffer2[99] = float(reversebits(0x00010000));
	buffer2[100] = float(reversebits(0x00008000));
	buffer2[101] = float(countbits(5));
	buffer2[102] = float(countbits(6));
	buffer2[103] = float(countbits(7));
	buffer2[104] = float(countbits(8));
	buffer2[105] = float(firstbithigh(0x00FFFFFF));
	buffer2[106] = float(firstbithigh(0x0FFFFFFF));
	buffer2[107] = float(firstbithigh(0xFFFFFFFF));
	buffer2[108] = float(firstbithigh(0xFFFFFFF0));
	buffer2[109] = float(firstbithigh(0xFFFFFF00));
	buffer2[110] = float(firstbitlow(0x00FFFFFF));
	buffer2[111] = float(firstbitlow(0x0FFFFFFF));
	buffer2[112] = float(firstbitlow(0xFFFFFFFF));
	buffer2[113] = float(firstbitlow(0xFFFFFFF0));
	buffer2[114] = float(firstbitlow(0xFFFFFF00));
	buffer2[115] = float(asint(-1.0));
	buffer2[116] = float(asuint(-1.0));
	buffer2[117] = float(asfloat(0x40000000));
}

And here's the result:

0: 0
1: 2.23607
2: -nan(ind)
3: 2.32193
4: -nan(ind)
5: -nan(ind)
6: 0.69897
7: 0.675
8: -0.675
9: 0.03125
10: 32
11: 286.479
12: 0.0872665
13: 0.2
14: -0.2
15: 0.447214
16: -nan(ind)
17: 1
18: 1
19: 0
20: 0
21: 0
22: 0.7
23: 0.283662
24: -0.958924
25: -3.38052
26: 0
27: 0
28: 1.3734
29: 74.2032
30: 74.2099
31: 0.999909
32: 6
33: 6
34: -5
35: -5
36: 148.413
37: 5
38: 5
39: -6
40: -6
41: 1.60944
42: 5
43: 6
44: -5
45: -6
46: 5
47: 5
48: -5
49: -5
50: 243
51: 1
52: 0
53: 40
54: 96
55: 3
56: 1
57: 0.5
58: 0
59: 1
60: 0.84375
61: 0.15625
62: 120
63: 40
64: 200
65: 140
66: 100
67: 17
68: 1
69: 0
70: 0
71: 0.643501
72: 0.909297
73: -0.416147
74: 1
75: 1
76: 1
77: 0
78: 1
79: 0
80: 0
81: 0
82: 5
83: 5
84: 1
85: 0
86: -1
87: 4
88: 4
89: 5
90: 5
91: 100
92: 90
93: 150
94: 160
95: 0.4
96: 3
97: -0.4
98: -3
99: 32768
100: 65536
101: 2
102: 2
103: 3
104: 1
105: 23
106: 27
107: 31
108: 31
109: 31
110: 0
111: 0
112: 0
113: 4
114: 8
115: -1.08213e+09
116: 3.21284e+09
117: 2

Still needs testing:
mul()
atomic functions
transpose()
refract(), reflect()
normalize()
lit()
length()
faceforward()
dot(), cross(), distance(), dst()
determinant()

Also: it looks like HLSL doesn't have fma(), isnormal(), isordered(), and isunordered(). count_bits() needs to be renamed to countbits(), and asfloat() needs to exist.
Comment 2 Myles C. Maxfield 2019-07-29 16:13:19 PDT
unsigned int x = 2147483655; result[0] = float(sign(x));" and the result is 1
Int x = 2147483655; result[0] = float(sign(x)); makes result -1
Unsigned int x = 2147483655; buffer2[0] = float(abs(x)) returns 2.14748e+09
Unsigned int x = 4294967293; buffer2[0] = float(abs(x)) returns 4.somethinge+something (not 3)
clamp(8, 15, 10), clamp(13, 15, 10), and clamp(18, 15, 10) should all return 10
Comment 3 Myles C. Maxfield 2019-07-29 16:13:46 PDT
See also: https://github.com/gpuweb/WHLSL/issues/36
Comment 4 Myles C. Maxfield 2019-07-29 17:03:22 PDT
RWStructuredBuffer<float> buffer1 : register(u0);
RWStructuredBuffer<float> buffer2 : register(u1);

[numthreads(1, 1, 1)]
void main()
{
	unsigned int u = 0x00FFFFFF;
	buffer2[0] = firstbitlow(u);
	u = 0x0FFFFFFF;
	buffer2[1] = firstbitlow(u);
	u = 0xFFFFFFFF;
	buffer2[2] = firstbitlow(u);
	u = 0xFFFFFFF0;
	buffer2[3] = firstbitlow(u);
	u = 0xFFFFFF00;
	buffer2[4] = firstbitlow(u);

	int i = 0x00FFFFFF;
	buffer2[5] = firstbitlow(i);
	i = 0x0FFFFFFF;
	buffer2[6] = firstbitlow(i);
	i = 0xFFFFFFF;
	buffer2[7] = firstbitlow(i);
	i = 0xFFFFFFF0;
	buffer2[8] = firstbitlow(i);
	i = 0xFFFFFFFF;
	buffer2[9] = firstbitlow(i);

	u = 0x00FFFFFF;
	buffer2[10] = firstbithigh(u);
	u = 0x0FFFFFFF;
	buffer2[11] = firstbithigh(u);
	u = 0xFFFFFFFF;
	buffer2[12] = firstbithigh(u);
	u = 0xFFFFFFF0;
	buffer2[13] = firstbithigh(u);
	u = 0xFFFFFF00;
	buffer2[14] = firstbithigh(u);

	i = 0x00FFFFFF;
	buffer2[15] = firstbithigh(i);
	i = 0x0FFFFFFF;
	buffer2[16] = firstbithigh(i);
	i = 0xFFFFFFF;
	buffer2[17] = firstbithigh(i);
	i = 0xFFFFFFF0;
	buffer2[18] = firstbithigh(i);
	i = 0xFFFFFFFF;
	buffer2[19] = firstbithigh(i);

	i = 0xFFFFFFFF;
	buffer2[20] = i;
}

0: 0
1: 0
2: 0
3: 4
4: 8
5: 0
6: 0
7: 0
8: 4
9: 0
10: 23
11: 27
12: 31
13: 31
14: 31
15: 23
16: 27
17: 27
18: 3
19: 4.29497e+09
20: -1
Comment 5 Myles C. Maxfield 2019-07-29 17:13:18 PDT
Whoops, the above comment has some typos in it. Here's a corrected one:

RWStructuredBuffer<float> buffer1 : register(u0);
RWStructuredBuffer<float> buffer2 : register(u1);

[numthreads(1, 1, 1)]
void main()
{
	unsigned int u = 0x00FFFFFF;
	buffer2[0] = firstbitlow(u);
	u = 0x0FFFFFFF;
	buffer2[1] = firstbitlow(u);
	u = 0xFFFFFFFF;
	buffer2[2] = firstbitlow(u);
	u = 0xFFFFFFF0;
	buffer2[3] = firstbitlow(u);
	u = 0xFFFFFF00;
	buffer2[4] = firstbitlow(u);

	int i = 0x00FFFFFF;
	buffer2[5] = firstbitlow(i);
	i = 0x0FFFFFFF;
	buffer2[6] = firstbitlow(i);
	i = 0xFFFFFFFF;
	buffer2[7] = firstbitlow(i);
	i = 0xFFFFFFF0;
	buffer2[8] = firstbitlow(i);
	i = 0xFFFFFF00;
	buffer2[9] = firstbitlow(i);

	u = 0x00FFFFFF;
	buffer2[10] = firstbithigh(u);
	u = 0x0FFFFFFF;
	buffer2[11] = firstbithigh(u);
	u = 0xFFFFFFFF;
	buffer2[12] = firstbithigh(u);
	u = 0xFFFFFFF0;
	buffer2[13] = firstbithigh(u);
	u = 0xFFFFFF00;
	buffer2[14] = firstbithigh(u);

	i = 0x00FFFFFF;
	buffer2[15] = firstbithigh(i);
	i = 0x0FFFFFFF;
	buffer2[16] = firstbithigh(i);
	i = 0xFFFFFFFF;
	buffer2[17] = firstbithigh(i);
	i = 0xFFFFFFF0;
	buffer2[18] = firstbithigh(i);
	i = 0xFFFFFF00;
	buffer2[19] = firstbithigh(i);

	i = 0xFFFFFFFF;
	buffer2[20] = i;
}

0: 0
1: 0
2: 0
3: 4
4: 8
5: 0
6: 0
7: 0
8: 4
9: 8
10: 23
11: 27
12: 31
13: 31
14: 31
15: 23
16: 27
17: 4.29497e+09
18: 3
19: 7
20: -1
Comment 6 Myles C. Maxfield 2019-07-29 17:16:17 PDT
	unsigned int u = 0;
	buffer2[0] = firstbitlow(u);

	int i = 0;
	buffer2[1] = firstbitlow(i);

	u = 0;
	buffer2[2] = firstbithigh(u);

	i = 0;
	buffer2[3] = firstbithigh(i);

0: 4.29497e+09
1: 4.29497e+09
2: 4.29497e+09
3: 4.29497e+09
Comment 7 Myles C. Maxfield 2019-08-01 12:13:14 PDT
RWStructuredBuffer<float> buffer1 : register(u0);
RWStructuredBuffer<float> buffer2 : register(u1);

[numthreads(1, 1, 1)]
void main()
{
	int index = 0;
	for (int i = 0; i < 10; ++i) {
		buffer2[index++] = buffer1[i];
		buffer2[index++] = isnan(buffer1[i]) ? 1 : 0;
		buffer2[index++] = isinf(buffer1[i]) ? 1 : 0;
		buffer2[index++] = trunc(buffer1[i]);
		buffer2[index++] = floor(buffer1[i]);
		buffer2[index++] = frac(buffer1[i]);
		buffer2[index++] = ceil(buffer1[i]);
		buffer2[index++] = round(buffer1[i]);
		buffer2[index++] = sqrt(buffer1[i]);
		buffer2[index++] = log(buffer1[i]);
		buffer2[index++] = rcp(buffer1[i]);
		buffer2[index++] = 9999999;
	}
}

"buffer1" is { 5, INFINITY, -INFINITY, NAN, 0.0, -0.0, -3.2, -3.7, 3.2, 3.7 }

Results:
0: 5
1: 0
2: 0
3: 5
4: 5
5: 0
6: 5
7: 5
8: 2.23607
9: 1.60944
10: 0.2
11: 1e+07
12: inf
13: 0
14: 1
15: inf
16: inf
17: -nan(ind)
18: inf
19: inf
20: inf
21: inf
22: 0
23: 1e+07
24: -inf
25: 0
26: 1
27: -inf
28: -inf
29: -nan(ind)
30: -inf
31: -inf
32: -nan(ind)
33: -nan(ind)
34: -0
35: 1e+07
36: -nan(ind)
37: 1
38: 0
39: -nan(ind)
40: -nan(ind)
41: -nan(ind)
42: -nan(ind)
43: -nan(ind)
44: -nan(ind)
45: -nan(ind)
46: -nan(ind)
47: 1e+07
48: 0
49: 0
50: 0
51: 0
52: 0
53: 0
54: 0
55: 0
56: 0
57: -inf
58: inf
59: 1e+07
60: -0
61: 0
62: 0
63: -0
64: -0
65: 0
66: -0
67: -0
68: -0
69: -inf
70: -inf
71: 1e+07
72: -3.2
73: 0
74: 0
75: -3
76: -4
77: 0.8
78: -3
79: -3
80: -nan(ind)
81: -nan(ind)
82: -0.3125
83: 1e+07
84: -3.7
85: 0
86: 0
87: -3
88: -4
89: 0.3
90: -3
91: -4
92: -nan(ind)
93: -nan(ind)
94: -0.27027
95: 1e+07
96: 3.2
97: 0
98: 0
99: 3
100: 3
101: 0.2
102: 4
103: 3
104: 1.78885
105: 1.16315
106: 0.3125
107: 1e+07
108: 3.7
109: 0
110: 0
111: 3
112: 3
113: 0.7
114: 4
115: 4
116: 1.92354
117: 1.30833
118: 0.27027
119: 1e+07
Comment 8 Myles C. Maxfield 2019-08-01 16:45:39 PDT
operator% needs to be defined on floats
Comment 9 Myles C. Maxfield 2019-08-08 16:57:04 PDT
min(0.0, -0.0) = -0.0 and min(-0.0, 0.0) = -0.0
Comment 10 Myles C. Maxfield 2019-08-08 16:59:36 PDT
sign(-0.0) is 0
Comment 11 Myles C. Maxfield 2020-05-05 00:42:43 PDT
WHLSL is no longer relevant.