• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 Collabora Ltd.
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef PAN_PACK_HELPERS_H
7 #define PAN_PACK_HELPERS_H
8 
9 #include <inttypes.h>
10 #include <stdio.h>
11 
12 #include "util/bitpack_helpers.h"
13 
14 static inline uint32_t
__gen_padded(uint32_t v,uint32_t start,uint32_t end)15 __gen_padded(uint32_t v, uint32_t start, uint32_t end)
16 {
17    unsigned shift = __builtin_ctz(v);
18    unsigned odd = v >> (shift + 1);
19 
20 #ifndef NDEBUG
21    assert((v >> shift) & 1);
22    assert(shift <= 31);
23    assert(odd <= 7);
24    assert((end - start + 1) == 8);
25 #endif
26 
27    return util_bitpack_uint(shift | (odd << 5), start, end);
28 }
29 
30 #define __gen_unpack_uint(out, cl, start, end)                                 \
31    do {                                                                        \
32       uint64_t __val = 0;                                                      \
33       const int __width = (end) - (start) + 1;                                 \
34       const uint64_t __mask =                                                  \
35          (__width == 64) ? ~((uint64_t)0) : ((uint64_t)1 << __width) - 1;      \
36                                                                                \
37       for (unsigned __word = (start) / 32; __word < ((end) / 32) + 1;          \
38            __word++) {                                                         \
39          __val |= ((uint64_t)(cl)[__word]) << ((__word - (start) / 32) * 32);  \
40       }                                                                        \
41                                                                                \
42       (out) = (__val >> ((start) % 32)) & __mask;                              \
43    } while (0)
44 
45 #define __gen_unpack_sint(out, cl, start, end)                                 \
46    do {                                                                        \
47       int size = (end) - (start) + 1;                                          \
48       int64_t __tmp_sint;                                                      \
49       __gen_unpack_uint(__tmp_sint, cl, start, end);                           \
50       (out) = util_sign_extend(__tmp_sint, size);                              \
51    } while (0)
52 
53 #define __gen_unpack_ulod(out, cl, start, end)                                 \
54    do {                                                                        \
55       uint32_t __tmp_ulod;                                                     \
56       __gen_unpack_uint(__tmp_ulod, cl, start, end);                           \
57       (out) = ((float)__tmp_ulod) / 256.0;                                     \
58    } while (0)
59 
60 #define __gen_unpack_slod(out, cl, start, end)                                 \
61    do {                                                                        \
62       int32_t __tmp_slod;                                                      \
63       __gen_unpack_sint(__tmp_slod, cl, start, end);                           \
64       (out) = ((float)__tmp_slod) / 256.0;                                     \
65    } while (0)
66 
67 #define __gen_unpack_float(out, cl, start, end)                                \
68    do {                                                                        \
69       uint32_t __tmp_float;                                                    \
70       __gen_unpack_uint(__tmp_float, cl, start, end);                          \
71       (out) = uif(__tmp_float);                                                \
72    } while (0)
73 
74 #define __gen_unpack_padded(out, cl, start, end)                               \
75    do {                                                                        \
76       uint32_t __tmp_padded;                                                   \
77       __gen_unpack_uint(__tmp_padded, cl, start, end);                         \
78       (out) = (2 * (__tmp_padded >> 5) + 1) << (__tmp_padded & 0b11111);       \
79    } while (0)
80 
81 #define PREFIX1(A)          MALI_##A
82 #define PREFIX2(A, B)       MALI_##A##_##B
83 #define PREFIX4(A, B, C, D) MALI_##A##_##B##_##C##_##D
84 
85 #define pan_pack(dst, T, name)                                                 \
86    for (UNUSED struct PREFIX1(T) name = {PREFIX2(T, header)},                  \
87                                  *_loop_terminate = &name;                     \
88         __builtin_expect(_loop_terminate != NULL, 1); ({                       \
89            PREFIX2(T, pack)((dst), &name);                                     \
90            _loop_terminate = NULL;                                             \
91         }))
92 
93 #define pan_pack_nodefaults(dst, T, name)                                      \
94    for (UNUSED struct PREFIX1(T) name = {0}, *_loop_terminate = &name;         \
95         __builtin_expect(_loop_terminate != NULL, 1); ({                       \
96            PREFIX2(T, pack)((dst), &name);                                     \
97            _loop_terminate = NULL;                                             \
98         }))
99 
100 #define pan_cast_and_pack(dst, T, name)                                        \
101    pan_pack((PREFIX2(T, PACKED_T) *)dst, T, name)
102 
103 #define pan_cast_and_pack_nodefaults(dst, T, name)                             \
104    pan_pack_nodefaults((PREFIX2(T, PACKED_T) *)dst, T, name)
105 
106 #define pan_unpack(src, T, name)                                               \
107    UNUSED struct PREFIX1(T) name;                                              \
108    PREFIX2(T, unpack)((src), &name)
109 
110 #define pan_cast_and_unpack(src, T, name)                                      \
111    pan_unpack((const PREFIX2(T, PACKED_T) *)(src), T, name)
112 
113 #define pan_print(fp, T, var, indent) PREFIX2(T, print)(fp, &(var), indent)
114 
115 #define pan_size(T)      PREFIX2(T, LENGTH)
116 #define pan_alignment(T) PREFIX2(T, ALIGN)
117 
118 #define pan_section_offset(A, S) PREFIX4(A, SECTION, S, OFFSET)
119 
120 #define pan_section_ptr(base, A, S)                                            \
121    ((PREFIX4(A, SECTION, S, PACKED_TYPE) *)((uint8_t *)(base) +                \
122                                             pan_section_offset(A, S)))
123 
124 #define pan_section_pack(dst, A, S, name)                                      \
125    for (UNUSED PREFIX4(A, SECTION, S, TYPE)                                    \
126            name = {PREFIX4(A, SECTION, S, header)},                            \
127            *_loop_terminate = (void *)(dst);                                   \
128         __builtin_expect(_loop_terminate != NULL, 1); ({                       \
129            PREFIX4(A, SECTION, S, pack)(pan_section_ptr(dst, A, S), &name);    \
130            _loop_terminate = NULL;                                             \
131         }))
132 
133 #define pan_section_unpack(src, A, S, name)                                    \
134    UNUSED PREFIX4(A, SECTION, S, TYPE) name;                                   \
135    PREFIX4(A, SECTION, S, unpack)(pan_section_ptr(src, A, S), &name)
136 
137 #define pan_section_print(fp, A, S, var, indent)                               \
138    PREFIX4(A, SECTION, S, print)(fp, &(var), indent)
139 
140 static inline void
pan_merge_helper(uint32_t * dst,const uint32_t * src,size_t bytes)141 pan_merge_helper(uint32_t *dst, const uint32_t *src, size_t bytes)
142 {
143    assert((bytes & 3) == 0);
144 
145    for (unsigned i = 0; i < (bytes / 4); ++i)
146       dst[i] |= src[i];
147 }
148 
149 #define pan_merge(packed1, packed2, type)                                      \
150    pan_merge_helper((packed1).opaque, (packed2).opaque, pan_size(type))
151 
152 static inline const char *
mali_component_swizzle(unsigned val)153 mali_component_swizzle(unsigned val)
154 {
155    static const char swiz_name[] = "RGBA01??";
156    static char out_str[5], *outp;
157    outp = out_str;
158    for (int i = 0; i < 12; i += 3) {
159       *outp++ = swiz_name[(val >> i) & 7];
160    }
161    *outp = 0;
162    return out_str;
163 }
164 
165 /* From presentations, 16x16 tiles externally. Use shift for fast computation
166  * of tile numbers. */
167 
168 #define MALI_TILE_SHIFT  4
169 #define MALI_TILE_LENGTH (1 << MALI_TILE_SHIFT)
170 
171 #endif
172