1 /* $Id: texutil_tmp.h,v 1.11 2002/09/21 16:51:25 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Gareth Hughes <gareth@valinux.com>
32 * For 2D and 3D texture images, we generate functions for
33 * - conversion without pixel unpacking and standard stride
34 * - conversion without pixel unpacking and non-standard stride
35 * - conversion with pixel unpacking and standard stride
36 * - conversion with pixel unpacking and non-standard stride
39 * Macros which need to be defined before including this file:
40 * TAG(x) - the function name wrapper
41 * DST_TYPE - the destination texel datatype (GLuint, GLushort, etc)
42 * DST_TEXELS_PER_DWORD - number of dest texels that'll fit in 4 bytes
43 * CONVERT_TEXEL - code to convert from source to dest texel
44 * CONVER_TEXEL_DWORD - if multiple texels fit in 4 bytes, this macros
45 * will convert/store multiple texels at once
46 * CONVERT_DIRECT - if defined, just memcpy texels from src to dest
47 * SRC_TEXEL_BYTES - bytes per source texel
48 * PRESERVE_DST_TYPE - if defined, don't undefined these macros at end
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)
59 /* =============================================================
60 * PRE: No pixelstore attribs, width == dstImageWidth.
63 TAG(texsubimage2d
)( const struct convert_info
*convert
)
65 const GLubyte
*src
= (const GLubyte
*)convert
->srcImage
;
66 GLuint
*dst
= (GLuint
*)((GLubyte
*)convert
->dstImage
+
67 (convert
->yoffset
* convert
->dstImageWidth
+
68 convert
->xoffset
) * DST_TEXEL_BYTES
);
71 _mesa_debug( NULL
, __FUNCTION__
"\n" );
75 MEMCPY( dst
, src
, convert
->height
* DST_ROW_BYTES
);
78 const GLint texels
= convert
->width
* convert
->height
;
79 const GLint dwords
= texels
/ DST_TEXELS_PER_DWORD
;
80 const GLint leftover
= texels
- dwords
* DST_TEXELS_PER_DWORD
;
82 for ( i
= 0 ; i
< dwords
; i
++ ) {
83 CONVERT_TEXEL_DWORD( *dst
++, src
);
84 src
+= SRC_TEXEL_BYTES
* DST_TEXELS_PER_DWORD
;
86 for ( i
= 0; i
< leftover
; i
++ ) {
87 CONVERT_TEXEL( *dst
++, src
);
88 src
+= SRC_TEXEL_BYTES
;
96 /* PRE: As above, height == dstImageHeight also.
99 TAG(texsubimage3d
)( const struct convert_info
*convert
)
101 const GLubyte
*src
= (const GLubyte
*)convert
->srcImage
;
102 GLuint
*dst
= (GLuint
*)((GLubyte
*)convert
->dstImage
+
103 ((convert
->zoffset
* convert
->height
+
104 convert
->yoffset
) * convert
->width
+
105 convert
->xoffset
) * DST_TEXEL_BYTES
);
107 _mesa_debug( NULL
, __FUNCTION__
"\n" );
110 #ifdef CONVERT_DIRECT
111 MEMCPY( dst
, src
, convert
->depth
* convert
->height
* DST_ROW_BYTES
);
114 const GLint texels
= convert
->width
* convert
->height
* convert
->depth
;
115 const GLint dwords
= texels
/ DST_TEXELS_PER_DWORD
;
116 const GLint leftover
= texels
- dwords
* DST_TEXELS_PER_DWORD
;
118 for ( i
= 0 ; i
< dwords
; i
++ ) {
119 CONVERT_TEXEL_DWORD( *dst
++, src
);
120 src
+= SRC_TEXEL_BYTES
* DST_TEXELS_PER_DWORD
;
122 for ( i
= 0; i
< leftover
; i
++ ) {
123 CONVERT_TEXEL( *dst
++, src
);
124 src
+= SRC_TEXEL_BYTES
;
134 /* =============================================================
135 * PRE: No pixelstore attribs, width != dstImageWidth.
138 TAG(texsubimage2d_stride
)( const struct convert_info
*convert
)
140 const GLubyte
*src
= (const GLubyte
*)convert
->srcImage
;
141 DST_TYPE
*dst
= (DST_TYPE
*)((GLubyte
*)convert
->dstImage
+
142 (convert
->yoffset
* convert
->dstImageWidth
+
143 convert
->xoffset
) * DST_TEXEL_BYTES
);
147 adjust
= convert
->dstImageWidth
- convert
->width
;
150 _mesa_debug( NULL
, __FUNCTION__
":\n" );
151 _mesa_debug( NULL
, " x=%d y=%d w=%d h=%d s=%d\n",
152 convert
->xoffset
, convert
->yoffset
, convert
->width
,
153 convert
->height
, convert
->dstImageWidth
);
154 _mesa_debug( NULL
, " adjust=%d\n", adjust
);
157 for ( row
= 0 ; row
< convert
->height
; row
++ ) {
158 for ( col
= 0 ; col
< convert
->width
; col
++ ) {
159 CONVERT_TEXEL( *dst
++, src
);
160 src
+= SRC_TEXEL_BYTES
;
168 /* PRE: As above, or height != dstImageHeight also.
171 TAG(texsubimage3d_stride
)( const struct convert_info
*convert
)
173 const GLubyte
*src
= (const GLubyte
*)convert
->srcImage
;
174 DST_TYPE
*dst
= (DST_TYPE
*)((GLubyte
*)convert
->dstImage
+
175 ((convert
->zoffset
* convert
->dstImageHeight
+
176 convert
->yoffset
) * convert
->dstImageWidth
+
177 convert
->xoffset
) * DST_TEXEL_BYTES
);
181 adjust
= convert
->dstImageWidth
- convert
->width
;
184 _mesa_debug( NULL
, __FUNCTION__
":\n" );
185 _mesa_debug( NULL
, " x=%d y=%d w=%d h=%d s=%d\n",
186 convert
->xoffset
, convert
->yoffset
, convert
->width
,
187 convert
->height
, convert
->dstImageWidth
);
188 _mesa_debug( NULL
, " adjust=%d\n", adjust
);
191 for ( img
= 0 ; img
< convert
->depth
; img
++ ) {
192 for ( row
= 0 ; row
< convert
->height
; row
++ ) {
193 for ( col
= 0 ; col
< convert
->width
; col
++ ) {
194 CONVERT_TEXEL( *dst
++, src
);
195 src
+= SRC_TEXEL_BYTES
;
207 /* =============================================================
208 * PRE: Require pixelstore attribs, width == dstImageWidth.
211 TAG(texsubimage2d_unpack
)( const struct convert_info
*convert
)
213 const GLubyte
*src
= (const GLubyte
*)
214 _mesa_image_address( convert
->unpacking
, convert
->srcImage
,
215 convert
->width
, convert
->height
,
216 convert
->format
, convert
->type
, 0, 0, 0 );
217 const GLint srcRowStride
=
218 _mesa_image_row_stride( convert
->unpacking
, convert
->width
,
219 convert
->format
, convert
->type
);
223 _mesa_debug( NULL
, __FUNCTION__
"\n" );
226 if (convert
->width
& (DST_TEXELS_PER_DWORD
- 1)) {
227 /* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2
228 * or width = 2 and texels/dword = 4).
230 DST_TYPE
*dst
= (DST_TYPE
*)((GLubyte
*)convert
->dstImage
+
231 (convert
->yoffset
* convert
->width
+
232 convert
->xoffset
) * DST_TEXEL_BYTES
);
233 for ( row
= 0 ; row
< convert
->height
; row
++ ) {
234 const GLubyte
*srcRow
= src
;
235 for ( col
= 0; col
< convert
->width
; col
++ ) {
236 CONVERT_TEXEL(*dst
, src
);
237 src
+= SRC_TEXEL_BYTES
;
239 src
= srcRow
+ srcRowStride
;
243 /* the common case */
244 GLuint
*dst
= (GLuint
*)((GLubyte
*)convert
->dstImage
+
245 (convert
->yoffset
* convert
->width
+
246 convert
->xoffset
) * DST_TEXEL_BYTES
);
247 for ( row
= 0 ; row
< convert
->height
; row
++ ) {
248 #ifdef CONVERT_DIRECT
249 MEMCPY( dst
, src
, DST_ROW_STRIDE
);
251 dst
= (GLuint
*)((GLubyte
*)dst
+ DST_ROW_STRIDE
);
253 const GLubyte
*srcRow
= src
;
254 for ( col
= convert
->width
/ DST_TEXELS_PER_DWORD
; col
; col
-- ) {
255 CONVERT_TEXEL_DWORD( *dst
++, src
);
256 src
+= SRC_TEXEL_BYTES
* DST_TEXELS_PER_DWORD
;
258 src
= srcRow
+ srcRowStride
;
266 /* PRE: as above, height == dstImageHeight also.
269 TAG(texsubimage3d_unpack
)( const struct convert_info
*convert
)
271 const GLubyte
*src
= (const GLubyte
*)
272 _mesa_image_address( convert
->unpacking
, convert
->srcImage
,
273 convert
->width
, convert
->height
,
274 convert
->format
, convert
->type
, 0, 0, 0 );
275 const GLint srcImgStride
= (const GLubyte
*)
276 _mesa_image_address( convert
->unpacking
, convert
->srcImage
,
277 convert
->width
, convert
->height
,
278 convert
->format
, convert
->type
, 1, 0, 0 ) - src
;
279 const GLint srcRowStride
=
280 _mesa_image_row_stride( convert
->unpacking
, convert
->width
,
281 convert
->format
, convert
->type
);
285 _mesa_debug( NULL
, __FUNCTION__
"\n" );
288 if (convert
->width
& (DST_TEXELS_PER_DWORD
- 1)) {
289 /* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2
290 * or width = 2 and texels/dword = 4).
292 DST_TYPE
*dst
= (DST_TYPE
*)((GLubyte
*)convert
->dstImage
+
293 ((convert
->zoffset
* convert
->height
+
294 convert
->yoffset
) * convert
->width
+
295 convert
->xoffset
) * DST_TEXEL_BYTES
);
296 for ( img
= 0 ; img
< convert
->depth
; img
++ ) {
297 const GLubyte
*srcImage
= src
;
298 for ( row
= 0 ; row
< convert
->height
; row
++ ) {
299 const GLubyte
*srcRow
= src
;
300 for ( col
= 0; col
< convert
->width
; col
++ ) {
301 CONVERT_TEXEL(*dst
, src
);
302 src
+= SRC_TEXEL_BYTES
;
304 src
= srcRow
+ srcRowStride
;
306 src
= srcImage
+ srcImgStride
;
310 /* the common case */
311 GLuint
*dst
= (GLuint
*)((GLubyte
*)convert
->dstImage
+
312 ((convert
->zoffset
* convert
->height
+
313 convert
->yoffset
) * convert
->width
+
314 convert
->xoffset
) * DST_TEXEL_BYTES
);
315 for ( img
= 0 ; img
< convert
->depth
; img
++ ) {
316 const GLubyte
*srcImage
= src
;
317 for ( row
= 0 ; row
< convert
->height
; row
++ ) {
318 #ifdef CONVERT_DIRECT
319 MEMCPY( dst
, src
, DST_ROW_STRIDE
);
321 dst
= (GLuint
*)((GLubyte
*)dst
+ DST_ROW_STRIDE
);
323 const GLubyte
*srcRow
= src
;
324 for ( col
= convert
->width
/ DST_TEXELS_PER_DWORD
; col
; col
-- ) {
325 CONVERT_TEXEL_DWORD( *dst
++, src
);
326 src
+= SRC_TEXEL_BYTES
* DST_TEXELS_PER_DWORD
;
328 src
= srcRow
+ srcRowStride
;
331 src
= srcImage
+ srcImgStride
;
340 /* =============================================================
341 * PRE: Require pixelstore attribs, width != dstImageWidth.
344 TAG(texsubimage2d_stride_unpack
)( const struct convert_info
*convert
)
346 const GLubyte
*src
= (const GLubyte
*)
347 _mesa_image_address( convert
->unpacking
, convert
->srcImage
,
348 convert
->width
, convert
->height
,
349 convert
->format
, convert
->type
, 0, 0, 0 );
350 const GLint srcRowStride
=
351 _mesa_image_row_stride( convert
->unpacking
, convert
->width
,
352 convert
->format
, convert
->type
);
353 DST_TYPE
*dst
= (DST_TYPE
*)((GLubyte
*)convert
->dstImage
+
354 (convert
->yoffset
* convert
->dstImageWidth
+
355 convert
->xoffset
) * DST_TEXEL_BYTES
);
360 adjust
= convert
->dstImageWidth
- convert
->width
;
363 _mesa_debug( NULL
, __FUNCTION__
":\n" );
364 _mesa_debug( NULL
, " x=%d y=%d w=%d h=%d s=%d\n",
365 convert
->xoffset
, convert
->yoffset
, convert
->width
,
366 convert
->height
, convert
->dstImageWidth
);
367 _mesa_debug( NULL
, " adjust=%d\n", adjust
);
370 for ( row
= 0 ; row
< convert
->height
; row
++ ) {
371 #ifdef CONVERT_DIRECT
372 MEMCPY( dst
, src
, DST_ROW_BYTES
);
374 dst
+= convert
->dstImageWidth
;
376 const GLubyte
*srcRow
= src
;
377 for ( col
= 0 ; col
< convert
->width
; col
++ ) {
378 CONVERT_TEXEL( *dst
++, src
);
379 src
+= SRC_TEXEL_BYTES
;
381 src
= srcRow
+ srcRowStride
;
389 /* PRE: As above, or height != dstImageHeight also.
392 TAG(texsubimage3d_stride_unpack
)( const struct convert_info
*convert
)
394 const GLubyte
*src
= (const GLubyte
*)
395 _mesa_image_address( convert
->unpacking
, convert
->srcImage
,
396 convert
->width
, convert
->height
,
397 convert
->format
, convert
->type
, 0, 0, 0 );
398 const GLint srcImgStride
= (const GLubyte
*)
399 _mesa_image_address( convert
->unpacking
, convert
->srcImage
,
400 convert
->width
, convert
->height
,
401 convert
->format
, convert
->type
, 1, 0, 0 ) - src
;
402 const GLint srcRowStride
=
403 _mesa_image_row_stride( convert
->unpacking
, convert
->width
,
404 convert
->format
, convert
->type
);
405 DST_TYPE
*dst
= (DST_TYPE
*)((GLubyte
*)convert
->dstImage
+
406 ((convert
->zoffset
* convert
->dstImageHeight
+
407 convert
->yoffset
) * convert
->dstImageWidth
+
408 convert
->xoffset
) * DST_TEXEL_BYTES
);
413 adjust
= convert
->dstImageWidth
- convert
->width
;
416 _mesa_debug( NULL
, __FUNCTION__
":\n" );
417 _mesa_debug( NULL
, " x=%d y=%d w=%d h=%d s=%d\n",
418 convert
->xoffset
, convert
->yoffset
, convert
->width
,
419 convert
->height
, convert
->dstImageWidth
);
420 _mesa_debug( NULL
, " adjust=%d\n", adjust
);
423 for ( img
= 0 ; img
< convert
->depth
; img
++ ) {
424 const GLubyte
*srcImage
= src
;
425 for ( row
= 0 ; row
< convert
->height
; row
++ ) {
426 #ifdef CONVERT_DIRECT
427 MEMCPY( dst
, src
, DST_ROW_BYTES
);
429 dst
+= convert
->dstImageWidth
;
431 const GLubyte
*srcRow
= src
;
432 for ( col
= 0 ; col
< convert
->width
; col
++ ) {
433 CONVERT_TEXEL( *dst
++, src
);
434 src
+= SRC_TEXEL_BYTES
;
436 src
= srcRow
+ srcRowStride
;
440 src
= srcImage
+ srcImgStride
;
448 static convert_func
TAG(texsubimage2d_tab
)[] = {
450 TAG(texsubimage2d_stride
),
451 TAG(texsubimage2d_unpack
),
452 TAG(texsubimage2d_stride_unpack
),
455 static convert_func
TAG(texsubimage3d_tab
)[] = {
457 TAG(texsubimage3d_stride
),
458 TAG(texsubimage3d_unpack
),
459 TAG(texsubimage3d_stride_unpack
),
463 #ifndef PRESERVE_DST_TYPE
465 #undef DST_TEXELS_PER_DWORD
468 #undef SRC_TEXEL_BYTES
469 #undef DST_TEXEL_BYTES
471 #undef DST_ROW_STRIDE
474 #undef CONVERT_TEXEL_DWORD
475 #undef CONVERT_DIRECT
479 #undef PRESERVE_DST_TYPE