]> git.cworth.org Git - apitrace/blob - helpers/glsize.hpp
egl: EGL image trace support
[apitrace] / helpers / glsize.hpp
1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
4  * Copyright 2010 VMware, Inc.
5  * Copyright 2004 IBM Corporation
6  * All Rights Reserved.
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, sub license,
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 (including the next
16  * paragraph) shall be included in all copies or substantial portions of the
17  * Software.
18  * 
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
22  * AUTHORS,
23  * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
25  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26  * SOFTWARE.
27  *
28  **************************************************************************/
29
30 /*
31  * Auxiliary functions to compute the size of array/blob arguments, depending.
32  */
33
34 #ifndef _GL_SIZE_HPP_
35 #define _GL_SIZE_HPP_
36
37
38 #include <string.h>
39
40 #include "os.hpp"
41 #include "glimports.hpp"
42
43
44 static inline size_t
45 _gl_type_size(GLenum type)
46 {
47     switch (type) {
48     case GL_BOOL:
49     case GL_BYTE:
50     case GL_UNSIGNED_BYTE:
51         return 1;
52     case GL_SHORT:
53     case GL_UNSIGNED_SHORT:
54     case GL_2_BYTES:
55     case GL_HALF_FLOAT:
56         return 2;
57     case GL_3_BYTES:
58         return 3;
59     case GL_INT:
60     case GL_UNSIGNED_INT:
61     case GL_FLOAT:
62     case GL_4_BYTES:
63     case GL_FIXED:
64         return 4;
65     case GL_DOUBLE:
66         return 8;
67     default:
68         os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, type);
69         return 0;
70     }
71 }
72
73 static inline void
74 _gl_uniform_size(GLenum type, GLenum &elemType, GLint &numCols, GLint &numRows) {
75     numCols = 1;
76     numRows = 1;
77
78     switch (type) {
79     case GL_FLOAT:
80         elemType = GL_FLOAT;
81         break;
82     case GL_FLOAT_VEC2:
83         elemType = GL_FLOAT;
84         numCols = 2;
85         break;
86     case GL_FLOAT_VEC3:
87         elemType = GL_FLOAT;
88         numCols = 3;
89         break;
90     case GL_FLOAT_VEC4:
91         elemType = GL_FLOAT;
92         numCols = 4;
93         break;
94     case GL_DOUBLE:
95         elemType = GL_DOUBLE;
96         break;
97     case GL_DOUBLE_VEC2:
98         elemType = GL_DOUBLE;
99         numCols = 2;
100         break;
101     case GL_DOUBLE_VEC3:
102         elemType = GL_DOUBLE;
103         numCols = 3;
104         break;
105     case GL_DOUBLE_VEC4:
106         elemType = GL_DOUBLE;
107         numCols = 4;
108         break;
109     case GL_INT:
110         elemType = GL_INT;
111         break;
112     case GL_INT_VEC2:
113         elemType = GL_INT;
114         numCols = 2;
115         break;
116     case GL_INT_VEC3:
117         elemType = GL_INT;
118         numCols = 3;
119         break;
120     case GL_INT_VEC4:
121         elemType = GL_INT;
122         numCols = 4;
123         break;
124     case GL_UNSIGNED_INT:
125         elemType = GL_UNSIGNED_INT;
126         break;
127     case GL_UNSIGNED_INT_VEC2:
128         elemType = GL_UNSIGNED_INT;
129         numCols = 2;
130         break;
131     case GL_UNSIGNED_INT_VEC3:
132         elemType = GL_UNSIGNED_INT;
133         numCols = 3;
134         break;
135     case GL_UNSIGNED_INT_VEC4:
136         elemType = GL_UNSIGNED_INT;
137         numCols = 4;
138         break;
139     case GL_BOOL:
140         elemType = GL_BOOL;
141         break;
142     case GL_BOOL_VEC2:
143         elemType = GL_BOOL;
144         numCols = 2;
145         break;
146     case GL_BOOL_VEC3:
147         elemType = GL_BOOL;
148         numCols = 3;
149         break;
150     case GL_BOOL_VEC4:
151         elemType = GL_BOOL;
152         numCols = 4;
153         break;
154     case GL_FLOAT_MAT2:
155         elemType = GL_FLOAT;
156         numCols = 2;
157         numRows = 2;
158         break;
159     case GL_FLOAT_MAT3:
160         elemType = GL_FLOAT;
161         numCols = 3;
162         numRows = 3;
163         break;
164     case GL_FLOAT_MAT4:
165         elemType = GL_FLOAT;
166         numCols = 4;
167         numRows = 4;
168         break;
169     case GL_FLOAT_MAT2x3:
170         elemType = GL_FLOAT;
171         numCols = 2;
172         numRows = 3;
173         break;
174     case GL_FLOAT_MAT2x4:
175         elemType = GL_FLOAT;
176         numCols = 2;
177         numRows = 4;
178         break;
179     case GL_FLOAT_MAT3x2:
180         elemType = GL_FLOAT;
181         numCols = 3;
182         numRows = 2;
183         break;
184     case GL_FLOAT_MAT3x4:
185         elemType = GL_FLOAT;
186         numCols = 3;
187         numRows = 4;
188         break;
189     case GL_FLOAT_MAT4x2:
190         elemType = GL_FLOAT;
191         numCols = 4;
192         numRows = 2;
193         break;
194     case GL_FLOAT_MAT4x3:
195         elemType = GL_FLOAT;
196         numCols = 4;
197         numRows = 3;
198         break;
199     case GL_DOUBLE_MAT2:
200         elemType = GL_DOUBLE;
201         numCols = 2;
202         numRows = 2;
203         break;
204     case GL_DOUBLE_MAT3:
205         elemType = GL_DOUBLE;
206         numCols = 3;
207         numRows = 3;
208         break;
209     case GL_DOUBLE_MAT4:
210         elemType = GL_DOUBLE;
211         numCols = 4;
212         numRows = 4;
213         break;
214     case GL_DOUBLE_MAT2x3:
215         elemType = GL_DOUBLE;
216         numCols = 2;
217         numRows = 3;
218         break;
219     case GL_DOUBLE_MAT2x4:
220         elemType = GL_DOUBLE;
221         numCols = 2;
222         numRows = 4;
223         break;
224     case GL_DOUBLE_MAT3x2:
225         elemType = GL_DOUBLE;
226         numCols = 3;
227         numRows = 2;
228         break;
229     case GL_DOUBLE_MAT3x4:
230         elemType = GL_DOUBLE;
231         numCols = 3;
232         numRows = 4;
233         break;
234     case GL_DOUBLE_MAT4x2:
235         elemType = GL_DOUBLE;
236         numCols = 4;
237         numRows = 2;
238         break;
239     case GL_DOUBLE_MAT4x3:
240         elemType = GL_DOUBLE;
241         numCols = 4;
242         numRows = 3;
243         break;
244     case GL_SAMPLER_1D:
245     case GL_SAMPLER_2D:
246     case GL_SAMPLER_3D:
247     case GL_SAMPLER_CUBE:
248     case GL_SAMPLER_1D_SHADOW:
249     case GL_SAMPLER_2D_SHADOW:
250     case GL_SAMPLER_1D_ARRAY:
251     case GL_SAMPLER_2D_ARRAY:
252     case GL_SAMPLER_CUBE_MAP_ARRAY:
253     case GL_SAMPLER_1D_ARRAY_SHADOW:
254     case GL_SAMPLER_2D_ARRAY_SHADOW:
255     case GL_SAMPLER_2D_MULTISAMPLE:
256     case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
257     case GL_SAMPLER_CUBE_SHADOW:
258     case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
259     case GL_SAMPLER_BUFFER:
260     case GL_SAMPLER_2D_RECT:
261     case GL_SAMPLER_2D_RECT_SHADOW:
262     case GL_INT_SAMPLER_1D:
263     case GL_INT_SAMPLER_2D:
264     case GL_INT_SAMPLER_3D:
265     case GL_INT_SAMPLER_CUBE:
266     case GL_INT_SAMPLER_1D_ARRAY:
267     case GL_INT_SAMPLER_2D_ARRAY:
268     case GL_INT_SAMPLER_CUBE_MAP_ARRAY:
269     case GL_INT_SAMPLER_2D_MULTISAMPLE:
270     case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
271     case GL_INT_SAMPLER_BUFFER:
272     case GL_INT_SAMPLER_2D_RECT:
273     case GL_UNSIGNED_INT_SAMPLER_1D:
274     case GL_UNSIGNED_INT_SAMPLER_2D:
275     case GL_UNSIGNED_INT_SAMPLER_3D:
276     case GL_UNSIGNED_INT_SAMPLER_CUBE:
277     case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
278     case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
279     case GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY:
280     case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
281     case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
282     case GL_UNSIGNED_INT_SAMPLER_BUFFER:
283     case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
284         elemType = GL_INT;
285         break;
286     default:
287         os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, type);
288         elemType = GL_NONE;
289         numCols = 0;
290         numRows = 0;
291         return;
292     }
293 }
294     
295 static inline size_t
296 _glArrayPointer_size(GLint size, GLenum type, GLsizei stride, GLsizei count)
297 {
298     if (!count) {
299         return 0;
300     }
301
302     size_t elementSize = size*_gl_type_size(type);
303     if (!stride) {
304         stride = (GLsizei)elementSize;
305     }
306
307     return stride*(count - 1) + elementSize;
308 }
309
310 #define _glVertexPointer_size(size, type, stride, count) _glArrayPointer_size(size, type, stride, count)
311 #define _glNormalPointer_size(type, stride, count) _glArrayPointer_size(3, type, stride, count)
312 #define _glColorPointer_size(size, type, stride, count) _glArrayPointer_size(size, type, stride, count)
313 #define _glIndexPointer_size(type, stride, count) _glArrayPointer_size(1, type, stride, count)
314 #define _glTexCoordPointer_size(size, type, stride, count) _glArrayPointer_size(size, type, stride, count)
315 #define _glEdgeFlagPointer_size(stride, count) _glArrayPointer_size(1, GL_BOOL, stride, count)
316 #define _glFogCoordPointer_size(type, stride, count) _glArrayPointer_size(1, type, stride, count)
317 #define _glSecondaryColorPointer_size(size, type, stride, count) _glArrayPointer_size(size, type, stride, count)
318 #define _glVertexAttribPointer_size(size, type, normalized, stride, count) _glArrayPointer_size(size, type, stride, count)
319 #define _glVertexAttribPointerARB_size(size, type, normalized, stride, count) _glArrayPointer_size(size, type, stride, count)
320 #define _glVertexAttribPointerNV_size(size, type, stride, count) _glArrayPointer_size(size, type, stride, count)
321
322 static inline GLuint
323 _glDrawArrays_count(GLint first, GLsizei count)
324 {
325     if (!count) {
326         return 0;
327     }
328     return first + count;
329 }
330
331 #define _glDrawArraysEXT_count _glDrawArrays_count
332
333 static inline GLuint
334 _glDrawElementsBaseVertex_count(GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)
335 {
336     GLvoid *temp = 0;
337     GLint element_array_buffer = 0;
338
339     if (!count) {
340         return 0;
341     }
342
343     _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &element_array_buffer);
344     if (element_array_buffer) {
345         // Read indices from index buffer object
346         GLintptr offset = (GLintptr)indices;
347         GLsizeiptr size = count*_gl_type_size(type);
348         GLvoid *temp = malloc(size);
349         if (!temp) {
350             return 0;
351         }
352         memset(temp, 0, size);
353         _glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, temp);
354         indices = temp;
355     } else {
356         if (!indices) {
357             return 0;
358         }
359     }
360
361     GLuint maxindex = 0;
362     GLsizei i;
363     if (type == GL_UNSIGNED_BYTE) {
364         const GLubyte *p = (const GLubyte *)indices;
365         for (i = 0; i < count; ++i) {
366             if (p[i] > maxindex) {
367                 maxindex = p[i];
368             }
369         }
370     } else if (type == GL_UNSIGNED_SHORT) {
371         const GLushort *p = (const GLushort *)indices;
372         for (i = 0; i < count; ++i) {
373             if (p[i] > maxindex) {
374                 maxindex = p[i];
375             }
376         }
377     } else if (type == GL_UNSIGNED_INT) {
378         const GLuint *p = (const GLuint *)indices;
379         for (i = 0; i < count; ++i) {
380             if (p[i] > maxindex) {
381                 maxindex = p[i];
382             }
383         }
384     } else {
385         os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, type);
386     }
387
388     if (element_array_buffer) {
389         free(temp);
390     }
391
392     maxindex += basevertex;
393
394     return maxindex + 1;
395 }
396
397 #define _glDrawRangeElementsBaseVertex_count(start, end, count, type, indices, basevertex) _glDrawElementsBaseVertex_count(count, type, indices, basevertex)
398
399 #define _glDrawElements_count(count, type, indices) _glDrawElementsBaseVertex_count(count, type, indices, 0);
400 #define _glDrawRangeElements_count(start, end, count, type, indices) _glDrawElements_count(count, type, indices)
401 #define _glDrawRangeElementsEXT_count _glDrawRangeElements_count
402
403 /* FIXME take in consideration instancing */
404 #define _glDrawArraysInstanced_count(first, count, primcount) _glDrawArrays_count(first, count)
405 #define _glDrawElementsInstanced_count(count, type, indices, primcount) _glDrawElements_count(count, type, indices)
406 #define _glDrawElementsInstancedBaseVertex_count(count, type, indices, primcount, basevertex) _glDrawElementsBaseVertex_count(count, type, indices, basevertex)
407 #define _glDrawRangeElementsInstanced_count(start, end, count, type, indices, primcount) _glDrawRangeElements_count(start, end, count, type, indices)
408 #define _glDrawRangeElementsInstancedBaseVertex_count(start, end, count, type, indices, primcount, basevertex) _glDrawRangeElementsBaseVertex_count(start, end, count, type, indices, basevertex)
409
410 #define _glDrawArraysInstancedBaseInstance_count(first, count, primcount, baseinstance) _glDrawArrays_count(first, count)
411 #define _glDrawElementsInstancedBaseInstance_count(count, type, indices, primcount, baseinstance) _glDrawElements_count(count, type, indices)
412 #define _glDrawElementsInstancedBaseVertexBaseInstance_count(count, type, indices, primcount, basevertex, baseinstance) _glDrawElementsBaseVertex_count(count, type, indices, basevertex)
413
414 #define _glDrawArraysInstancedARB_count _glDrawArraysInstanced_count
415 #define _glDrawElementsInstancedARB_count _glDrawElementsInstanced_count
416 #define _glDrawArraysInstancedEXT_count _glDrawArraysInstanced_count
417 #define _glDrawElementsInstancedEXT_count _glDrawElementsInstanced_count
418
419 static inline GLuint
420 _glDrawArraysIndirect_count(const GLvoid *indirect) {
421     os::log("apitrace: warning: %s: unsupported\n", __FUNCTION__);
422     return 0;
423 }
424
425 static inline GLuint
426 _glDrawElementsIndirect_count(GLenum type, const GLvoid *indirect) {
427     os::log("apitrace: warning: %s: unsupported\n", __FUNCTION__);
428     return 0;
429 }
430
431 static inline GLuint
432 _glMultiDrawArrays_count(const GLint *first, const GLsizei *count, GLsizei primcount) {
433     GLuint _count = 0;
434     for (GLsizei prim = 0; prim < primcount; ++prim) {
435         GLuint _count_prim = _glDrawArrays_count(first[prim], count[prim]);
436         _count = std::max(_count, _count_prim);
437     }
438     return _count;
439 }
440
441 static inline GLuint
442 _glMultiDrawElements_count(const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
443     GLuint _count = 0;
444     for (GLsizei prim = 0; prim < primcount; ++prim) {
445         GLuint _count_prim = _glDrawElements_count(count[prim], type, indices[prim]);
446         _count = std::max(_count, _count_prim);
447     }
448     return _count;
449 }
450
451 static inline GLuint
452 _glMultiDrawElementsBaseVertex_count(const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint * basevertex) {
453     GLuint _count = 0;
454     for (GLsizei prim = 0; prim < primcount; ++prim) {
455         GLuint _count_prim = _glDrawElementsBaseVertex_count(count[prim], type, indices[prim], basevertex[prim]);
456         _count = std::max(_count, _count_prim);
457     }
458     return _count;
459 }
460
461 #define _glMultiDrawArraysEXT_count _glMultiDrawArrays_count
462 #define _glMultiDrawElementsEXT_count _glMultiDrawElements_count
463
464 #define _glMultiModeDrawArraysIBM_count(first, count, primcount, modestride) _glMultiDrawArrays_count(first, count, primcount)
465 #define _glMultiModeDrawElementsIBM_count(count, type, indices, primcount, modestride) _glMultiDrawElements_count(count, type, (const GLvoid **)indices, primcount)
466
467
468 static inline size_t
469 _glCallLists_size(GLsizei n, GLenum type)
470 {
471     return n*_gl_type_size(type);
472 }
473
474 static inline size_t
475 _glMap1d_size(GLenum target, GLint stride, GLint order)
476 {
477     if (order < 1) {
478         return 0;
479     }
480
481     GLint channels;
482     switch (target) {
483     case GL_MAP1_INDEX:
484     case GL_MAP1_TEXTURE_COORD_1:
485         channels = 1;
486         break;
487     case GL_MAP1_TEXTURE_COORD_2:
488         channels = 2;
489         break;
490     case GL_MAP1_NORMAL:
491     case GL_MAP1_TEXTURE_COORD_3:
492     case GL_MAP1_VERTEX_3:
493         channels = 3;
494         break;
495     case GL_MAP1_COLOR_4:
496     case GL_MAP1_TEXTURE_COORD_4:
497     case GL_MAP1_VERTEX_4:
498         channels = 4;
499         break;
500     default:
501         os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, target);
502         return 0;
503     }
504
505     if (stride < channels) {
506         return 0;
507     }
508
509     return channels + stride * (order - 1);
510 }
511
512 #define _glMap1f_size _glMap1d_size
513
514 static inline size_t
515 _glMap2d_size(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder)
516 {
517     if (uorder < 1 || vorder < 1) {
518         return 0;
519     }
520
521     GLint channels;
522     switch (target) {
523     case GL_MAP2_INDEX:
524     case GL_MAP2_TEXTURE_COORD_1:
525         channels = 1;
526         break;
527     case GL_MAP2_TEXTURE_COORD_2:
528         channels = 2;
529         break;
530     case GL_MAP2_NORMAL:
531     case GL_MAP2_TEXTURE_COORD_3:
532     case GL_MAP2_VERTEX_3:
533         channels = 3;
534         break;
535     case GL_MAP2_COLOR_4:
536     case GL_MAP2_TEXTURE_COORD_4:
537     case GL_MAP2_VERTEX_4:
538         channels = 4;
539         break;
540     default:
541         os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, target);
542         return 0;
543     }
544
545     if (ustride < channels || vstride < channels) {
546         return 0;
547     }
548
549     return channels + 
550            ustride * (uorder - 1) +
551            vstride * (vorder - 1);
552 }
553
554 #define _glMap2f_size _glMap2d_size
555
556 static inline unsigned
557 _gl_format_channels(GLenum format) {
558     switch (format) {
559     case GL_COLOR_INDEX:
560     case GL_RED:
561     case GL_GREEN:
562     case GL_BLUE:
563     case GL_ALPHA:
564     case GL_INTENSITY:
565     case GL_LUMINANCE:
566     case GL_DEPTH_COMPONENT:
567     case GL_STENCIL_INDEX:
568         return 1;
569     case GL_DEPTH_STENCIL:
570     case GL_LUMINANCE_ALPHA:
571     case GL_RG:
572     case GL_HILO_NV:
573     case GL_DSDT_NV:
574         return 2;
575     case GL_RGB:
576     case GL_BGR:
577     case GL_DSDT_MAG_NV:
578         return 3;
579     case GL_RGBA:
580     case GL_BGRA:
581     case GL_ABGR_EXT:
582     case GL_CMYK_EXT:
583     case GL_DSDT_MAG_VIB_NV:
584         return 4;
585     case GL_CMYKA_EXT:
586         return 5;
587     default:
588         os::log("apitrace: warning: %s: unexpected format GLenum 0x%04X\n", __FUNCTION__, format);
589         return 0;
590     }
591 }
592
593 template<class X>
594 static inline bool
595 _is_pot(X x) {
596     return (x & (x - 1)) == 0;
597 }
598
599 template<class X, class Y>
600 static inline X
601 _align(X x, Y y) {
602     return (x + (y - 1)) & ~(y - 1);
603 }
604
605 static inline size_t
606 _gl_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLboolean has_unpack_subimage) {
607     unsigned num_channels = _gl_format_channels(format);
608
609     unsigned bits_per_pixel;
610     switch (type) {
611     case GL_BITMAP:
612         bits_per_pixel = 1;
613         break;
614     case GL_BYTE:
615     case GL_UNSIGNED_BYTE:
616         bits_per_pixel = 8 * num_channels;
617         break;
618     case GL_SHORT:
619     case GL_UNSIGNED_SHORT:
620     case GL_HALF_FLOAT:
621         bits_per_pixel = 16 * num_channels;
622         break;
623     case GL_INT:
624     case GL_UNSIGNED_INT:
625     case GL_FLOAT:
626         bits_per_pixel = 32 * num_channels;
627         break;
628     case GL_UNSIGNED_BYTE_3_3_2:
629     case GL_UNSIGNED_BYTE_2_3_3_REV:
630         bits_per_pixel = 8;
631         break;
632     case GL_UNSIGNED_SHORT_4_4_4_4:
633     case GL_UNSIGNED_SHORT_4_4_4_4_REV:
634     case GL_UNSIGNED_SHORT_5_5_5_1:
635     case GL_UNSIGNED_SHORT_1_5_5_5_REV:
636     case GL_UNSIGNED_SHORT_5_6_5:
637     case GL_UNSIGNED_SHORT_5_6_5_REV:
638     case GL_UNSIGNED_SHORT_8_8_MESA:
639     case GL_UNSIGNED_SHORT_8_8_REV_MESA:
640         bits_per_pixel = 16;
641         break;
642     case GL_UNSIGNED_INT_8_8_8_8:
643     case GL_UNSIGNED_INT_8_8_8_8_REV:
644     case GL_UNSIGNED_INT_10_10_10_2:
645     case GL_UNSIGNED_INT_2_10_10_10_REV:
646     case GL_UNSIGNED_INT_24_8:
647     case GL_UNSIGNED_INT_10F_11F_11F_REV:
648     case GL_UNSIGNED_INT_5_9_9_9_REV:
649     case GL_UNSIGNED_INT_S8_S8_8_8_NV:
650     case GL_UNSIGNED_INT_8_8_S8_S8_REV_NV:
651         bits_per_pixel = 32;
652         break;
653     case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
654         bits_per_pixel = 64;
655         break;
656     default:
657         os::log("apitrace: warning: %s: unexpected type GLenum 0x%04X\n", __FUNCTION__, type);
658         bits_per_pixel = 0;
659         break;
660     }
661
662     GLint alignment = 4;
663     GLint row_length = 0;
664     GLint image_height = 0;
665     GLint skip_rows = 0;
666     GLint skip_pixels = 0;
667     GLint skip_images = 0;
668
669     _glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
670     if (has_unpack_subimage) {
671         _glGetIntegerv(GL_UNPACK_ROW_LENGTH,   &row_length);
672         _glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &image_height);
673         _glGetIntegerv(GL_UNPACK_SKIP_ROWS,    &skip_rows);
674         _glGetIntegerv(GL_UNPACK_SKIP_PIXELS,  &skip_pixels);
675         _glGetIntegerv(GL_UNPACK_SKIP_IMAGES,  &skip_images);
676     }
677
678     if (row_length <= 0) {
679         row_length = width;
680     }
681
682     size_t row_stride = (row_length*bits_per_pixel + 7)/8;
683
684     if ((GLint)bits_per_pixel < alignment*8 &&
685         (bits_per_pixel & 7) == 0 &&
686         _is_pot(bits_per_pixel)) {
687         row_stride = _align(row_stride, alignment);
688     }
689
690     if (image_height <= 0) {
691         image_height = height;
692     }
693
694     /* XXX: GL_UNPACK_IMAGE_HEIGHT and GL_UNPACK_SKIP_IMAGES should probably
695      * not be considered for pixel rectangles. */
696
697     size_t image_stride = image_height*row_stride;
698
699     size_t size = depth*image_stride;
700
701     size += (skip_pixels*bits_per_pixel + 7)/8;
702     size += skip_rows*row_stride;
703     size += skip_images*image_stride;
704
705     return size;
706 }
707
708 // note that can_unpack_subimage() is generated by gltrace.py
709 #define _glTexImage3D_size(format, type, width, height, depth) _gl_image_size(format, type, width, height, depth, can_unpack_subimage())
710 #define _glTexImage2D_size(format, type, width, height)        _gl_image_size(format, type, width, height, 1, can_unpack_subimage())
711 #define _glTexImage1D_size(format, type, width)                _gl_image_size(format, type, width, 1, 1, can_unpack_subimage())
712
713 #define _glTexSubImage3D_size(format, type, width, height, depth) _glTexImage3D_size(format, type, width, height, depth)
714 #define _glTexSubImage2D_size(format, type, width, height)        _glTexImage2D_size(format, type, width, height)
715 #define _glTexSubImage1D_size(format, type, width)                _glTexImage1D_size(format, type, width)
716
717 #define _glTexImage3DEXT_size _glTexImage3D_size
718 #define _glTexImage2DEXT_size _glTexImage2D_size
719 #define _glTexImage1DEXT_size _glTexImage1D_size
720 #define _glTexSubImage3DEXT_size _glTexSubImage3D_size
721 #define _glTexSubImage2DEXT_size _glTexSubImage2D_size
722 #define _glTexSubImage1DEXT_size _glTexSubImage1D_size
723
724 #define _glTextureImage3DEXT_size _glTexImage3D_size
725 #define _glTextureImage2DEXT_size _glTexImage2D_size
726 #define _glTextureImage1DEXT_size _glTexImage1D_size
727 #define _glTextureSubImage3DEXT_size _glTexSubImage3D_size
728 #define _glTextureSubImage2DEXT_size _glTexSubImage2D_size
729 #define _glTextureSubImage1DEXT_size _glTexSubImage1D_size
730
731 #define _glMultiTexImage3DEXT_size _glTexImage3D_size
732 #define _glMultiTexImage2DEXT_size _glTexImage2D_size
733 #define _glMultiTexImage1DEXT_size _glTexImage1D_size
734 #define _glMultiTexSubImage3DEXT_size _glTexSubImage3D_size
735 #define _glMultiTexSubImage2DEXT_size _glTexSubImage2D_size
736 #define _glMultiTexSubImage1DEXT_size _glTexSubImage1D_size
737
738 #define _glDrawPixels_size(format, type, width, height) _glTexImage2D_size(format, type, width, height)
739 #define _glConvolutionFilter1D_size(format, type, width) _glTexImage1D_size(format, type, width)
740 #define _glConvolutionFilter2D_size(format, type, width, height) _glTexImage2D_size(format, type, width, height)
741 #define _glColorTable_size(format, type, width) _glTexImage1D_size(format, type, width)
742 #define _glColorSubTable_size(format, type, count) _glColorTable_size(format, type, count)
743
744 #define _glBitmap_size(width, height) _glTexImage2D_size(GL_COLOR_INDEX, GL_BITMAP, width, height)
745 #define _glPolygonStipple_size() _glBitmap_size(32, 32)
746
747 static inline size_t
748 _glClearBuffer_size(GLenum buffer)
749 {
750     switch (buffer) {
751     case GL_COLOR:
752     case GL_FRONT:
753     case GL_BACK:
754     case GL_LEFT:
755     case GL_RIGHT:
756     case GL_FRONT_AND_BACK:
757         return 4;
758     case GL_DEPTH:
759     case GL_STENCIL:
760         return 1;
761     default:
762         os::log("apitrace: warning: %s: unexpected buffer GLenum 0x%04X\n", __FUNCTION__, buffer);
763         return 0;
764     }
765 }
766
767 /* 
768  * attribute list, terminated by the given terminator.
769  */
770 template<class T>
771 static inline size_t
772 _AttribList_size(const T *pAttribList, const T terminator = static_cast<T>(0))
773 {
774     size_t size = 0;
775
776     if (pAttribList) {
777         do {
778             ++size;
779         } while (*pAttribList++ != terminator);
780     }
781
782     return size;
783 }
784
785
786 /*
787  * (key, value) attribute list, terminated by the given terminator.
788  */
789 template<class T>
790 static inline size_t
791 _AttribPairList_size(const T *pAttribList, const T terminator = static_cast<T>(0))
792 {
793     size_t size = 0;
794
795     if (pAttribList) {
796         while (pAttribList[size] != terminator) {
797             size += 2;
798         }
799         // terminator also counts
800         ++size;
801     }
802
803     return size;
804 }
805
806
807 #endif /* _GL_SIZE_HPP_ */