Source browser

examples/shaders/math.cpp

Read the complete file below or download its original bytes. Line numbers provide stable links to a declaration or processing step.

File fingerprint
1// Native GLSL compute source. The build compiles a generated C++11 adapter and
2// embeds this source in its registered math_kernel factory automatically.
3#ifdef __cplusplus // Expose host declarations only when a C++ compiler reads this shader.
4#include "shdr.h" // Include shdr.h declarations.
5#endif // Finish this conditional compilation branch.
6
7layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; // Group 1 independent invocations along x.
8layout(std430, binding = 0) writeonly buffer FloatResults { // Write floating-point reference results through buffer binding 0.
9    float results[]; // Store floating-point reference results.
10}; // Finish this declaration.
11layout(std430, binding = 1) writeonly buffer BitResults { // Write integer and packed-bit reference results through buffer binding 1.
12    uint bits[]; // Store integer and packed-bit reference results.
13}; // Finish this declaration.
14uniform vec2 controls; // Supply runtime values for the absolute-value and exact-bit tests.
15
16// Native GLSL out parameters become C++ references in the generated adapter.
17void split(in vec2 value, out vec2 integral, out vec2 fractional) { // Split a vector into signed integer and fractional parts through out parameters.
18    fractional = modf(value, integral); // Use modf to fill the integer out parameter and return the fractional part.
19} // End this block.
20
21void main() { // Record deterministic GLSL builtin and numeric results for CPU and GPU comparison.
22    vec3 c = cross(vec3(2.0, 3.0, 4.0), vec3(5.0, 6.0, 7.0)); // Form a cross product whose three components are checked independently.
23    results[0] = c.x; // Record the x component of the three-dimensional cross product.
24    results[1] = c.y; // Record the y component of the three-dimensional cross product.
25    results[2] = c.z; // Record the z component of the three-dimensional cross product.
26    results[3] = dot(vec3(1.0, 2.0, 3.0), vec3(4.0, 5.0, 6.0)); // Record the scalar dot product of two vectors.
27    results[4] = length(vec2(3.0, 4.0)); // Record the Euclidean length of a three-four vector.
28    vec2 normalized = normalize(vec2(3.0, 4.0)); // Normalize a vector with a known three-four-five length.
29    results[5] = normalized.x; // Record the normalized x component.
30    results[6] = normalized.y; // Record the normalized y component.
31    results[7] = reflect(vec3(1.0, -1.0, 0.0), vec3(0.0, 1.0, 0.0)).y; // Record the reflected vector's y component.
32    results[8] = refract(vec2(0.0, -1.0), vec2(0.0, 1.0), 0.5).y; // Record the refracted vector's y component.
33    results[9] = mod(-3.5, 2.0); // Record floor-based mod with a negative dividend.
34    results[10] = mod(3.5, -2.0); // Record floor-based mod with a negative divisor.
35    results[11] = fract(-1.25); // Record the positive fractional part of a negative input.
36    vec4 rounded = roundEven(vec4(0.5, 1.5, 2.5, -1.5)); // Exercise halfway rounding on positive and negative values.
37    results[12] = rounded.x; // Record ties-to-even rounding of positive one-half.
38    results[13] = rounded.y; // Record ties-to-even rounding of positive one-and-a-half.
39    results[14] = rounded.z; // Record ties-to-even rounding of positive two-and-a-half.
40    results[15] = rounded.w; // Record ties-to-even rounding of negative one-and-a-half.
41
42    mat2 a = mat2(1.0, 2.0, 3.0, 4.0); // Specify the two-by-two test matrix in GLSL column order.
43    mat3 b = mat3(3.0, 1.0, 3.0, 5.0, 5.0, 9.0, 2.0, 8.0, 2.0); // Specify the three-by-three determinant test matrix in GLSL column order.
44    results[16] = determinant(a); // Record the determinant of the two-by-two matrix.
45    results[17] = determinant(b); // Record the determinant of the three-by-three matrix.
46    vec2 mv = a * vec2(2.0, 3.0); // Multiply a matrix by a column vector.
47    vec2 vm = vec2(2.0, 3.0) * a; // Multiply a row vector by the same matrix.
48    results[18] = mv.x; // Record the x component of matrix times column vector.
49    results[19] = mv.y; // Record the y component of matrix times column vector.
50    results[20] = vm.x; // Record the x component of row vector times matrix.
51    results[21] = vm.y; // Record the y component of row vector times matrix.
52    mat2 product = a * a; // Check the row-by-column products of ordinary matrix multiplication.
53    results[22] = product[0][0]; // Record the first diagonal matrix product element.
54    results[23] = product[1][1]; // Record the second diagonal matrix product element.
55    mat2 identity = a * inverse(a); // Multiply a nonsingular matrix by its inverse.
56    results[24] = identity[0][0]; // Record the identity product's first diagonal element.
57    results[25] = identity[1][0]; // Record the identity product's off-diagonal element.
58    mat3x2 rectangular = mat3x2(1.0, 2.0, 3.0, 4.0, 5.0, 6.0); // Use a three-column, two-row matrix to check non-square dimensions.
59    mat2 rectangular_product = rectangular * mat2x3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0); // Multiply compatible rectangular dimensions into a two-by-two result.
60    results[26] = rectangular_product[1][1]; // Record a rectangular matrix product element.
61    mat2x3 transposed = transpose(rectangular); // Swap the rectangular matrix's row and column dimensions.
62    results[27] = transposed[0][1]; // Record a rectangular transpose element.
63    mat2x3 outer = outerProduct(vec3(1.0, 2.0, 3.0), vec2(4.0, 5.0)); // Create a matrix from the outer product of two differently sized vectors.
64    results[28] = outer[1][2]; // Record an outer-product element.
65    mat2 components = matrixCompMult(a, a); // Multiply matching matrix components independently.
66    results[29] = components[1][1]; // Record a componentwise matrix product element.
67
68    vec2 swapped = vec2(1.0, 2.0); // Start with distinct components so aliasing swizzle errors are visible.
69    swapped.xy = swapped.yx; // Read both source components before assigning their reversed order.
70    results[30] = swapped.x; // Record the x component after an aliasing swizzle assignment.
71    results[31] = swapped.y; // Record the y component after an aliasing swizzle assignment.
72    swapped += swapped.yx; // Snapshot the reversed source before applying both swizzle writes.
73    results[32] = swapped.x; // Record the x component after an aliasing swizzle addition.
74    results[33] = swapped.y; // Record the y component after an aliasing swizzle addition.
75    results[34] = mix(vec2(2.0), vec2(4.0), 0.25).x; // Record floating-point vector interpolation.
76    vec2 selected = mix(vec2(2.0, 3.0), vec2(4.0, 5.0), bvec2(true, false)); // Choose components from different inputs using a boolean selector vector.
77    results[35] = float(selected.x); // Record boolean selection of the first vector component.
78    results[36] = float(selected.y); // Record boolean selection of the second vector component.
79    results[37] = smoothstep(0.0, 1.0, 0.5); // Record the midpoint of the cubic smoothstep curve.
80    results[38] = step(1.0, 0.5); // Record a step input below the edge.
81    results[39] = step(1.0, 1.0); // Record a step input exactly on the edge.
82    results[40] = degrees(radians(90.0)); // Record the angle after a radians-degrees round trip.
83    results[41] = inversesqrt(16.0); // Record the reciprocal square root of sixteen.
84    vec2 integral; // Receive the signed integer parts through the helper's out parameter.
85    vec2 fractional; // Receive the signed fractional parts through the helper's out parameter.
86    split(vec2(-1.25, 2.5), integral, fractional); // Exercise vector out-parameter translation with positive and negative inputs.
87    results[42] = integral.x; // Record the signed integer part produced through an out parameter.
88    results[43] = fractional.x; // Record the signed fractional part produced through an out parameter.
89    ivec2 exponent; // Receive the base-two exponents through frexp's out parameter.
90    vec2 mantissa = frexp(vec2(4.0, 0.125), exponent); // Separate each input into a signed mantissa and a base-two exponent.
91    vec2 restored = ldexp(mantissa, exponent); // Recombine those mantissas and exponents with ldexp.
92    results[44] = restored.x; // Record a value reconstructed from binary mantissa and exponent.
93    results[45] = ldexp(0.5, 3); // Record scalar reconstruction from a mantissa and exponent.
94    results[46] = unpackHalf2x16(packHalf2x16(vec2(1.0, -2.0))).y; // Record a packed half-float round trip.
95    results[47] = unpackSnorm2x16(packSnorm2x16(vec2(-1.0, 1.0))).x; // Record a packed signed-normalized round trip.
96    results[48] = abs(controls.y); // Record the absolute value of a runtime uniform component.
97    results[49] = clamp(0.5, 0.0, 1.0); // Record scalar clamping inside its interval.
98    results[50] = faceforward(vec2(0.0, 1.0), vec2(0.0, 1.0), vec2(0.0, 1.0)).y; // Record the normal chosen by faceforward.
99    bvec2 inverted = not(bvec2(false, true)); // Apply componentwise GLSL logical negation.
100    results[51] = float(inverted.x); // Record the first component of a logical vector inversion.
101    results[52] = mix(2.0, 4.0, 0.25); // Record scalar floating-point interpolation.
102    results[53] = pow(3.0, 2.0); // Record a scalar power.
103
104    bits[0] = floatBitsToUint(controls.x); // Record the exact IEEE bits of a runtime floating-point value.
105    bits[1] = floatBitsToUint(-0.0); // Record the IEEE sign bit of negative zero.
106    bits[2] = uint(bitCount(-1)); // Record the number of set bits in a signed negative integer.
107    bits[3] = uint(findLSB(8u)); // Record the least-significant set-bit position.
108    bits[4] = uint(findMSB(-2)); // Record the signed most-significant set-bit position.
109    bits[5] = bitfieldReverse(1u); // Record a complete reversal of the low input bit.
110    bits[6] = uint(bitfieldExtract(240, 4, 4)); // Record an extracted signed bit field.
111    bits[7] = bitfieldInsert(0xff00u, 3u, 0, 4); // Record an inserted low unsigned bit field.
112    uint carry; // Receive the unsigned-addition carry through an out parameter.
113    uint sum = uaddCarry(0xffffffffu, 2u, carry); // Add across the uint limit to check the result and carry separately.
114    bits[8] = sum; // Record the wrapped sum from unsigned addition.
115    bits[9] = carry; // Record the carry from that unsigned addition.
116    uint hi; // Receive the high half of the full unsigned product.
117    uint lo; // Receive the low half of the full unsigned product.
118    umulExtended(0xffffffffu, 0xffffffffu, hi, lo); // Multiply two uint values into an exact two-word unsigned product.
119    bits[10] = hi; // Record the high word of the full unsigned product.
120    bits[11] = lo; // Record the low word of the full unsigned product.
121    bits[12] = packHalf2x16(vec2(1.0, -2.0)); // Record two half-float encodings packed into one uint.
122    bits[13] = packUnorm2x16(vec2(0.0, 1.0)); // Record two unsigned normalized components packed into one uint.
123    bits[14] = packUnorm4x8(vec4(1.0, 0.0, 1.0, 0.0)); // Record four unsigned normalized bytes packed into one uint.
124    uint borrow; // Receive the unsigned-subtraction borrow through an out parameter.
125    uint difference = usubBorrow(0u, 1u, borrow); // Subtract across zero to check the wrapped difference and borrow separately.
126    bits[15] = difference; // Record the wrapped difference from unsigned subtraction.
127    bits[16] = borrow; // Record the borrow from that unsigned subtraction.
128} // End this block.