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