c98e90d1c3dda88290b8f41eeda8f29b8f5f0927
[mesa.git] / src / mesa / main / formats.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.7
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2008-2009 VMware, Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 #include "imports.h"
28 #include "formats.h"
29 #include "config.h"
30 #include "texstore.h"
31
32
33 /**
34 * Info about each format.
35 * These must be in the same order as the MESA_FORMAT_* enums so that
36 * we can do lookups without searching.
37 */
38 static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
39 {
40 {
41 MESA_FORMAT_NONE, /* Name */
42 GL_NONE, /* BaseFormat */
43 GL_NONE, /* DataType */
44 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
45 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
46 0, 0, 0 /* BlockWidth/Height,Bytes */
47 },
48 {
49 MESA_FORMAT_RGBA8888, /* Name */
50 GL_RGBA, /* BaseFormat */
51 GL_UNSIGNED_NORMALIZED, /* DataType */
52 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */
53 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
54 1, 1, 4 /* BlockWidth/Height,Bytes */
55 },
56 {
57 MESA_FORMAT_RGBA8888_REV, /* Name */
58 GL_RGBA, /* BaseFormat */
59 GL_UNSIGNED_NORMALIZED, /* DataType */
60 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */
61 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
62 1, 1, 4 /* BlockWidth/Height,Bytes */
63 },
64 {
65 MESA_FORMAT_ARGB8888, /* Name */
66 GL_RGBA, /* BaseFormat */
67 GL_UNSIGNED_NORMALIZED, /* DataType */
68 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */
69 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
70 1, 1, 4 /* BlockWidth/Height,Bytes */
71 },
72 {
73 MESA_FORMAT_ARGB8888_REV, /* Name */
74 GL_RGBA, /* BaseFormat */
75 GL_UNSIGNED_NORMALIZED, /* DataType */
76 8, 8, 8, 8, /* Red/Green/Blue/AlphaBits */
77 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
78 1, 1, 4 /* BlockWidth/Height,Bytes */
79 },
80 {
81 MESA_FORMAT_RGB888, /* Name */
82 GL_RGB, /* BaseFormat */
83 GL_UNSIGNED_NORMALIZED, /* DataType */
84 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */
85 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
86 1, 1, 3 /* BlockWidth/Height,Bytes */
87 },
88 {
89 MESA_FORMAT_BGR888, /* Name */
90 GL_RGB, /* BaseFormat */
91 GL_UNSIGNED_NORMALIZED, /* DataType */
92 8, 8, 8, 0, /* Red/Green/Blue/AlphaBits */
93 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
94 1, 1, 3 /* BlockWidth/Height,Bytes */
95 },
96 {
97 MESA_FORMAT_RGB565, /* Name */
98 GL_RGB, /* BaseFormat */
99 GL_UNSIGNED_NORMALIZED, /* DataType */
100 5, 6, 5, 0, /* Red/Green/Blue/AlphaBits */
101 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
102 1, 1, 2 /* BlockWidth/Height,Bytes */
103 },
104 {
105 MESA_FORMAT_RGB565_REV, /* Name */
106 GL_RGB, /* BaseFormat */
107 GL_UNSIGNED_NORMALIZED, /* DataType */
108 5, 6, 5, 0, /* Red/Green/Blue/AlphaBits */
109 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
110 1, 1, 2 /* BlockWidth/Height,Bytes */
111 },
112 {
113 MESA_FORMAT_ARGB4444, /* Name */
114 GL_RGBA, /* BaseFormat */
115 GL_UNSIGNED_NORMALIZED, /* DataType */
116 4, 4, 4, 4, /* Red/Green/Blue/AlphaBits */
117 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
118 1, 1, 2 /* BlockWidth/Height,Bytes */
119 },
120 {
121 MESA_FORMAT_ARGB4444_REV, /* Name */
122 GL_RGBA, /* BaseFormat */
123 GL_UNSIGNED_NORMALIZED, /* DataType */
124 4, 4, 4, 4, /* Red/Green/Blue/AlphaBits */
125 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
126 1, 1, 2 /* BlockWidth/Height,Bytes */
127 },
128 {
129 MESA_FORMAT_RGBA5551, /* Name */
130 GL_RGBA, /* BaseFormat */
131 GL_UNSIGNED_NORMALIZED, /* DataType */
132 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */
133 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
134 1, 1, 2 /* BlockWidth/Height,Bytes */
135 },
136 {
137 MESA_FORMAT_ARGB1555, /* Name */
138 GL_RGBA, /* BaseFormat */
139 GL_UNSIGNED_NORMALIZED, /* DataType */
140 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */
141 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
142 1, 1, 2 /* BlockWidth/Height,Bytes */
143 },
144 {
145 MESA_FORMAT_ARGB1555_REV, /* Name */
146 GL_RGBA, /* BaseFormat */
147 GL_UNSIGNED_NORMALIZED, /* DataType */
148 5, 5, 5, 1, /* Red/Green/Blue/AlphaBits */
149 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
150 1, 1, 2 /* BlockWidth/Height,Bytes */
151 },
152 {
153 MESA_FORMAT_AL88, /* Name */
154 GL_LUMINANCE_ALPHA, /* BaseFormat */
155 GL_UNSIGNED_NORMALIZED, /* DataType */
156 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */
157 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
158 1, 1, 2 /* BlockWidth/Height,Bytes */
159 },
160 {
161 MESA_FORMAT_AL88_REV, /* Name */
162 GL_LUMINANCE_ALPHA, /* BaseFormat */
163 GL_UNSIGNED_NORMALIZED, /* DataType */
164 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */
165 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
166 1, 1, 2 /* BlockWidth/Height,Bytes */
167 },
168 {
169 MESA_FORMAT_RGB332, /* Name */
170 GL_RGB, /* BaseFormat */
171 GL_UNSIGNED_NORMALIZED, /* DataType */
172 3, 3, 2, 0, /* Red/Green/Blue/AlphaBits */
173 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
174 1, 1, 1 /* BlockWidth/Height,Bytes */
175 },
176 {
177 MESA_FORMAT_A8, /* Name */
178 GL_ALPHA, /* BaseFormat */
179 GL_UNSIGNED_NORMALIZED, /* DataType */
180 0, 0, 0, 8, /* Red/Green/Blue/AlphaBits */
181 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
182 1, 1, 1 /* BlockWidth/Height,Bytes */
183 },
184 {
185 MESA_FORMAT_L8, /* Name */
186 GL_LUMINANCE, /* BaseFormat */
187 GL_UNSIGNED_NORMALIZED, /* DataType */
188 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
189 8, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
190 1, 1, 1 /* BlockWidth/Height,Bytes */
191 },
192 {
193 MESA_FORMAT_I8, /* Name */
194 GL_INTENSITY, /* BaseFormat */
195 GL_UNSIGNED_NORMALIZED, /* DataType */
196 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
197 0, 8, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
198 1, 1, 1 /* BlockWidth/Height,Bytes */
199 },
200 {
201 MESA_FORMAT_CI8, /* Name */
202 GL_COLOR_INDEX, /* BaseFormat */
203 GL_UNSIGNED_INT, /* DataType */
204 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
205 0, 0, 8, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
206 1, 1, 1 /* BlockWidth/Height,Bytes */
207 },
208 {
209 MESA_FORMAT_YCBCR, /* Name */
210 GL_YCBCR_MESA, /* BaseFormat */
211 GL_UNSIGNED_NORMALIZED, /* DataType */
212 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
213 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
214 1, 1, 2 /* BlockWidth/Height,Bytes */
215 },
216 {
217 MESA_FORMAT_YCBCR_REV, /* Name */
218 GL_YCBCR_MESA, /* BaseFormat */
219 GL_UNSIGNED_NORMALIZED, /* DataType */
220 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
221 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
222 1, 1, 2 /* BlockWidth/Height,Bytes */
223 },
224 {
225 MESA_FORMAT_Z24_S8, /* Name */
226 GL_DEPTH_STENCIL, /* BaseFormat */
227 GL_UNSIGNED_INT, /* DataType */
228 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
229 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */
230 1, 1, 4 /* BlockWidth/Height,Bytes */
231 },
232 {
233 MESA_FORMAT_S8_Z24, /* Name */
234 GL_DEPTH_STENCIL, /* BaseFormat */
235 GL_UNSIGNED_INT, /* DataType */
236 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
237 0, 0, 0, 24, 8, /* Lum/Int/Index/Depth/StencilBits */
238 1, 1, 4 /* BlockWidth/Height,Bytes */
239 },
240 {
241 MESA_FORMAT_Z16, /* Name */
242 GL_DEPTH_COMPONENT, /* BaseFormat */
243 GL_UNSIGNED_INT, /* DataType */
244 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
245 0, 0, 0, 16, 0, /* Lum/Int/Index/Depth/StencilBits */
246 1, 1, 2 /* BlockWidth/Height,Bytes */
247 },
248 {
249 MESA_FORMAT_Z32, /* Name */
250 GL_DEPTH_COMPONENT, /* BaseFormat */
251 GL_UNSIGNED_INT, /* DataType */
252 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
253 0, 0, 0, 32, 0, /* Lum/Int/Index/Depth/StencilBits */
254 1, 1, 4 /* BlockWidth/Height,Bytes */
255 },
256 {
257 MESA_FORMAT_S8, /* Name */
258 GL_STENCIL_INDEX, /* BaseFormat */
259 GL_UNSIGNED_INT, /* DataType */
260 0, 0, 0, 0, /* Red/Green/Blue/AlphaBits */
261 0, 0, 0, 0, 8, /* Lum/Int/Index/Depth/StencilBits */
262 1, 1, 1 /* BlockWidth/Height,Bytes */
263 },
264 {
265 MESA_FORMAT_SRGB8,
266 GL_RGB,
267 GL_UNSIGNED_NORMALIZED,
268 8, 8, 8, 0,
269 0, 0, 0, 0, 0,
270 1, 1, 3
271 },
272 {
273 MESA_FORMAT_SRGBA8,
274 GL_RGBA,
275 GL_UNSIGNED_NORMALIZED,
276 8, 8, 8, 8,
277 0, 0, 0, 0, 0,
278 1, 1, 4
279 },
280 {
281 MESA_FORMAT_SARGB8,
282 GL_RGBA,
283 GL_UNSIGNED_NORMALIZED,
284 8, 8, 8, 8,
285 0, 0, 0, 0, 0,
286 1, 1, 4
287 },
288 {
289 MESA_FORMAT_SL8,
290 GL_LUMINANCE_ALPHA,
291 GL_UNSIGNED_NORMALIZED,
292 0, 0, 0, 8,
293 8, 0, 0, 0, 0,
294 1, 1, 2
295 },
296 {
297 MESA_FORMAT_SLA8,
298 GL_LUMINANCE_ALPHA,
299 GL_UNSIGNED_NORMALIZED,
300 0, 0, 0, 8,
301 8, 0, 0, 0, 0,
302 1, 1, 2
303 },
304 {
305 MESA_FORMAT_SRGB_DXT1, /* Name */
306 GL_RGB, /* BaseFormat */
307 GL_UNSIGNED_NORMALIZED, /* DataType */
308 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */
309 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
310 4, 4, 8 /* 8 bytes per 4x4 block */
311 },
312 {
313 MESA_FORMAT_SRGBA_DXT1,
314 GL_RGBA,
315 GL_UNSIGNED_NORMALIZED,
316 4, 4, 4, 4,
317 0, 0, 0, 0, 0,
318 4, 4, 8 /* 8 bytes per 4x4 block */
319 },
320 {
321 MESA_FORMAT_SRGBA_DXT3,
322 GL_RGBA,
323 GL_UNSIGNED_NORMALIZED,
324 4, 4, 4, 4,
325 0, 0, 0, 0, 0,
326 4, 4, 16 /* 16 bytes per 4x4 block */
327 },
328 {
329 MESA_FORMAT_SRGBA_DXT5,
330 GL_RGBA,
331 GL_UNSIGNED_NORMALIZED,
332 4, 4, 4, 4,
333 0, 0, 0, 0, 0,
334 4, 4, 16 /* 16 bytes per 4x4 block */
335 },
336
337 {
338 MESA_FORMAT_RGB_FXT1,
339 GL_RGB,
340 GL_UNSIGNED_NORMALIZED,
341 8, 8, 8, 0,
342 0, 0, 0, 0, 0,
343 8, 4, 16 /* 16 bytes per 8x4 block */
344 },
345 {
346 MESA_FORMAT_RGBA_FXT1,
347 GL_RGBA,
348 GL_UNSIGNED_NORMALIZED,
349 8, 8, 8, 8,
350 0, 0, 0, 0, 0,
351 8, 4, 16 /* 16 bytes per 8x4 block */
352 },
353
354 {
355 MESA_FORMAT_RGB_DXT1, /* Name */
356 GL_RGB, /* BaseFormat */
357 GL_UNSIGNED_NORMALIZED, /* DataType */
358 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */
359 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
360 4, 4, 8 /* 8 bytes per 4x4 block */
361 },
362 {
363 MESA_FORMAT_RGBA_DXT1,
364 GL_RGBA,
365 GL_UNSIGNED_NORMALIZED,
366 4, 4, 4, 4,
367 0, 0, 0, 0, 0,
368 4, 4, 8 /* 8 bytes per 4x4 block */
369 },
370 {
371 MESA_FORMAT_RGBA_DXT3,
372 GL_RGBA,
373 GL_UNSIGNED_NORMALIZED,
374 4, 4, 4, 4,
375 0, 0, 0, 0, 0,
376 4, 4, 16 /* 16 bytes per 4x4 block */
377 },
378 {
379 MESA_FORMAT_RGBA_DXT5,
380 GL_RGBA,
381 GL_UNSIGNED_NORMALIZED,
382 4, 4, 4, 4,
383 0, 0, 0, 0, 0,
384 4, 4, 16 /* 16 bytes per 4x4 block */
385 },
386 {
387 MESA_FORMAT_RGBA_FLOAT32,
388 GL_RGBA,
389 GL_FLOAT,
390 32, 32, 32, 32,
391 0, 0, 0, 0, 0,
392 1, 1, 16
393 },
394 {
395 MESA_FORMAT_RGBA_FLOAT16,
396 GL_RGBA,
397 GL_FLOAT,
398 16, 16, 16, 16,
399 0, 0, 0, 0, 0,
400 1, 1, 8
401 },
402 {
403 MESA_FORMAT_RGB_FLOAT32,
404 GL_RGB,
405 GL_FLOAT,
406 32, 32, 32, 0,
407 0, 0, 0, 0, 0,
408 1, 1, 12
409 },
410 {
411 MESA_FORMAT_RGB_FLOAT16,
412 GL_RGB,
413 GL_FLOAT,
414 16, 16, 16, 0,
415 0, 0, 0, 0, 0,
416 1, 1, 6
417 },
418 {
419 MESA_FORMAT_ALPHA_FLOAT32,
420 GL_ALPHA,
421 GL_FLOAT,
422 0, 0, 0, 32,
423 0, 0, 0, 0, 0,
424 1, 1, 4
425 },
426 {
427 MESA_FORMAT_ALPHA_FLOAT16,
428 GL_ALPHA,
429 GL_FLOAT,
430 0, 0, 0, 16,
431 0, 0, 0, 0, 0,
432 1, 1, 2
433 },
434 {
435 MESA_FORMAT_LUMINANCE_FLOAT32,
436 GL_ALPHA,
437 GL_FLOAT,
438 0, 0, 0, 0,
439 32, 0, 0, 0, 0,
440 1, 1, 4
441 },
442 {
443 MESA_FORMAT_LUMINANCE_FLOAT16,
444 GL_ALPHA,
445 GL_FLOAT,
446 0, 0, 0, 0,
447 16, 0, 0, 0, 0,
448 1, 1, 2
449 },
450 {
451 MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32,
452 GL_LUMINANCE_ALPHA,
453 GL_FLOAT,
454 0, 0, 0, 32,
455 32, 0, 0, 0, 0,
456 1, 1, 8
457 },
458 {
459 MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16,
460 GL_LUMINANCE_ALPHA,
461 GL_FLOAT,
462 0, 0, 0, 16,
463 16, 0, 0, 0, 0,
464 1, 1, 4
465 },
466 {
467 MESA_FORMAT_INTENSITY_FLOAT32,
468 GL_INTENSITY,
469 GL_FLOAT,
470 0, 0, 0, 0,
471 0, 32, 0, 0, 0,
472 1, 1, 4
473 },
474 {
475 MESA_FORMAT_INTENSITY_FLOAT16,
476 GL_INTENSITY,
477 GL_FLOAT,
478 0, 0, 0, 0,
479 0, 16, 0, 0, 0,
480 1, 1, 2
481 },
482 {
483 MESA_FORMAT_DUDV8,
484 GL_DUDV_ATI,
485 GL_SIGNED_NORMALIZED,
486 0, 0, 0, 0,
487 0, 0, 0, 0, 0,
488 1, 1, 2
489 },
490 {
491 MESA_FORMAT_SIGNED_RGBA8888,
492 GL_RGBA,
493 GL_SIGNED_NORMALIZED,
494 8, 8, 8, 8,
495 0, 0, 0, 0, 0,
496 1, 1, 4
497 },
498 {
499 MESA_FORMAT_SIGNED_RGBA8888_REV,
500 GL_RGBA,
501 GL_SIGNED_NORMALIZED,
502 8, 8, 8, 8,
503 0, 0, 0, 0, 0,
504 1, 1, 4
505 },
506
507 };
508
509
510
511 static const struct gl_format_info *
512 _mesa_get_format_info(gl_format format)
513 {
514 const struct gl_format_info *info = &format_info[format];
515 assert(info->Name == format);
516 return info;
517 }
518
519
520 GLuint
521 _mesa_get_format_bytes(gl_format format)
522 {
523 const struct gl_format_info *info = _mesa_get_format_info(format);
524 ASSERT(info->BytesPerBlock);
525 return info->BytesPerBlock;
526 }
527
528
529 GLint
530 _mesa_get_format_bits(gl_format format, GLenum pname)
531 {
532 const struct gl_format_info *info = _mesa_get_format_info(format);
533
534 switch (pname) {
535 case GL_TEXTURE_RED_SIZE:
536 return info->RedBits;
537 case GL_TEXTURE_GREEN_SIZE:
538 return info->GreenBits;
539 case GL_TEXTURE_BLUE_SIZE:
540 return info->BlueBits;
541 case GL_TEXTURE_ALPHA_SIZE:
542 return info->AlphaBits;
543 case GL_TEXTURE_INTENSITY_SIZE:
544 return info->IntensityBits;
545 case GL_TEXTURE_LUMINANCE_SIZE:
546 return info->LuminanceBits;
547 case GL_TEXTURE_INDEX_SIZE_EXT:
548 return info->IndexBits;
549 case GL_TEXTURE_DEPTH_SIZE_ARB:
550 return info->DepthBits;
551 case GL_TEXTURE_STENCIL_SIZE_EXT:
552 return info->StencilBits;
553 default:
554 _mesa_problem(NULL, "bad pname in _mesa_get_format_bits()");
555 return 0;
556 }
557 }
558
559
560 GLenum
561 _mesa_get_format_datatype(gl_format format)
562 {
563 const struct gl_format_info *info = _mesa_get_format_info(format);
564 return info->DataType;
565 }
566
567
568 GLenum
569 _mesa_get_format_base_format(gl_format format)
570 {
571 const struct gl_format_info *info = _mesa_get_format_info(format);
572 return info->BaseFormat;
573 }
574
575
576 GLboolean
577 _mesa_is_format_compressed(gl_format format)
578 {
579 const struct gl_format_info *info = _mesa_get_format_info(format);
580 return info->BlockWidth > 1 || info->BlockHeight > 1;
581 }
582
583
584 /**
585 * Return number of bytes needed to store an image of the given size
586 * in the given format.
587 */
588 GLuint
589 _mesa_format_image_size(gl_format format, GLsizei width,
590 GLsizei height, GLsizei depth)
591 {
592 const struct gl_format_info *info = _mesa_get_format_info(format);
593 /* Strictly speaking, a conditional isn't needed here */
594 if (info->BlockWidth > 1 || info->BlockHeight > 1) {
595 /* compressed format */
596 const GLuint bw = info->BlockWidth, bh = info->BlockHeight;
597 const GLuint wblocks = (width + bw - 1) / bw;
598 const GLuint hblocks = (height + bh - 1) / bh;
599 const GLuint sz = wblocks * hblocks * info->BytesPerBlock;
600 return sz;
601 }
602 else {
603 /* non-compressed */
604 const GLuint sz = width * height * depth * info->BytesPerBlock;
605 return sz;
606 }
607 }
608
609
610
611 GLint
612 _mesa_format_row_stride(gl_format format, GLsizei width)
613 {
614 const struct gl_format_info *info = _mesa_get_format_info(format);
615 /* Strictly speaking, a conditional isn't needed here */
616 if (info->BlockWidth > 1 || info->BlockHeight > 1) {
617 /* compressed format */
618 const GLuint bw = info->BlockWidth;
619 const GLuint wblocks = (width + bw - 1) / bw;
620 const GLint stride = wblocks * info->BytesPerBlock;
621 return stride;
622 }
623 else {
624 const GLint stride = width * info->BytesPerBlock;
625 return stride;
626 }
627 }
628
629
630
631 /**
632 * Do sanity checking of the format info table.
633 */
634 void
635 _mesa_test_formats(void)
636 {
637 GLuint i;
638
639 assert(Elements(format_info) == MESA_FORMAT_COUNT);
640
641 for (i = 0; i < MESA_FORMAT_COUNT; i++) {
642 const struct gl_format_info *info = _mesa_get_format_info(i);
643 assert(info);
644
645 assert(info->Name == i);
646
647 if (info->Name == MESA_FORMAT_NONE)
648 continue;
649
650 if (info->BlockWidth == 1 && info->BlockHeight == 1) {
651 if (info->RedBits > 0) {
652 GLuint t = info->RedBits + info->GreenBits
653 + info->BlueBits + info->AlphaBits;
654 assert(t / 8 == info->BytesPerBlock);
655 }
656 }
657
658 assert(info->DataType == GL_UNSIGNED_NORMALIZED ||
659 info->DataType == GL_SIGNED_NORMALIZED ||
660 info->DataType == GL_UNSIGNED_INT ||
661 info->DataType == GL_FLOAT);
662
663 if (info->BaseFormat == GL_RGB) {
664 assert(info->RedBits > 0);
665 assert(info->GreenBits > 0);
666 assert(info->BlueBits > 0);
667 assert(info->AlphaBits == 0);
668 assert(info->LuminanceBits == 0);
669 assert(info->IntensityBits == 0);
670 }
671 else if (info->BaseFormat == GL_RGBA) {
672 assert(info->RedBits > 0);
673 assert(info->GreenBits > 0);
674 assert(info->BlueBits > 0);
675 assert(info->AlphaBits > 0);
676 assert(info->LuminanceBits == 0);
677 assert(info->IntensityBits == 0);
678 }
679 else if (info->BaseFormat == GL_LUMINANCE) {
680 assert(info->RedBits == 0);
681 assert(info->GreenBits == 0);
682 assert(info->BlueBits == 0);
683 assert(info->AlphaBits == 0);
684 assert(info->LuminanceBits > 0);
685 assert(info->IntensityBits == 0);
686 }
687 else if (info->BaseFormat == GL_INTENSITY) {
688 assert(info->RedBits == 0);
689 assert(info->GreenBits == 0);
690 assert(info->BlueBits == 0);
691 assert(info->AlphaBits == 0);
692 assert(info->LuminanceBits == 0);
693 assert(info->IntensityBits > 0);
694 }
695
696 }
697 }
698
699
700 /**
701 * XXX possible replacement for _mesa_format_to_type_and_comps()
702 * Used for mipmap generation.
703 */
704 void
705 _mesa_format_to_type_and_comps2(gl_format format,
706 GLenum *datatype, GLuint *comps)
707 {
708 const struct gl_format_info *info = _mesa_get_format_info(format);
709
710 /* We use a bunch of heuristics here. If this gets too ugly we could
711 * just encode the info the in the gl_format_info structures.
712 */
713 if (info->BaseFormat == GL_RGB ||
714 info->BaseFormat == GL_RGBA ||
715 info->BaseFormat == GL_ALPHA) {
716 *comps = ((info->RedBits > 0) +
717 (info->GreenBits > 0) +
718 (info->BlueBits > 0) +
719 (info->AlphaBits > 0));
720
721 if (info->DataType== GL_FLOAT) {
722 if (info->RedBits == 32)
723 *datatype = GL_FLOAT;
724 else
725 *datatype = GL_HALF_FLOAT;
726 }
727 else if (info->GreenBits == 3) {
728 *datatype = GL_UNSIGNED_BYTE_3_3_2;
729 }
730 else if (info->GreenBits == 4) {
731 *datatype = GL_UNSIGNED_SHORT_4_4_4_4;
732 }
733 else if (info->GreenBits == 6) {
734 *datatype = GL_UNSIGNED_SHORT_5_6_5;
735 }
736 else if (info->GreenBits == 5) {
737 *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV;
738 }
739 else if (info->RedBits == 8) {
740 *datatype = GL_UNSIGNED_BYTE;
741 }
742 else {
743 ASSERT(info->RedBits == 16);
744 *datatype = GL_UNSIGNED_SHORT;
745 }
746 }
747 else if (info->BaseFormat == GL_LUMINANCE ||
748 info->BaseFormat == GL_LUMINANCE_ALPHA) {
749 *comps = ((info->LuminanceBits > 0) +
750 (info->AlphaBits > 0));
751 if (info->LuminanceBits == 8) {
752 *datatype = GL_UNSIGNED_BYTE;
753 }
754 else if (info->LuminanceBits == 16) {
755 *datatype = GL_UNSIGNED_SHORT;
756 }
757 else {
758 *datatype = GL_FLOAT;
759 }
760 }
761 else if (info->BaseFormat == GL_INTENSITY) {
762 *comps = 1;
763 if (info->IntensityBits == 8) {
764 *datatype = GL_UNSIGNED_BYTE;
765 }
766 else if (info->IntensityBits == 16) {
767 *datatype = GL_UNSIGNED_SHORT;
768 }
769 else {
770 *datatype = GL_FLOAT;
771 }
772 }
773 else if (info->BaseFormat == GL_COLOR_INDEX) {
774 *comps = 1;
775 *datatype = GL_UNSIGNED_BYTE;
776 }
777 else if (info->BaseFormat == GL_DEPTH_COMPONENT) {
778 *comps = 1;
779 if (info->DepthBits == 16) {
780 *datatype = GL_UNSIGNED_SHORT;
781 }
782 else {
783 ASSERT(info->DepthBits == 32);
784 *datatype = GL_UNSIGNED_INT;
785 }
786 }
787 else if (info->BaseFormat == GL_DEPTH_STENCIL) {
788 *comps = 1;
789 *datatype = GL_UNSIGNED_INT;
790 }
791 else if (info->BaseFormat == GL_YCBCR_MESA) {
792 *comps = 2;
793 *datatype = GL_UNSIGNED_SHORT;
794 }
795 else if (info->BaseFormat == GL_DUDV_ATI) {
796 *comps = 2;
797 *datatype = GL_BYTE;
798 }
799 else {
800 /* any other formats? */
801 ASSERT(0);
802 *comps = 1;
803 *datatype = GL_UNSIGNED_BYTE;
804 }
805 }