mesa: added _mesa_format_row_stride()
[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 #if FEATURE_EXT_texture_sRGB
266 {
267 MESA_FORMAT_SRGB8,
268 GL_RGB,
269 GL_UNSIGNED_NORMALIZED,
270 8, 8, 8, 0,
271 0, 0, 0, 0, 0,
272 1, 1, 3
273 },
274 {
275 MESA_FORMAT_SRGBA8,
276 GL_RGBA,
277 GL_UNSIGNED_NORMALIZED,
278 8, 8, 8, 8,
279 0, 0, 0, 0, 0,
280 1, 1, 4
281 },
282 {
283 MESA_FORMAT_SARGB8,
284 GL_RGBA,
285 GL_UNSIGNED_NORMALIZED,
286 8, 8, 8, 8,
287 0, 0, 0, 0, 0,
288 1, 1, 4
289 },
290 {
291 MESA_FORMAT_SL8,
292 GL_LUMINANCE_ALPHA,
293 GL_UNSIGNED_NORMALIZED,
294 0, 0, 0, 8,
295 8, 0, 0, 0, 0,
296 1, 1, 2
297 },
298 {
299 MESA_FORMAT_SLA8,
300 GL_LUMINANCE_ALPHA,
301 GL_UNSIGNED_NORMALIZED,
302 0, 0, 0, 8,
303 8, 0, 0, 0, 0,
304 1, 1, 2
305 },
306 #if FEATURE_texture_s3tc
307 {
308 MESA_FORMAT_SRGB_DXT1, /* Name */
309 GL_RGB, /* BaseFormat */
310 GL_UNSIGNED_NORMALIZED, /* DataType */
311 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */
312 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
313 4, 4, 8 /* 8 bytes per 4x4 block */
314 },
315 {
316 MESA_FORMAT_SRGBA_DXT1,
317 GL_RGBA,
318 GL_UNSIGNED_NORMALIZED,
319 4, 4, 4, 4,
320 0, 0, 0, 0, 0,
321 4, 4, 8 /* 8 bytes per 4x4 block */
322 },
323 {
324 MESA_FORMAT_SRGBA_DXT3,
325 GL_RGBA,
326 GL_UNSIGNED_NORMALIZED,
327 4, 4, 4, 4,
328 0, 0, 0, 0, 0,
329 4, 4, 16 /* 16 bytes per 4x4 block */
330 },
331 {
332 MESA_FORMAT_SRGBA_DXT5,
333 GL_RGBA,
334 GL_UNSIGNED_NORMALIZED,
335 4, 4, 4, 4,
336 0, 0, 0, 0, 0,
337 4, 4, 16 /* 16 bytes per 4x4 block */
338 },
339 #endif
340 #endif
341
342 #if FEATURE_texture_fxt1
343 {
344 MESA_FORMAT_RGB_FXT1,
345 GL_RGB,
346 GL_UNSIGNED_NORMALIZED,
347 8, 8, 8, 0,
348 0, 0, 0, 0, 0,
349 8, 4, 16 /* 16 bytes per 8x4 block */
350 },
351 {
352 MESA_FORMAT_RGBA_FXT1,
353 GL_RGBA,
354 GL_UNSIGNED_NORMALIZED,
355 8, 8, 8, 8,
356 0, 0, 0, 0, 0,
357 8, 4, 16 /* 16 bytes per 8x4 block */
358 },
359 #endif
360
361 #if FEATURE_texture_s3tc
362 {
363 MESA_FORMAT_RGB_DXT1, /* Name */
364 GL_RGB, /* BaseFormat */
365 GL_UNSIGNED_NORMALIZED, /* DataType */
366 4, 4, 4, 0, /* approx Red/Green/Blue/AlphaBits */
367 0, 0, 0, 0, 0, /* Lum/Int/Index/Depth/StencilBits */
368 4, 4, 8 /* 8 bytes per 4x4 block */
369 },
370 {
371 MESA_FORMAT_RGBA_DXT1,
372 GL_RGBA,
373 GL_UNSIGNED_NORMALIZED,
374 4, 4, 4, 4,
375 0, 0, 0, 0, 0,
376 4, 4, 8 /* 8 bytes per 4x4 block */
377 },
378 {
379 MESA_FORMAT_RGBA_DXT3,
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_DXT5,
388 GL_RGBA,
389 GL_UNSIGNED_NORMALIZED,
390 4, 4, 4, 4,
391 0, 0, 0, 0, 0,
392 4, 4, 16 /* 16 bytes per 4x4 block */
393 },
394 #endif
395
396 {
397 MESA_FORMAT_RGBA_FLOAT32,
398 GL_RGBA,
399 GL_FLOAT,
400 32, 32, 32, 32,
401 0, 0, 0, 0, 0,
402 1, 1, 16
403 },
404 {
405 MESA_FORMAT_RGBA_FLOAT16,
406 GL_RGBA,
407 GL_FLOAT,
408 16, 16, 16, 16,
409 0, 0, 0, 0, 0,
410 1, 1, 8
411 },
412 {
413 MESA_FORMAT_RGB_FLOAT32,
414 GL_RGB,
415 GL_FLOAT,
416 32, 32, 32, 0,
417 0, 0, 0, 0, 0,
418 1, 1, 12
419 },
420 {
421 MESA_FORMAT_RGB_FLOAT16,
422 GL_RGB,
423 GL_FLOAT,
424 16, 16, 16, 0,
425 0, 0, 0, 0, 0,
426 1, 1, 6
427 },
428 {
429 MESA_FORMAT_ALPHA_FLOAT32,
430 GL_ALPHA,
431 GL_FLOAT,
432 0, 0, 0, 32,
433 0, 0, 0, 0, 0,
434 1, 1, 4
435 },
436 {
437 MESA_FORMAT_ALPHA_FLOAT16,
438 GL_ALPHA,
439 GL_FLOAT,
440 0, 0, 0, 16,
441 0, 0, 0, 0, 0,
442 1, 1, 2
443 },
444 {
445 MESA_FORMAT_LUMINANCE_FLOAT32,
446 GL_ALPHA,
447 GL_FLOAT,
448 0, 0, 0, 0,
449 32, 0, 0, 0, 0,
450 1, 1, 4
451 },
452 {
453 MESA_FORMAT_LUMINANCE_FLOAT16,
454 GL_ALPHA,
455 GL_FLOAT,
456 0, 0, 0, 0,
457 16, 0, 0, 0, 0,
458 1, 1, 2
459 },
460 {
461 MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32,
462 GL_LUMINANCE_ALPHA,
463 GL_FLOAT,
464 0, 0, 0, 32,
465 32, 0, 0, 0, 0,
466 1, 1, 8
467 },
468 {
469 MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16,
470 GL_LUMINANCE_ALPHA,
471 GL_FLOAT,
472 0, 0, 0, 16,
473 16, 0, 0, 0, 0,
474 1, 1, 4
475 },
476 {
477 MESA_FORMAT_INTENSITY_FLOAT32,
478 GL_INTENSITY,
479 GL_FLOAT,
480 0, 0, 0, 0,
481 0, 32, 0, 0, 0,
482 1, 1, 4
483 },
484 {
485 MESA_FORMAT_INTENSITY_FLOAT16,
486 GL_INTENSITY,
487 GL_FLOAT,
488 0, 0, 0, 0,
489 0, 16, 0, 0, 0,
490 1, 1, 2
491 },
492
493 {
494 MESA_FORMAT_DUDV8,
495 GL_DUDV_ATI,
496 GL_SIGNED_NORMALIZED,
497 0, 0, 0, 0,
498 0, 0, 0, 0, 0,
499 1, 1, 2
500 },
501
502 {
503 MESA_FORMAT_SIGNED_RGBA8888,
504 GL_RGBA,
505 GL_SIGNED_NORMALIZED,
506 8, 8, 8, 8,
507 0, 0, 0, 0, 0,
508 1, 1, 4
509 },
510 {
511 MESA_FORMAT_SIGNED_RGBA8888_REV,
512 GL_RGBA,
513 GL_SIGNED_NORMALIZED,
514 8, 8, 8, 8,
515 0, 0, 0, 0, 0,
516 1, 1, 4
517 },
518
519 };
520
521
522
523 static const struct gl_format_info *
524 _mesa_get_format_info(gl_format format)
525 {
526 const struct gl_format_info *info = &format_info[format];
527 assert(info->Name == format);
528 return info;
529 }
530
531
532 GLuint
533 _mesa_get_format_bytes(gl_format format)
534 {
535 const struct gl_format_info *info = _mesa_get_format_info(format);
536 ASSERT(info->BytesPerBlock);
537 return info->BytesPerBlock;
538 }
539
540
541 GLint
542 _mesa_get_format_bits(gl_format format, GLenum pname)
543 {
544 const struct gl_format_info *info = _mesa_get_format_info(format);
545
546 switch (pname) {
547 case GL_TEXTURE_RED_SIZE:
548 return info->RedBits;
549 case GL_TEXTURE_GREEN_SIZE:
550 return info->GreenBits;
551 case GL_TEXTURE_BLUE_SIZE:
552 return info->BlueBits;
553 case GL_TEXTURE_ALPHA_SIZE:
554 return info->AlphaBits;
555 case GL_TEXTURE_INTENSITY_SIZE:
556 return info->IntensityBits;
557 case GL_TEXTURE_LUMINANCE_SIZE:
558 return info->LuminanceBits;
559 case GL_TEXTURE_INDEX_SIZE_EXT:
560 return info->IndexBits;
561 case GL_TEXTURE_DEPTH_SIZE_ARB:
562 return info->DepthBits;
563 case GL_TEXTURE_STENCIL_SIZE_EXT:
564 return info->StencilBits;
565 default:
566 _mesa_problem(NULL, "bad pname in _mesa_get_format_bits()");
567 return 0;
568 }
569 }
570
571
572 GLenum
573 _mesa_get_format_datatype(gl_format format)
574 {
575 const struct gl_format_info *info = _mesa_get_format_info(format);
576 return info->DataType;
577 }
578
579
580 GLenum
581 _mesa_get_format_base_format(gl_format format)
582 {
583 const struct gl_format_info *info = _mesa_get_format_info(format);
584 return info->BaseFormat;
585 }
586
587
588 GLboolean
589 _mesa_is_format_compressed(gl_format format)
590 {
591 const struct gl_format_info *info = _mesa_get_format_info(format);
592 return info->BlockWidth > 1 || info->BlockHeight > 1;
593 }
594
595
596 /**
597 * Return number of bytes needed to store an image of the given size
598 * in the given format.
599 */
600 GLuint
601 _mesa_format_image_size(gl_format format, GLsizei width,
602 GLsizei height, GLsizei depth)
603 {
604 const struct gl_format_info *info = _mesa_get_format_info(format);
605 /* Strictly speaking, a conditional isn't needed here */
606 if (info->BlockWidth > 1 || info->BlockHeight > 1) {
607 /* compressed format */
608 const GLuint bw = info->BlockWidth, bh = info->BlockHeight;
609 const GLuint wblocks = (width + bw - 1) / bw;
610 const GLuint hblocks = (height + bh - 1) / bh;
611 const GLuint sz = wblocks * hblocks * info->BytesPerBlock;
612 return sz;
613 }
614 else {
615 /* non-compressed */
616 const GLuint sz = width * height * depth * info->BytesPerBlock;
617 return sz;
618 }
619 }
620
621
622
623 GLint
624 _mesa_format_row_stride(gl_format format, GLsizei width)
625 {
626 const struct gl_format_info *info = _mesa_get_format_info(format);
627 /* Strictly speaking, a conditional isn't needed here */
628 if (info->BlockWidth > 1 || info->BlockHeight > 1) {
629 /* compressed format */
630 const GLuint bw = info->BlockWidth;
631 const GLuint wblocks = (width + bw - 1) / bw;
632 const GLint stride = wblocks * info->BytesPerBlock;
633 return stride;
634 }
635 else {
636 const GLint stride = width * info->BytesPerBlock;
637 return stride;
638 }
639 }
640
641
642
643 /**
644 * Do sanity checking of the format info table.
645 */
646 void
647 _mesa_test_formats(void)
648 {
649 GLuint i;
650
651 assert(Elements(format_info) == MESA_FORMAT_COUNT);
652
653 for (i = 0; i < MESA_FORMAT_COUNT; i++) {
654 const struct gl_format_info *info = _mesa_get_format_info(i);
655 assert(info);
656
657 assert(info->Name == i);
658
659 if (info->Name == MESA_FORMAT_NONE)
660 continue;
661
662 if (info->BlockWidth == 1 && info->BlockHeight == 1) {
663 if (info->RedBits > 0) {
664 GLuint t = info->RedBits + info->GreenBits
665 + info->BlueBits + info->AlphaBits;
666 assert(t / 8 == info->BytesPerBlock);
667 }
668 }
669
670 assert(info->DataType == GL_UNSIGNED_NORMALIZED ||
671 info->DataType == GL_SIGNED_NORMALIZED ||
672 info->DataType == GL_UNSIGNED_INT ||
673 info->DataType == GL_FLOAT);
674
675 if (info->BaseFormat == GL_RGB) {
676 assert(info->RedBits > 0);
677 assert(info->GreenBits > 0);
678 assert(info->BlueBits > 0);
679 assert(info->AlphaBits == 0);
680 assert(info->LuminanceBits == 0);
681 assert(info->IntensityBits == 0);
682 }
683 else if (info->BaseFormat == GL_RGBA) {
684 assert(info->RedBits > 0);
685 assert(info->GreenBits > 0);
686 assert(info->BlueBits > 0);
687 assert(info->AlphaBits > 0);
688 assert(info->LuminanceBits == 0);
689 assert(info->IntensityBits == 0);
690 }
691 else if (info->BaseFormat == GL_LUMINANCE) {
692 assert(info->RedBits == 0);
693 assert(info->GreenBits == 0);
694 assert(info->BlueBits == 0);
695 assert(info->AlphaBits == 0);
696 assert(info->LuminanceBits > 0);
697 assert(info->IntensityBits == 0);
698 }
699 else if (info->BaseFormat == GL_INTENSITY) {
700 assert(info->RedBits == 0);
701 assert(info->GreenBits == 0);
702 assert(info->BlueBits == 0);
703 assert(info->AlphaBits == 0);
704 assert(info->LuminanceBits == 0);
705 assert(info->IntensityBits > 0);
706 }
707
708 }
709 }
710
711
712 /**
713 * XXX possible replacement for _mesa_format_to_type_and_comps()
714 * Used for mipmap generation.
715 */
716 void
717 _mesa_format_to_type_and_comps2(gl_format format,
718 GLenum *datatype, GLuint *comps)
719 {
720 const struct gl_format_info *info = _mesa_get_format_info(format);
721
722 /* We use a bunch of heuristics here. If this gets too ugly we could
723 * just encode the info the in the gl_format_info structures.
724 */
725 if (info->BaseFormat == GL_RGB ||
726 info->BaseFormat == GL_RGBA ||
727 info->BaseFormat == GL_ALPHA) {
728 *comps = ((info->RedBits > 0) +
729 (info->GreenBits > 0) +
730 (info->BlueBits > 0) +
731 (info->AlphaBits > 0));
732
733 if (info->DataType== GL_FLOAT) {
734 if (info->RedBits == 32)
735 *datatype = GL_FLOAT;
736 else
737 *datatype = GL_HALF_FLOAT;
738 }
739 else if (info->GreenBits == 3) {
740 *datatype = GL_UNSIGNED_BYTE_3_3_2;
741 }
742 else if (info->GreenBits == 4) {
743 *datatype = GL_UNSIGNED_SHORT_4_4_4_4;
744 }
745 else if (info->GreenBits == 6) {
746 *datatype = GL_UNSIGNED_SHORT_5_6_5;
747 }
748 else if (info->GreenBits == 5) {
749 *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV;
750 }
751 else if (info->RedBits == 8) {
752 *datatype = GL_UNSIGNED_BYTE;
753 }
754 else {
755 ASSERT(info->RedBits == 16);
756 *datatype = GL_UNSIGNED_SHORT;
757 }
758 }
759 else if (info->BaseFormat == GL_LUMINANCE ||
760 info->BaseFormat == GL_LUMINANCE_ALPHA) {
761 *comps = ((info->LuminanceBits > 0) +
762 (info->AlphaBits > 0));
763 if (info->LuminanceBits == 8) {
764 *datatype = GL_UNSIGNED_BYTE;
765 }
766 else if (info->LuminanceBits == 16) {
767 *datatype = GL_UNSIGNED_SHORT;
768 }
769 else {
770 *datatype = GL_FLOAT;
771 }
772 }
773 else if (info->BaseFormat == GL_INTENSITY) {
774 *comps = 1;
775 if (info->IntensityBits == 8) {
776 *datatype = GL_UNSIGNED_BYTE;
777 }
778 else if (info->IntensityBits == 16) {
779 *datatype = GL_UNSIGNED_SHORT;
780 }
781 else {
782 *datatype = GL_FLOAT;
783 }
784 }
785 else if (info->BaseFormat == GL_COLOR_INDEX) {
786 *comps = 1;
787 *datatype = GL_UNSIGNED_BYTE;
788 }
789 else if (info->BaseFormat == GL_DEPTH_COMPONENT) {
790 *comps = 1;
791 if (info->DepthBits == 16) {
792 *datatype = GL_UNSIGNED_SHORT;
793 }
794 else {
795 ASSERT(info->DepthBits == 32);
796 *datatype = GL_UNSIGNED_INT;
797 }
798 }
799 else if (info->BaseFormat == GL_DEPTH_STENCIL) {
800 *comps = 1;
801 *datatype = GL_UNSIGNED_INT;
802 }
803 else if (info->BaseFormat == GL_YCBCR_MESA) {
804 *comps = 2;
805 *datatype = GL_UNSIGNED_SHORT;
806 }
807 else if (info->BaseFormat == GL_DUDV_ATI) {
808 *comps = 2;
809 *datatype = GL_BYTE;
810 }
811 else {
812 /* any other formats? */
813 ASSERT(0);
814 *comps = 1;
815 *datatype = GL_UNSIGNED_BYTE;
816 }
817 }