1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON 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
25SOFTWARE, 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/******************************************************************************
34formats
35******************************************************************************/
36
37uint32_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
64uint32_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
85uint32_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
106uint32_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
127uint32_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
150uint32_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
170uint32_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
182uint32_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
204uint32_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
226uint32_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
231uint32_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/******************************************************************************
237image handling
238******************************************************************************/
239
240uint32_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
255uint32_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
268uint32_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
273uint32_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
291void 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