1#include <gtk/gtk.h>
2
3#include "gsk/gl/fp16private.h"
4
5static void
6test_constants (void)
7{
8 struct {
9 float f;
10 guint16 h;
11 } tests[] = {
12 { 0.0, FP16_ZERO },
13 { 1.0, FP16_ONE },
14 { -1.0, FP16_MINUS_ONE },
15 };
16
17 for (int i = 0; i < G_N_ELEMENTS (tests); i++)
18 {
19 float f[4];
20 guint16 h[4];
21
22 memset (s: f, c: 0, n: sizeof (f));
23 f[0] = tests[i].f;
24 float_to_half4 (f, h);
25 g_assert_cmpuint (h[0], ==, tests[i].h);
26
27
28 memset (s: h, c: 0, n: sizeof (h));
29 h[0] = tests[i].h;
30 half_to_float4 (h, f);
31 g_assert_cmpfloat (f[0], ==, tests[i].f);
32 }
33}
34
35static float
36random_representable_float (void)
37{
38 guint16 h[4];
39 float f[4];
40 do
41 {
42 /* generate a random float thats representable as fp16 */
43 memset (s: h, c: 0, n: sizeof (h));
44 h[0] = g_random_int_range (G_MININT16, G_MAXINT16);
45 half_to_float4 (h, f);
46 }
47 while (!isnormal (f[0])); /* skip nans and infs since they don't compare well */
48
49 return f[0];
50}
51
52static void
53test_roundtrip (void)
54{
55 for (int i = 0; i < 100; i++)
56 {
57 float f[4];
58 float f2[4];
59 guint16 h[4];
60
61 f2[0] = random_representable_float ();
62 memset (s: f, c: 0, n: sizeof (f));
63 f[0] = f2[0];
64
65 float_to_half4 (f, h);
66 half_to_float4 (h, f: f2);
67
68 g_assert_cmpfloat (f[0], ==, f2[0]);
69 }
70}
71
72/* Test that the array version work as expected,
73 * in particular with unaligned boundaries.
74 */
75static void
76test_many (void)
77{
78 for (int i = 0; i < 100; i++)
79 {
80 int size = g_random_int_range (begin: 100, end: 200);
81 int offset = g_random_int_range (begin: 0, end: 20);
82
83 guint16 *h = g_new0 (guint16, size);
84 float *f = g_new0 (float, size);
85 float *f2 = g_new0 (float, size);
86
87 for (int j = offset; j < size; j++)
88 f[j] = random_representable_float ();
89
90 float_to_half (f: f + offset, h: h + offset, n: size - offset);
91 half_to_float (h: h + offset, f: f2 + offset, n: size - offset);
92
93 for (int j = offset; j < size; j++)
94 g_assert_cmpfloat (f[j], ==, f2[j]);
95 }
96}
97
98int
99main (int argc, char *argv[])
100{
101 (g_test_init) (argc: &argc, argv: &argv, NULL);
102
103 g_test_add_func (testpath: "/half-float/constants", test_func: test_constants);
104 g_test_add_func (testpath: "/half-float/roundtrip", test_func: test_roundtrip);
105 g_test_add_func (testpath: "/half-float/many", test_func: test_many);
106
107 return g_test_run ();
108}
109

source code of gtk/testsuite/gsk/half-float.c