1 | /* |
2 | Copyright (c) 2012, Broadcom Europe Ltd |
3 | All rights reserved. |
4 | |
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the following conditions are met: |
7 | * Redistributions of source code must retain the above copyright |
8 | notice, this list of conditions and the following disclaimer. |
9 | * Redistributions in binary form must reproduce the above copyright |
10 | notice, this list of conditions and the following disclaimer in the |
11 | documentation and/or other materials provided with the distribution. |
12 | * Neither the name of the copyright holder nor the |
13 | names of its contributors may be used to endorse or promote products |
14 | derived from this software without specific prior written permission. |
15 | |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY |
20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ |
27 | |
28 | #include "interface/khronos/common/khrn_int_common.h" |
29 | |
30 | #include "interface/khronos/common/khrn_int_image.h" |
31 | #include "interface/khronos/common/khrn_int_util.h" |
32 | |
33 | /****************************************************************************** |
34 | formats |
35 | ******************************************************************************/ |
36 | |
37 | uint32_t khrn_image_get_bpp(KHRN_IMAGE_FORMAT_T format) |
38 | { |
39 | vcos_assert(format != IMAGE_FORMAT_INVALID); |
40 | |
41 | switch (format & IMAGE_FORMAT_COMP_MASK) { |
42 | case IMAGE_FORMAT_UNCOMP: |
43 | switch (format & IMAGE_FORMAT_PIXEL_SIZE_MASK) { |
44 | case IMAGE_FORMAT_1: return 1; |
45 | case IMAGE_FORMAT_4: return 4; |
46 | case IMAGE_FORMAT_8: return 8; |
47 | case IMAGE_FORMAT_16: return 16; |
48 | case IMAGE_FORMAT_24: return 24; |
49 | case IMAGE_FORMAT_32: return 32; |
50 | case IMAGE_FORMAT_64: return 64; |
51 | default: UNREACHABLE(); return 0; |
52 | } |
53 | case IMAGE_FORMAT_ETC1: return 4; |
54 | case IMAGE_FORMAT_YUYV: return 16; |
55 | default: UNREACHABLE(); return 0; |
56 | } |
57 | } |
58 | |
59 | /* |
60 | returns the number of red bits in each pixel of an image of the |
61 | specified format, or zero if not an RGB or RGBA format |
62 | */ |
63 | |
64 | uint32_t khrn_image_get_red_size(KHRN_IMAGE_FORMAT_T format) |
65 | { |
66 | if (khrn_image_is_color(format) && (format & IMAGE_FORMAT_RGB)) { |
67 | switch (format & (IMAGE_FORMAT_PIXEL_SIZE_MASK | IMAGE_FORMAT_PIXEL_LAYOUT_MASK)) { |
68 | case (IMAGE_FORMAT_32 | IMAGE_FORMAT_8888): return 8; |
69 | case (IMAGE_FORMAT_24 | IMAGE_FORMAT_888): return 8; |
70 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_4444): return 4; |
71 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_5551): return 5; |
72 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_565): return 5; |
73 | default: UNREACHABLE(); return 0; |
74 | } |
75 | } else { |
76 | return 0; |
77 | } |
78 | } |
79 | |
80 | /* |
81 | returns the number of green bits in each pixel of an image of the |
82 | specified format, or zero if not an RGB or RGBA format |
83 | */ |
84 | |
85 | uint32_t khrn_image_get_green_size(KHRN_IMAGE_FORMAT_T format) |
86 | { |
87 | if (khrn_image_is_color(format) && (format & IMAGE_FORMAT_RGB)) { |
88 | switch (format & (IMAGE_FORMAT_PIXEL_SIZE_MASK | IMAGE_FORMAT_PIXEL_LAYOUT_MASK)) { |
89 | case (IMAGE_FORMAT_32 | IMAGE_FORMAT_8888): return 8; |
90 | case (IMAGE_FORMAT_24 | IMAGE_FORMAT_888): return 8; |
91 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_4444): return 4; |
92 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_5551): return 5; |
93 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_565): return 6; |
94 | default: UNREACHABLE(); return 0; |
95 | } |
96 | } else { |
97 | return 0; |
98 | } |
99 | } |
100 | |
101 | /* |
102 | returns the number of blue bits in each pixel of an image of the |
103 | specified format, or zero if not an RGB or RGBA format |
104 | */ |
105 | |
106 | uint32_t khrn_image_get_blue_size(KHRN_IMAGE_FORMAT_T format) |
107 | { |
108 | if (khrn_image_is_color(format) && (format & IMAGE_FORMAT_RGB)) { |
109 | switch (format & (IMAGE_FORMAT_PIXEL_SIZE_MASK | IMAGE_FORMAT_PIXEL_LAYOUT_MASK)) { |
110 | case (IMAGE_FORMAT_32 | IMAGE_FORMAT_8888): return 8; |
111 | case (IMAGE_FORMAT_24 | IMAGE_FORMAT_888): return 8; |
112 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_4444): return 4; |
113 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_5551): return 5; |
114 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_565): return 5; |
115 | default: UNREACHABLE(); return 0; |
116 | } |
117 | } else { |
118 | return 0; |
119 | } |
120 | } |
121 | |
122 | /* |
123 | returns the number of alpha bits in each pixel of an image of the |
124 | specified format, or zero if not an alpha or RGBA format |
125 | */ |
126 | |
127 | uint32_t khrn_image_get_alpha_size(KHRN_IMAGE_FORMAT_T format) |
128 | { |
129 | if (khrn_image_is_color(format) && (format & IMAGE_FORMAT_A)) { |
130 | switch (format & (IMAGE_FORMAT_PIXEL_SIZE_MASK | IMAGE_FORMAT_PIXEL_LAYOUT_MASK)) { |
131 | case (IMAGE_FORMAT_32 | IMAGE_FORMAT_8888): return 8; |
132 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_4444): return 4; |
133 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_5551): return 1; |
134 | case (IMAGE_FORMAT_16 | IMAGE_FORMAT_88): return 8; |
135 | case IMAGE_FORMAT_8: return 8; |
136 | case IMAGE_FORMAT_4: return 4; |
137 | case IMAGE_FORMAT_1: return 1; |
138 | default: UNREACHABLE(); return 0; |
139 | } |
140 | } else { |
141 | return 0; |
142 | } |
143 | } |
144 | |
145 | /* |
146 | returns the number of depth bits in each pixel of an image of the |
147 | specified format, or zero if not a depth or depth+stencil format |
148 | */ |
149 | |
150 | uint32_t khrn_image_get_z_size(KHRN_IMAGE_FORMAT_T format) |
151 | { |
152 | if (khrn_image_is_depth(format) && (format & IMAGE_FORMAT_Z)) { |
153 | if (format == DEPTH_32_TLBD || format == DEPTH_COL_64_TLBD) |
154 | return 24; |
155 | switch (format & IMAGE_FORMAT_PIXEL_SIZE_MASK) { |
156 | case IMAGE_FORMAT_32: return 24; |
157 | case IMAGE_FORMAT_16: return 16; |
158 | default: UNREACHABLE(); return 0; |
159 | } |
160 | } else { |
161 | return 0; |
162 | } |
163 | } |
164 | |
165 | /* |
166 | returns the number of stencil bits in each pixel of an image of the |
167 | specified format, or zero if not a depth+stencil format |
168 | */ |
169 | |
170 | uint32_t khrn_image_get_stencil_size(KHRN_IMAGE_FORMAT_T format) |
171 | { |
172 | if (khrn_image_is_depth(format) && (format & IMAGE_FORMAT_STENCIL)) { |
173 | if (format == DEPTH_32_TLBD || format == DEPTH_COL_64_TLBD) |
174 | return 8; |
175 | vcos_assert((format & IMAGE_FORMAT_PIXEL_SIZE_MASK) == IMAGE_FORMAT_32); |
176 | return 8; |
177 | } else { |
178 | return 0; |
179 | } |
180 | } |
181 | |
182 | uint32_t khrn_image_get_log2_brcm2_width(KHRN_IMAGE_FORMAT_T format) |
183 | { |
184 | vcos_assert(khrn_image_is_brcm1(format) || khrn_image_is_brcm2(format)); |
185 | |
186 | switch (format & IMAGE_FORMAT_COMP_MASK) { |
187 | case IMAGE_FORMAT_UNCOMP: |
188 | { |
189 | switch (format & IMAGE_FORMAT_PIXEL_SIZE_MASK) { |
190 | case IMAGE_FORMAT_1: return 6; |
191 | case IMAGE_FORMAT_4: return 4; |
192 | case IMAGE_FORMAT_8: return 3; |
193 | case IMAGE_FORMAT_16: return 3; |
194 | case IMAGE_FORMAT_32: return 2; |
195 | default: UNREACHABLE(); return 0; |
196 | } |
197 | } |
198 | case IMAGE_FORMAT_ETC1: return 3; |
199 | case IMAGE_FORMAT_YUYV: return 3; |
200 | default: UNREACHABLE(); return 0; |
201 | } |
202 | } |
203 | |
204 | uint32_t khrn_image_get_log2_brcm2_height(KHRN_IMAGE_FORMAT_T format) |
205 | { |
206 | vcos_assert(khrn_image_is_brcm1(format) || khrn_image_is_brcm2(format)); |
207 | |
208 | switch (format & IMAGE_FORMAT_COMP_MASK) { |
209 | case IMAGE_FORMAT_UNCOMP: |
210 | { |
211 | switch (format & IMAGE_FORMAT_PIXEL_SIZE_MASK) { |
212 | case IMAGE_FORMAT_1: return 3; |
213 | case IMAGE_FORMAT_4: return 3; |
214 | case IMAGE_FORMAT_8: return 3; |
215 | case IMAGE_FORMAT_16: return 2; |
216 | case IMAGE_FORMAT_32: return 2; |
217 | default: UNREACHABLE(); return 0; |
218 | } |
219 | } |
220 | case IMAGE_FORMAT_ETC1: return 4; |
221 | case IMAGE_FORMAT_YUYV: return 2; |
222 | default: UNREACHABLE(); return 0; |
223 | } |
224 | } |
225 | |
226 | uint32_t khrn_image_get_log2_brcm1_width(KHRN_IMAGE_FORMAT_T format) |
227 | { |
228 | return khrn_image_get_log2_brcm2_width(format) + 3; |
229 | } |
230 | |
231 | uint32_t khrn_image_get_log2_brcm1_height(KHRN_IMAGE_FORMAT_T format) |
232 | { |
233 | return khrn_image_get_log2_brcm2_height(format) + 3; |
234 | } |
235 | |
236 | /****************************************************************************** |
237 | image handling |
238 | ******************************************************************************/ |
239 | |
240 | uint32_t khrn_image_pad_width(KHRN_IMAGE_FORMAT_T format, uint32_t width) |
241 | { |
242 | vcos_assert(format != IMAGE_FORMAT_INVALID); |
243 | |
244 | switch (format & IMAGE_FORMAT_MEM_LAYOUT_MASK) { |
245 | case IMAGE_FORMAT_RSO: |
246 | vcos_assert(!(khrn_image_get_bpp(format) & 7)); |
247 | return width; |
248 | case IMAGE_FORMAT_BRCM1: return round_up(width, (uint32_t) (1 << khrn_image_get_log2_brcm1_width(format))); |
249 | case IMAGE_FORMAT_BRCM2: return round_up(width, (uint32_t) (1 << khrn_image_get_log2_brcm2_width(format))); |
250 | case IMAGE_FORMAT_BRCM4: return round_up(width, 64); |
251 | default: UNREACHABLE(); return 0; |
252 | } |
253 | } |
254 | |
255 | uint32_t khrn_image_pad_height(KHRN_IMAGE_FORMAT_T format, uint32_t height) |
256 | { |
257 | vcos_assert(format != IMAGE_FORMAT_INVALID); |
258 | |
259 | switch (format & IMAGE_FORMAT_MEM_LAYOUT_MASK) { |
260 | case IMAGE_FORMAT_RSO: return height; |
261 | case IMAGE_FORMAT_BRCM1: return round_up(height, (uint32_t) (1 << khrn_image_get_log2_brcm1_height(format))); |
262 | case IMAGE_FORMAT_BRCM2: return round_up(height, (uint32_t) (1 << khrn_image_get_log2_brcm2_height(format))); |
263 | case IMAGE_FORMAT_BRCM4: return round_up(height, 64); |
264 | default: UNREACHABLE(); return 0; |
265 | } |
266 | } |
267 | |
268 | uint32_t khrn_image_get_stride(KHRN_IMAGE_FORMAT_T format, uint32_t width) |
269 | { |
270 | return (khrn_image_pad_width(format, width) * khrn_image_get_bpp(format)) >> 3; |
271 | } |
272 | |
273 | uint32_t khrn_image_get_size(KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height) |
274 | { |
275 | uint32_t size = khrn_image_get_stride(format, width) * khrn_image_pad_height(format, height); |
276 | #ifdef WORKAROUND_HW2038 |
277 | if (khrn_image_is_brcm1(format) || khrn_image_is_brcm2(format)) { |
278 | uint32_t log2_brcm2_width = khrn_image_get_log2_brcm2_width(format); |
279 | uint32_t log2_brcm2_height = khrn_image_get_log2_brcm2_height(format); |
280 | uint32_t width_in_brcm2s = (width + ((1 << log2_brcm2_width) - 1)) >> log2_brcm2_width; |
281 | uint32_t height_in_brcm2s = (height + ((1 << log2_brcm2_height) - 1)) >> log2_brcm2_height; |
282 | uint32_t hw2038_size = |
283 | ((((height_in_brcm2s - 1) >> 3) << 7) + |
284 | ((width_in_brcm2s - 1) >> 3) + 1) << 6; |
285 | size = _max(size, hw2038_size); |
286 | } /* else: can't bind it as a texture */ |
287 | #endif |
288 | return size; |
289 | } |
290 | |
291 | void khrn_image_wrap(KHRN_IMAGE_WRAP_T *wrap, KHRN_IMAGE_FORMAT_T format, uint32_t width, uint32_t height, int32_t stride, void *storage) |
292 | { |
293 | wrap->format = format; |
294 | wrap->width = (uint16_t)width; |
295 | wrap->height = (uint16_t)height; |
296 | wrap->stride = stride; |
297 | wrap->aux = NULL; |
298 | wrap->storage = storage; |
299 | } |
300 | |