added pointer to Vincent (OpenGL ES implementation)
[mesa.git] / src / mesa / main / texutil_tmp.h
1 /**
2 * \file texutil_tmp.h
3 * Texture conversion templates.
4 *
5 * \author Gareth Hughes
6 *
7 * For 2D and 3D texture images, we generate functions for
8 * - conversion without pixel unpacking and standard stride
9 * - conversion without pixel unpacking and non-standard stride
10 * - conversion with pixel unpacking and standard stride
11 * - conversion with pixel unpacking and non-standard stride
12 *
13 * Macros which need to be defined before including this file:
14 * - \c TAG(x) - the function name wrapper
15 * - \c DST_TYPE - the destination texel data type (GLuint, GLushort, etc)
16 * - \c DST_TEXELS_PER_DWORD - number of destination texels that'll fit in 4 bytes
17 * - \c CONVERT_TEXEL - code to convert from source to destination texel
18 * - \c CONVER_TEXEL_DWORD - if multiple texels fit in 4 bytes, this macros
19 * will convert/store multiple texels at once
20 * - \c CONVERT_DIRECT - if defined, just memcpy texels from source to destination
21 * - \c SRC_TEXEL_BYTES - bytes per source texel
22 * - \c PRESERVE_DST_TYPE - if defined, don't undefined these macros at end
23 *
24 * \sa convert_func.
25 */
26
27 /*
28 * Mesa 3-D graphics library
29 * Version: 4.0.2
30 *
31 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
32 *
33 * Permission is hereby granted, free of charge, to any person obtaining a
34 * copy of this software and associated documentation files (the "Software"),
35 * to deal in the Software without restriction, including without limitation
36 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
37 * and/or sell copies of the Software, and to permit persons to whom the
38 * Software is furnished to do so, subject to the following conditions:
39 *
40 * The above copyright notice and this permission notice shall be included
41 * in all copies or substantial portions of the Software.
42 *
43 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
44 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
46 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
47 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
48 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
49 */
50
51
52 #define DST_TEXEL_BYTES (4 / DST_TEXELS_PER_DWORD)
53 #define DST_ROW_BYTES (convert->width * DST_TEXEL_BYTES)
54 #define DST_ROW_STRIDE (convert->dstImageWidth * DST_TEXEL_BYTES)
55 #define DST_IMG_STRIDE (convert->dstImageWidth * \
56 convert->dstImageHeight * DST_TEXEL_BYTES)
57
58
59 /***************************************************************/
60 /** \name Doesn't require pixelstore attributes or stride
61 *
62 * \code width == dstImageWidth \endcode
63 * and
64 * \code height == dstImageHeight \endcode
65 * if applicable.
66 */
67 /*@{*/
68
69 /** \sa convert_func */
70 static GLboolean
71 TAG(texsubimage2d)( const struct convert_info *convert )
72 {
73 const GLubyte *src = (const GLubyte *)convert->srcImage;
74 GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
75 (convert->yoffset * convert->dstImageWidth +
76 convert->xoffset) * DST_TEXEL_BYTES);
77
78 #if DEBUG_TEXUTIL
79 _mesa_debug( NULL, __FUNCTION__ "\n" );
80 #endif
81
82 #ifdef CONVERT_DIRECT
83 MEMCPY( dst, src, convert->height * DST_ROW_BYTES );
84 #else
85 {
86 const GLint texels = convert->width * convert->height;
87 const GLint dwords = texels / DST_TEXELS_PER_DWORD;
88 const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD;
89 GLint i;
90 for ( i = 0 ; i < dwords ; i++ ) {
91 CONVERT_TEXEL_DWORD( *dst++, src );
92 src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
93 }
94 for ( i = 0; i < leftover; i++ ) {
95 CONVERT_TEXEL( *dst++, src );
96 src += SRC_TEXEL_BYTES;
97 }
98 }
99 #endif
100
101 return GL_TRUE;
102 }
103
104 /** \sa convert_func */
105 static GLboolean
106 TAG(texsubimage3d)( const struct convert_info *convert )
107 {
108 const GLubyte *src = (const GLubyte *)convert->srcImage;
109 GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
110 ((convert->zoffset * convert->height +
111 convert->yoffset) * convert->width +
112 convert->xoffset) * DST_TEXEL_BYTES);
113 #if DEBUG_TEXUTIL
114 _mesa_debug( NULL, __FUNCTION__ "\n" );
115 #endif
116
117 #ifdef CONVERT_DIRECT
118 MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_BYTES );
119 #else
120 {
121 const GLint texels = convert->width * convert->height * convert->depth;
122 const GLint dwords = texels / DST_TEXELS_PER_DWORD;
123 const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD;
124 GLint i;
125 for ( i = 0 ; i < dwords ; i++ ) {
126 CONVERT_TEXEL_DWORD( *dst++, src );
127 src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
128 }
129 for ( i = 0; i < leftover; i++ ) {
130 CONVERT_TEXEL( *dst++, src );
131 src += SRC_TEXEL_BYTES;
132 }
133 }
134 #endif
135
136 return GL_TRUE;
137 }
138
139 /*@}*/
140
141
142 /***************************************************************/
143 /** \name Requires stride but no pixelstore attributes
144 *
145 * \code width != dstImageWidth \endcode
146 * or
147 * \code height != dstImageHeight \endcode
148 * if applicable.
149 */
150 /*@{*/
151
152 /** \sa convert_func */
153 static GLboolean
154 TAG(texsubimage2d_stride)( const struct convert_info *convert )
155 {
156 const GLubyte *src = (const GLubyte *)convert->srcImage;
157 DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
158 (convert->yoffset * convert->dstImageWidth +
159 convert->xoffset) * DST_TEXEL_BYTES);
160 GLint adjust;
161 GLint row, col;
162
163 adjust = convert->dstImageWidth - convert->width;
164
165 #if DEBUG_TEXUTIL
166 _mesa_debug( NULL, __FUNCTION__ ":\n" );
167 _mesa_debug( NULL, " x=%d y=%d w=%d h=%d s=%d\n",
168 convert->xoffset, convert->yoffset, convert->width,
169 convert->height, convert->dstImageWidth );
170 _mesa_debug( NULL, " adjust=%d\n", adjust );
171 #endif
172
173 for ( row = 0 ; row < convert->height ; row++ ) {
174 for ( col = 0 ; col < convert->width ; col++ ) {
175 CONVERT_TEXEL( *dst++, src );
176 src += SRC_TEXEL_BYTES;
177 }
178 dst += adjust;
179 }
180
181 return GL_TRUE;
182 }
183
184 /** \sa convert_func */
185 static GLboolean
186 TAG(texsubimage3d_stride)( const struct convert_info *convert )
187 {
188 const GLubyte *src = (const GLubyte *)convert->srcImage;
189 DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
190 ((convert->zoffset * convert->dstImageHeight +
191 convert->yoffset) * convert->dstImageWidth +
192 convert->xoffset) * DST_TEXEL_BYTES);
193 GLint adjust;
194 GLint row, col, img;
195
196 adjust = convert->dstImageWidth - convert->width;
197
198 #if DEBUG_TEXUTIL
199 _mesa_debug( NULL, __FUNCTION__ ":\n" );
200 _mesa_debug( NULL, " x=%d y=%d w=%d h=%d s=%d\n",
201 convert->xoffset, convert->yoffset, convert->width,
202 convert->height, convert->dstImageWidth );
203 _mesa_debug( NULL, " adjust=%d\n", adjust );
204 #endif
205
206 for ( img = 0 ; img < convert->depth ; img++ ) {
207 for ( row = 0 ; row < convert->height ; row++ ) {
208 for ( col = 0 ; col < convert->width ; col++ ) {
209 CONVERT_TEXEL( *dst++, src );
210 src += SRC_TEXEL_BYTES;
211 }
212 dst += adjust;
213 }
214 /* FIXME: ... */
215 }
216
217 return GL_TRUE;
218 }
219
220 /*@}*/
221
222
223 /***************************************************************/
224 /** \name Requires pixelstore attributes but no stride.
225 *
226 * \code width == dstImageWidth \endcode
227 * and
228 * \code height == dstImageHeight \endcode
229 * if applicable.
230 */
231 /*@{*/
232
233 /** \sa convert_func */
234 static GLboolean
235 TAG(texsubimage2d_unpack)( const struct convert_info *convert )
236 {
237 const GLubyte *src = (const GLubyte *)
238 _mesa_image_address( convert->unpacking, convert->srcImage,
239 convert->width, convert->height,
240 convert->format, convert->type, 0, 0, 0 );
241 const GLint srcRowStride =
242 _mesa_image_row_stride( convert->unpacking, convert->width,
243 convert->format, convert->type );
244 GLint row, col;
245
246 #if DEBUG_TEXUTIL
247 _mesa_debug( NULL, __FUNCTION__ "\n" );
248 #endif
249
250 if (convert->width & (DST_TEXELS_PER_DWORD - 1)) {
251 /* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2
252 * or width = 2 and texels/dword = 4).
253 */
254 DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
255 (convert->yoffset * convert->width +
256 convert->xoffset) * DST_TEXEL_BYTES);
257 for ( row = 0 ; row < convert->height ; row++ ) {
258 const GLubyte *srcRow = src;
259 for ( col = 0; col < convert->width; col++ ) {
260 CONVERT_TEXEL(*dst, src);
261 src += SRC_TEXEL_BYTES;
262 }
263 src = srcRow + srcRowStride;
264 }
265 }
266 else {
267 /* the common case */
268 GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
269 (convert->yoffset * convert->width +
270 convert->xoffset) * DST_TEXEL_BYTES);
271 for ( row = 0 ; row < convert->height ; row++ ) {
272 #ifdef CONVERT_DIRECT
273 MEMCPY( dst, src, DST_ROW_STRIDE );
274 src += srcRowStride;
275 dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
276 #else
277 const GLubyte *srcRow = src;
278 for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
279 CONVERT_TEXEL_DWORD( *dst++, src );
280 src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
281 }
282 src = srcRow + srcRowStride;
283 #endif
284 }
285 }
286
287 return GL_TRUE;
288 }
289
290 /** \sa convert_func */
291 static GLboolean
292 TAG(texsubimage3d_unpack)( const struct convert_info *convert )
293 {
294 const GLubyte *src = (const GLubyte *)
295 _mesa_image_address( convert->unpacking, convert->srcImage,
296 convert->width, convert->height,
297 convert->format, convert->type, 0, 0, 0 );
298 const GLint srcImgStride = (const GLubyte *)
299 _mesa_image_address( convert->unpacking, convert->srcImage,
300 convert->width, convert->height,
301 convert->format, convert->type, 1, 0, 0 ) - src;
302 const GLint srcRowStride =
303 _mesa_image_row_stride( convert->unpacking, convert->width,
304 convert->format, convert->type );
305 GLint row, col, img;
306
307 #if DEBUG_TEXUTIL
308 _mesa_debug( NULL, __FUNCTION__ "\n" );
309 #endif
310
311 if (convert->width & (DST_TEXELS_PER_DWORD - 1)) {
312 /* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2
313 * or width = 2 and texels/dword = 4).
314 */
315 DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
316 ((convert->zoffset * convert->height +
317 convert->yoffset) * convert->width +
318 convert->xoffset) * DST_TEXEL_BYTES);
319 for ( img = 0 ; img < convert->depth ; img++ ) {
320 const GLubyte *srcImage = src;
321 for ( row = 0 ; row < convert->height ; row++ ) {
322 const GLubyte *srcRow = src;
323 for ( col = 0; col < convert->width; col++ ) {
324 CONVERT_TEXEL(*dst, src);
325 src += SRC_TEXEL_BYTES;
326 }
327 src = srcRow + srcRowStride;
328 }
329 src = srcImage + srcImgStride;
330 }
331 }
332 else {
333 /* the common case */
334 GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
335 ((convert->zoffset * convert->height +
336 convert->yoffset) * convert->width +
337 convert->xoffset) * DST_TEXEL_BYTES);
338 for ( img = 0 ; img < convert->depth ; img++ ) {
339 const GLubyte *srcImage = src;
340 for ( row = 0 ; row < convert->height ; row++ ) {
341 #ifdef CONVERT_DIRECT
342 MEMCPY( dst, src, DST_ROW_STRIDE );
343 src += srcRowStride;
344 dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
345 #else
346 const GLubyte *srcRow = src;
347 for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
348 CONVERT_TEXEL_DWORD( *dst++, src );
349 src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
350 }
351 src = srcRow + srcRowStride;
352 #endif
353 }
354 src = srcImage + srcImgStride;
355 }
356 }
357
358 return GL_TRUE;
359 }
360
361 /*@}*/
362
363
364 /***************************************************************/
365 /** \name Requires pixelstore attributes and stride.
366 *
367 * \code width != dstImageWidth \endcode
368 * or
369 * \code height != dstImageHeight \endcode
370 * if applicable.
371 */
372 /*@{*/
373
374 /** \sa convert_func */
375 static GLboolean
376 TAG(texsubimage2d_stride_unpack)( const struct convert_info *convert )
377 {
378 const GLubyte *src = (const GLubyte *)
379 _mesa_image_address( convert->unpacking, convert->srcImage,
380 convert->width, convert->height,
381 convert->format, convert->type, 0, 0, 0 );
382 const GLint srcRowStride =
383 _mesa_image_row_stride( convert->unpacking, convert->width,
384 convert->format, convert->type );
385 DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
386 (convert->yoffset * convert->dstImageWidth +
387 convert->xoffset) * DST_TEXEL_BYTES);
388 GLint row;
389 #ifndef CONVERT_DIRECT
390 GLint adjust = convert->dstImageWidth - convert->width;
391 #endif
392
393 #if DEBUG_TEXUTIL
394 _mesa_debug( NULL, __FUNCTION__ ":\n" );
395 _mesa_debug( NULL, " x=%d y=%d w=%d h=%d s=%d\n",
396 convert->xoffset, convert->yoffset, convert->width,
397 convert->height, convert->dstImageWidth );
398 #endif
399
400 for ( row = 0 ; row < convert->height ; row++ ) {
401 #ifdef CONVERT_DIRECT
402 MEMCPY( dst, src, DST_ROW_BYTES );
403 src += srcRowStride;
404 dst += convert->dstImageWidth;
405 #else
406 const GLubyte *srcRow = src;
407 GLint col;
408 for ( col = 0 ; col < convert->width ; col++ ) {
409 CONVERT_TEXEL( *dst++, src );
410 src += SRC_TEXEL_BYTES;
411 }
412 src = srcRow + srcRowStride;
413 dst += adjust;
414 #endif
415 }
416
417 return GL_TRUE;
418 }
419
420 /** \sa convert_func */
421 static GLboolean
422 TAG(texsubimage3d_stride_unpack)( const struct convert_info *convert )
423 {
424 const GLubyte *src = (const GLubyte *)
425 _mesa_image_address( convert->unpacking, convert->srcImage,
426 convert->width, convert->height,
427 convert->format, convert->type, 0, 0, 0 );
428 const GLint srcImgStride = (const GLubyte *)
429 _mesa_image_address( convert->unpacking, convert->srcImage,
430 convert->width, convert->height,
431 convert->format, convert->type, 1, 0, 0 ) - src;
432 const GLint srcRowStride =
433 _mesa_image_row_stride( convert->unpacking, convert->width,
434 convert->format, convert->type );
435 DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
436 ((convert->zoffset * convert->dstImageHeight +
437 convert->yoffset) * convert->dstImageWidth +
438 convert->xoffset) * DST_TEXEL_BYTES);
439 GLint row, img;
440 #ifndef CONVERT_DIRECT
441 GLint adjust = convert->dstImageWidth - convert->width;
442 #endif
443
444 #if DEBUG_TEXUTIL
445 _mesa_debug( NULL, __FUNCTION__ ":\n" );
446 _mesa_debug( NULL, " x=%d y=%d w=%d h=%d s=%d\n",
447 convert->xoffset, convert->yoffset, convert->width,
448 convert->height, convert->dstImageWidth );
449 #endif
450
451 for ( img = 0 ; img < convert->depth ; img++ ) {
452 const GLubyte *srcImage = src;
453 for ( row = 0 ; row < convert->height ; row++ ) {
454 #ifdef CONVERT_DIRECT
455 MEMCPY( dst, src, DST_ROW_BYTES );
456 src += srcRowStride;
457 dst += convert->dstImageWidth;
458 #else
459 const GLubyte *srcRow = src;
460 GLint col;
461 for ( col = 0 ; col < convert->width ; col++ ) {
462 CONVERT_TEXEL( *dst++, src );
463 src += SRC_TEXEL_BYTES;
464 }
465 src = srcRow + srcRowStride;
466 dst += adjust;
467 #endif
468 }
469 src = srcImage + srcImgStride;
470 }
471
472 return GL_TRUE;
473 }
474
475 /*@}*/
476
477
478 /***********************************************************************/
479 /** \name Conversion function tables
480 */
481 /*@{*/
482
483 /**
484 * 2D texture conversion functions table.
485 *
486 * \sa convert_func.
487 */
488 static convert_func TAG(texsubimage2d_tab)[] = {
489 TAG(texsubimage2d),
490 TAG(texsubimage2d_stride),
491 TAG(texsubimage2d_unpack),
492 TAG(texsubimage2d_stride_unpack),
493 };
494
495 /**
496 * 3D texture conversion functions table.
497 *
498 * \sa convert_func.
499 */
500 static convert_func TAG(texsubimage3d_tab)[] = {
501 TAG(texsubimage3d),
502 TAG(texsubimage3d_stride),
503 TAG(texsubimage3d_unpack),
504 TAG(texsubimage3d_stride_unpack),
505 };
506
507 /*@}*/
508
509
510 #ifndef PRESERVE_DST_TYPE
511 #undef DST_TYPE
512 #undef DST_TEXELS_PER_DWORD
513 #endif
514
515 #undef SRC_TEXEL_BYTES
516 #undef DST_TEXEL_BYTES
517 #undef DST_ROW_BYTES
518 #undef DST_ROW_STRIDE
519
520 #undef CONVERT_TEXEL
521 #undef CONVERT_TEXEL_DWORD
522 #undef CONVERT_DIRECT
523
524 #undef TAG
525
526 #undef PRESERVE_DST_TYPE