fixed a bunch of g++ warnings/errors. Compiling with g++ can help find lots of poten...
[mesa.git] / src / mesa / main / texstore.c
1 /* $Id: texstore.c,v 1.10 2001/03/07 05:06:12 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 */
26
27 /*
28 * Authors:
29 * Brian Paul
30 */
31
32
33 /*
34 * The functions in this file are mostly related to software texture fallbacks.
35 * This includes texture image transfer/packing and texel fetching.
36 * Hardware drivers will likely override most of this.
37 */
38
39
40
41 #include "colormac.h"
42 #include "context.h"
43 #include "convolve.h"
44 #include "image.h"
45 #include "macros.h"
46 #include "mem.h"
47 #include "teximage.h"
48 #include "texstore.h"
49 #include "swrast/s_depth.h" /* XXX this is kind of a cheat */
50 #include "swrast/s_span.h"
51
52
53 /*
54 * Default 1-D texture texel fetch function. This will typically be
55 * overridden by hardware drivers which store their texture images in
56 * special ways.
57 */
58 static void
59 fetch_1d_texel(const struct gl_texture_image *img,
60 GLint i, GLint j, GLint k, GLvoid *texel)
61 {
62 switch (img->Format) {
63 case GL_RGBA:
64 {
65 const GLchan *src = (GLchan *) img->Data + i * 4;
66 GLchan *rgba = (GLchan *) texel;
67 COPY_CHAN4(rgba, src);
68 return;
69 }
70 case GL_RGB:
71 {
72 const GLchan *src = (GLchan *) img->Data + i * 3;
73 GLchan *rgba = (GLchan *) texel;
74 rgba[RCOMP] = src[0];
75 rgba[GCOMP] = src[1];
76 rgba[BCOMP] = src[2];
77 rgba[ACOMP] = CHAN_MAX;
78 return;
79 }
80 case GL_ALPHA:
81 {
82 const GLchan *src = (GLchan *) img->Data + i;
83 GLchan *rgba = (GLchan *) texel;
84 rgba[RCOMP] = 0;
85 rgba[GCOMP] = 0;
86 rgba[BCOMP] = 0;
87 rgba[ACOMP] = src[0];
88 return;
89 }
90 case GL_LUMINANCE:
91 {
92 const GLchan *src = (GLchan *) img->Data + i;
93 GLchan *rgba = (GLchan *) texel;
94 rgba[RCOMP] = src[0];
95 rgba[GCOMP] = src[0];
96 rgba[BCOMP] = src[0];
97 rgba[ACOMP] = CHAN_MAX;
98 return;
99 }
100 case GL_INTENSITY:
101 {
102 const GLchan *src = (GLchan *) img->Data + i;
103 GLchan *rgba = (GLchan *) texel;
104 rgba[RCOMP] = src[0];
105 rgba[GCOMP] = src[0];
106 rgba[BCOMP] = src[0];
107 rgba[ACOMP] = src[0];
108 return;
109 }
110 case GL_LUMINANCE_ALPHA:
111 {
112 const GLchan *src = (GLchan *) img->Data + i * 2;
113 GLchan *rgba = (GLchan *) texel;
114 rgba[RCOMP] = src[0];
115 rgba[GCOMP] = src[0];
116 rgba[BCOMP] = src[0];
117 rgba[ACOMP] = src[1];
118 return;
119 }
120 case GL_COLOR_INDEX:
121 {
122 const GLchan *src = (GLchan *) img->Data + i;
123 GLchan *index = (GLchan *) texel;
124 *index = *src;
125 return;
126 }
127 case GL_DEPTH_COMPONENT:
128 {
129 const GLfloat *src = (GLfloat *) img->Data + i;
130 GLfloat *depth = (GLfloat *) texel;
131 *depth = *src;
132 return;
133 }
134 default:
135 _mesa_problem(NULL, "Bad format in fetch_1d_texel");
136 }
137 }
138
139
140 /*
141 * Default 2-D texture texel fetch function.
142 */
143 static void
144 fetch_2d_texel(const struct gl_texture_image *img,
145 GLint i, GLint j, GLint k, GLvoid *texel)
146 {
147 switch (img->Format) {
148 case GL_RGBA:
149 {
150 const GLchan *src = (GLchan *) img->Data + (img->Width * j + i) * 4;
151 GLchan *rgba = (GLchan *) texel;
152 COPY_CHAN4(rgba, src);
153 return;
154 }
155 case GL_RGB:
156 {
157 const GLchan *src = (GLchan *) img->Data + (img->Width * j + i) * 3;
158 GLchan *rgba = (GLchan *) texel;
159 rgba[RCOMP] = src[0];
160 rgba[GCOMP] = src[1];
161 rgba[BCOMP] = src[2];
162 rgba[ACOMP] = CHAN_MAX;
163 return;
164 }
165 case GL_ALPHA:
166 {
167 const GLchan *src = (GLchan *) img->Data + (img->Width * j + i);
168 GLchan *rgba = (GLchan *) texel;
169 rgba[RCOMP] = 0;
170 rgba[GCOMP] = 0;
171 rgba[BCOMP] = 0;
172 rgba[ACOMP] = src[0];
173 return;
174 }
175 case GL_LUMINANCE:
176 {
177 const GLchan *src = (GLchan *) img->Data + (img->Width * j + i);
178 GLchan *rgba = (GLchan *) texel;
179 rgba[RCOMP] = src[0];
180 rgba[GCOMP] = src[0];
181 rgba[BCOMP] = src[0];
182 rgba[ACOMP] = CHAN_MAX;
183 return;
184 }
185 case GL_INTENSITY:
186 {
187 const GLchan *src = (GLchan *) img->Data + (img->Width * j + i);
188 GLchan *rgba = (GLchan *) texel;
189 rgba[RCOMP] = src[0];
190 rgba[GCOMP] = src[0];
191 rgba[BCOMP] = src[0];
192 rgba[ACOMP] = src[0];
193 return;
194 }
195 case GL_LUMINANCE_ALPHA:
196 {
197 const GLchan *src = (GLchan *) img->Data + (img->Width * j + i) * 2;
198 GLchan *rgba = (GLchan *) texel;
199 rgba[RCOMP] = src[0];
200 rgba[GCOMP] = src[0];
201 rgba[BCOMP] = src[0];
202 rgba[ACOMP] = src[1];
203 return;
204 }
205 case GL_COLOR_INDEX:
206 {
207 const GLchan *src = (GLchan *) img->Data + (img->Width * j + i);
208 GLchan *index = (GLchan *) texel;
209 *index = *src;
210 return;
211 }
212 case GL_DEPTH_COMPONENT:
213 {
214 const GLfloat *src = (GLfloat *) img->Data + (img->Width * j + i);
215 GLfloat *depth = (GLfloat *) texel;
216 *depth = *src;
217 return;
218 }
219 default:
220 _mesa_problem(NULL, "Bad format in fetch_2d_texel");
221 }
222 }
223
224
225 /*
226 * Default 2-D texture texel fetch function.
227 */
228 static void
229 fetch_3d_texel(const struct gl_texture_image *img,
230 GLint i, GLint j, GLint k, GLvoid *texel)
231 {
232 const GLint width = img->Width;
233 const GLint rectArea = width * img->Height;
234
235 switch (img->Format) {
236 case GL_RGBA:
237 {
238 const GLchan *src = (GLchan *) img->Data
239 + (rectArea * k + width * j + i) * 4;
240 GLchan *rgba = (GLchan *) texel;
241 COPY_CHAN4(rgba, src);
242 return;
243 }
244 case GL_RGB:
245 {
246 const GLchan *src = (GLchan *) img->Data
247 + (rectArea * k + width * j + i) * 3;
248 GLchan *rgba = (GLchan *) texel;
249 rgba[RCOMP] = src[0];
250 rgba[GCOMP] = src[1];
251 rgba[BCOMP] = src[2];
252 rgba[ACOMP] = CHAN_MAX;
253 return;
254 }
255 case GL_ALPHA:
256 {
257 const GLchan *src = (GLchan *) img->Data
258 + (rectArea * k + width * j + i);
259 GLchan *rgba = (GLchan *) texel;
260 rgba[RCOMP] = 0;
261 rgba[GCOMP] = 0;
262 rgba[BCOMP] = 0;
263 rgba[ACOMP] = src[0];
264 return;
265 }
266 case GL_LUMINANCE:
267 {
268 const GLchan *src = (GLchan *) img->Data
269 + (rectArea * k + width * j + i);
270 GLchan *rgba = (GLchan *) texel;
271 rgba[RCOMP] = src[0];
272 rgba[GCOMP] = src[0];
273 rgba[BCOMP] = src[0];
274 rgba[ACOMP] = CHAN_MAX;
275 return;
276 }
277 case GL_INTENSITY:
278 {
279 const GLchan *src = (GLchan *) img->Data
280 + (rectArea * k + width * j + i);
281 GLchan *rgba = (GLchan *) texel;
282 rgba[RCOMP] = src[0];
283 rgba[GCOMP] = src[0];
284 rgba[BCOMP] = src[0];
285 rgba[ACOMP] = src[0];
286 return;
287 }
288 case GL_LUMINANCE_ALPHA:
289 {
290 const GLchan *src = (GLchan *) img->Data
291 + (rectArea * k + width * j + i) * 2;
292 GLchan *rgba = (GLchan *) texel;
293 rgba[RCOMP] = src[0];
294 rgba[GCOMP] = src[0];
295 rgba[BCOMP] = src[0];
296 rgba[ACOMP] = src[1];
297 return;
298 }
299 case GL_COLOR_INDEX:
300 {
301 const GLchan *src = (GLchan *) img->Data
302 + (rectArea * k + width * j + i);
303 GLchan *index = (GLchan *) texel;
304 *index = *src;
305 return;
306 }
307 case GL_DEPTH_COMPONENT:
308 {
309 const GLfloat *src = (GLfloat *) img->Data
310 + (rectArea * k + width * j + i);
311 GLfloat *depth = (GLfloat *) texel;
312 *depth = *src;
313 return;
314 }
315 default:
316 _mesa_problem(NULL, "Bad format in fetch_3d_texel");
317 }
318 }
319
320
321
322 /*
323 * Examine the texImage->Format field and set the Red, Green, Blue, etc
324 * texel component sizes to default values.
325 * These fields are set only here by core Mesa but device drivers may
326 * overwritting these fields to indicate true texel resolution.
327 */
328 static void
329 set_teximage_component_sizes( struct gl_texture_image *texImage )
330 {
331 switch (texImage->Format) {
332 case GL_ALPHA:
333 texImage->RedBits = 0;
334 texImage->GreenBits = 0;
335 texImage->BlueBits = 0;
336 texImage->AlphaBits = 8 * sizeof(GLchan);
337 texImage->IntensityBits = 0;
338 texImage->LuminanceBits = 0;
339 texImage->IndexBits = 0;
340 texImage->DepthBits = 0;
341 break;
342 case GL_LUMINANCE:
343 texImage->RedBits = 0;
344 texImage->GreenBits = 0;
345 texImage->BlueBits = 0;
346 texImage->AlphaBits = 0;
347 texImage->IntensityBits = 0;
348 texImage->LuminanceBits = 8 * sizeof(GLchan);
349 texImage->IndexBits = 0;
350 texImage->DepthBits = 0;
351 break;
352 case GL_LUMINANCE_ALPHA:
353 texImage->RedBits = 0;
354 texImage->GreenBits = 0;
355 texImage->BlueBits = 0;
356 texImage->AlphaBits = 8 * sizeof(GLchan);
357 texImage->IntensityBits = 0;
358 texImage->LuminanceBits = 8 * sizeof(GLchan);
359 texImage->IndexBits = 0;
360 texImage->DepthBits = 0;
361 break;
362 case GL_INTENSITY:
363 texImage->RedBits = 0;
364 texImage->GreenBits = 0;
365 texImage->BlueBits = 0;
366 texImage->AlphaBits = 0;
367 texImage->IntensityBits = 8 * sizeof(GLchan);
368 texImage->LuminanceBits = 0;
369 texImage->IndexBits = 0;
370 texImage->DepthBits = 0;
371 break;
372 case GL_RED:
373 texImage->RedBits = 8 * sizeof(GLchan);
374 texImage->GreenBits = 0;
375 texImage->BlueBits = 0;
376 texImage->AlphaBits = 0;
377 texImage->IntensityBits = 0;
378 texImage->LuminanceBits = 0;
379 texImage->IndexBits = 0;
380 texImage->DepthBits = 0;
381 break;
382 case GL_GREEN:
383 texImage->RedBits = 0;
384 texImage->GreenBits = 8 * sizeof(GLchan);
385 texImage->BlueBits = 0;
386 texImage->AlphaBits = 0;
387 texImage->IntensityBits = 0;
388 texImage->LuminanceBits = 0;
389 texImage->IndexBits = 0;
390 texImage->DepthBits = 0;
391 break;
392 case GL_BLUE:
393 texImage->RedBits = 0;
394 texImage->GreenBits = 0;
395 texImage->BlueBits = 8 * sizeof(GLchan);
396 texImage->AlphaBits = 0;
397 texImage->IntensityBits = 0;
398 texImage->LuminanceBits = 0;
399 texImage->IndexBits = 0;
400 texImage->DepthBits = 0;
401 break;
402 case GL_RGB:
403 case GL_BGR:
404 texImage->RedBits = 8 * sizeof(GLchan);
405 texImage->GreenBits = 8 * sizeof(GLchan);
406 texImage->BlueBits = 8 * sizeof(GLchan);
407 texImage->AlphaBits = 0;
408 texImage->IntensityBits = 0;
409 texImage->LuminanceBits = 0;
410 texImage->IndexBits = 0;
411 texImage->DepthBits = 0;
412 break;
413 case GL_RGBA:
414 case GL_BGRA:
415 case GL_ABGR_EXT:
416 texImage->RedBits = 8 * sizeof(GLchan);
417 texImage->GreenBits = 8 * sizeof(GLchan);
418 texImage->BlueBits = 8 * sizeof(GLchan);
419 texImage->AlphaBits = 8 * sizeof(GLchan);
420 texImage->IntensityBits = 0;
421 texImage->LuminanceBits = 0;
422 texImage->IndexBits = 0;
423 texImage->DepthBits = 0;
424 break;
425 case GL_COLOR_INDEX:
426 texImage->RedBits = 0;
427 texImage->GreenBits = 0;
428 texImage->BlueBits = 0;
429 texImage->AlphaBits = 0;
430 texImage->IntensityBits = 0;
431 texImage->LuminanceBits = 0;
432 texImage->IndexBits = 8 * sizeof(GLchan);
433 texImage->DepthBits = 0;
434 break;
435 case GL_DEPTH_COMPONENT:
436 texImage->RedBits = 0;
437 texImage->GreenBits = 0;
438 texImage->BlueBits = 0;
439 texImage->AlphaBits = 0;
440 texImage->IntensityBits = 0;
441 texImage->LuminanceBits = 0;
442 texImage->IndexBits = 0;
443 texImage->DepthBits = 8 * sizeof(GLfloat);
444 break;
445 default:
446 _mesa_problem(NULL, "unexpected format in set_teximage_component_sizes");
447 }
448 }
449
450
451
452 /*
453 * Given an internal texture format enum or 1, 2, 3, 4 return the
454 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
455 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
456 * number of components for the format. Return -1 if invalid enum.
457 */
458 static GLint
459 components_in_intformat( GLint format )
460 {
461 switch (format) {
462 case GL_ALPHA:
463 case GL_ALPHA4:
464 case GL_ALPHA8:
465 case GL_ALPHA12:
466 case GL_ALPHA16:
467 return 1;
468 case 1:
469 case GL_LUMINANCE:
470 case GL_LUMINANCE4:
471 case GL_LUMINANCE8:
472 case GL_LUMINANCE12:
473 case GL_LUMINANCE16:
474 return 1;
475 case 2:
476 case GL_LUMINANCE_ALPHA:
477 case GL_LUMINANCE4_ALPHA4:
478 case GL_LUMINANCE6_ALPHA2:
479 case GL_LUMINANCE8_ALPHA8:
480 case GL_LUMINANCE12_ALPHA4:
481 case GL_LUMINANCE12_ALPHA12:
482 case GL_LUMINANCE16_ALPHA16:
483 return 2;
484 case GL_INTENSITY:
485 case GL_INTENSITY4:
486 case GL_INTENSITY8:
487 case GL_INTENSITY12:
488 case GL_INTENSITY16:
489 return 1;
490 case 3:
491 case GL_RGB:
492 case GL_R3_G3_B2:
493 case GL_RGB4:
494 case GL_RGB5:
495 case GL_RGB8:
496 case GL_RGB10:
497 case GL_RGB12:
498 case GL_RGB16:
499 return 3;
500 case 4:
501 case GL_RGBA:
502 case GL_RGBA2:
503 case GL_RGBA4:
504 case GL_RGB5_A1:
505 case GL_RGBA8:
506 case GL_RGB10_A2:
507 case GL_RGBA12:
508 case GL_RGBA16:
509 return 4;
510 case GL_COLOR_INDEX:
511 case GL_COLOR_INDEX1_EXT:
512 case GL_COLOR_INDEX2_EXT:
513 case GL_COLOR_INDEX4_EXT:
514 case GL_COLOR_INDEX8_EXT:
515 case GL_COLOR_INDEX12_EXT:
516 case GL_COLOR_INDEX16_EXT:
517 return 1;
518 case GL_DEPTH_COMPONENT:
519 case GL_DEPTH_COMPONENT16_SGIX:
520 case GL_DEPTH_COMPONENT24_SGIX:
521 case GL_DEPTH_COMPONENT32_SGIX:
522 return 1;
523 default:
524 return -1; /* error */
525 }
526 }
527
528
529 /*
530 * This function is used to transfer the user's image data into a texture
531 * image buffer. We handle both full texture images and subtexture images.
532 * We also take care of all image transfer operations here, including
533 * convolution, scale/bias, colortables, etc.
534 *
535 * The destination texel channel type is always GLchan.
536 *
537 * A hardware driver may use this as a helper routine to unpack and
538 * apply pixel transfer ops into a temporary image buffer. Then,
539 * convert the temporary image into the special hardware format.
540 *
541 * Input:
542 * dimensions - 1, 2, or 3
543 * texFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA,
544 * GL_RGB or GL_RGBA
545 * texAddr - destination image address
546 * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images
547 * dstXoffset, dstYoffset, dstZoffset - position to store the image within
548 * the destination 3D texture
549 * dstRowStride, dstImageStride - dest image strides in GLchan's
550 * srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc)
551 * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc
552 * srcPacking - describes packing of incoming image.
553 */
554 void
555 _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
556 GLenum texFormat, GLchan *texAddr,
557 GLint srcWidth, GLint srcHeight, GLint srcDepth,
558 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
559 GLint dstRowStride, GLint dstImageStride,
560 GLenum srcFormat, GLenum srcType,
561 const GLvoid *srcAddr,
562 const struct gl_pixelstore_attrib *srcPacking)
563 {
564 GLint texComponents;
565
566 ASSERT(ctx);
567 ASSERT(dimensions >= 1 && dimensions <= 3);
568 ASSERT(texAddr);
569 ASSERT(srcWidth >= 1);
570 ASSERT(srcHeight >= 1);
571 ASSERT(srcDepth >= 1);
572 ASSERT(dstXoffset >= 0);
573 ASSERT(dstYoffset >= 0);
574 ASSERT(dstZoffset >= 0);
575 ASSERT(dstRowStride >= 0);
576 ASSERT(dstImageStride >= 0);
577 ASSERT(srcAddr);
578 ASSERT(srcPacking);
579
580 texComponents = components_in_intformat(texFormat);
581
582 /* try common 2D texture cases first */
583 if (!ctx->_ImageTransferState && dimensions == 2 && srcType == CHAN_TYPE) {
584
585 if (srcFormat == texFormat) {
586 /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
587 * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy().
588 */
589 const GLchan *src = (const GLchan *) _mesa_image_address(
590 srcPacking, srcAddr, srcWidth, srcHeight,
591 srcFormat, srcType, 0, 0, 0);
592 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
593 srcWidth, srcFormat, srcType);
594 const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan);
595 GLchan *dst = texAddr + dstYoffset * dstRowStride
596 + dstXoffset * texComponents;
597 if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
598 MEMCPY(dst, src, srcHeight * widthInBytes);
599 }
600 else {
601 GLint i;
602 for (i = 0; i < srcHeight; i++) {
603 MEMCPY(dst, src, widthInBytes);
604 src += srcRowStride;
605 dst += dstRowStride;
606 }
607 }
608 return; /* all done */
609 }
610 else if (srcFormat == GL_RGBA && texFormat == GL_RGB) {
611 /* commonly used by Quake */
612 const GLchan *src = (const GLchan *) _mesa_image_address(
613 srcPacking, srcAddr, srcWidth, srcHeight,
614 srcFormat, srcType, 0, 0, 0);
615 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
616 srcWidth, srcFormat, srcType);
617 GLchan *dst = texAddr + dstYoffset * dstRowStride
618 + dstXoffset * texComponents;
619 GLint i, j;
620 for (i = 0; i < srcHeight; i++) {
621 const GLchan *s = src;
622 GLchan *d = dst;
623 for (j = 0; j < srcWidth; j++) {
624 *d++ = *s++; /*red*/
625 *d++ = *s++; /*green*/
626 *d++ = *s++; /*blue*/
627 s++; /*alpha*/
628 }
629 src += srcRowStride;
630 dst += dstRowStride;
631 }
632 return; /* all done */
633 }
634 }
635
636 /*
637 * General case solutions
638 */
639 if (texFormat == GL_COLOR_INDEX) {
640 /* color index texture */
641 const GLenum texType = CHAN_TYPE;
642 GLint img, row;
643 GLchan *dest = texAddr + dstZoffset * dstImageStride
644 + dstYoffset * dstRowStride
645 + dstXoffset * texComponents;
646 for (img = 0; img < srcDepth; img++) {
647 GLchan *destRow = dest;
648 for (row = 0; row < srcHeight; row++) {
649 const GLvoid *src = _mesa_image_address(srcPacking,
650 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
651 _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
652 srcType, src, srcPacking,
653 ctx->_ImageTransferState);
654 destRow += dstRowStride;
655 }
656 dest += dstImageStride;
657 }
658 }
659 else if (texFormat == GL_DEPTH_COMPONENT) {
660 /* Depth texture (shadow maps) */
661 GLint img, row;
662 GLfloat *dest = (GLfloat *) texAddr + dstZoffset * dstImageStride
663 + dstYoffset * dstRowStride
664 + dstXoffset * texComponents;
665 for (img = 0; img < srcDepth; img++) {
666 GLfloat *destRow = dest;
667 for (row = 0; row < srcHeight; row++) {
668 const GLvoid *src = _mesa_image_address(srcPacking,
669 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
670 _mesa_unpack_depth_span(ctx, srcWidth, destRow,
671 srcType, src, srcPacking);
672 destRow += dstRowStride;
673 }
674 dest += dstImageStride;
675 }
676 }
677 else {
678 /* regular, color texture */
679 if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
680 (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
681 (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
682 /*
683 * Fill texture image with convolution
684 */
685 GLint img, row;
686 GLint convWidth = srcWidth, convHeight = srcHeight;
687 GLfloat *tmpImage, *convImage;
688 tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
689 if (!tmpImage) {
690 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
691 return;
692 }
693 convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
694 if (!convImage) {
695 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
696 FREE(tmpImage);
697 return;
698 }
699
700 for (img = 0; img < srcDepth; img++) {
701 const GLfloat *srcf;
702 GLfloat *dstf = tmpImage;
703 GLchan *dest;
704
705 /* unpack and do transfer ops up to convolution */
706 for (row = 0; row < srcHeight; row++) {
707 const GLvoid *src = _mesa_image_address(srcPacking,
708 srcAddr, srcWidth, srcHeight,
709 srcFormat, srcType, img, row, 0);
710 _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
711 srcFormat, srcType, src, srcPacking,
712 ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
713 GL_TRUE);
714 dstf += srcWidth * 4;
715 }
716
717 /* convolve */
718 if (dimensions == 1) {
719 ASSERT(ctx->Pixel.Convolution1DEnabled);
720 _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
721 }
722 else {
723 if (ctx->Pixel.Convolution2DEnabled) {
724 _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
725 tmpImage, convImage);
726 }
727 else {
728 ASSERT(ctx->Pixel.Separable2DEnabled);
729 _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
730 tmpImage, convImage);
731 }
732 }
733
734 /* packing and transfer ops after convolution */
735 srcf = convImage;
736 dest = texAddr + (dstZoffset + img) * dstImageStride
737 + dstYoffset * dstRowStride;
738 for (row = 0; row < convHeight; row++) {
739 _mesa_pack_float_rgba_span(ctx, convWidth,
740 (const GLfloat (*)[4]) srcf,
741 texFormat, CHAN_TYPE,
742 dest, &_mesa_native_packing,
743 ctx->_ImageTransferState
744 & IMAGE_POST_CONVOLUTION_BITS);
745 srcf += convWidth * 4;
746 dest += dstRowStride;
747 }
748 }
749
750 FREE(convImage);
751 FREE(tmpImage);
752 }
753 else {
754 /*
755 * no convolution
756 */
757 GLint img, row;
758 GLchan *dest = texAddr + dstZoffset * dstImageStride
759 + dstYoffset * dstRowStride
760 + dstXoffset * texComponents;
761 for (img = 0; img < srcDepth; img++) {
762 GLchan *destRow = dest;
763 for (row = 0; row < srcHeight; row++) {
764 const GLvoid *srcRow = _mesa_image_address(srcPacking,
765 srcAddr, srcWidth, srcHeight,
766 srcFormat, srcType, img, row, 0);
767 _mesa_unpack_chan_color_span(ctx, srcWidth, texFormat, destRow,
768 srcFormat, srcType, srcRow, srcPacking,
769 ctx->_ImageTransferState);
770 destRow += dstRowStride;
771 }
772 dest += dstImageStride;
773 }
774 }
775 }
776 }
777
778
779
780 /*
781 * This is the software fallback for Driver.TexImage1D().
782 * The texture image type will be GLchan.
783 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
784 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
785 *
786 */
787 void
788 _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
789 GLint internalFormat,
790 GLint width, GLint border,
791 GLenum format, GLenum type, const GLvoid *pixels,
792 const struct gl_pixelstore_attrib *packing,
793 struct gl_texture_object *texObj,
794 struct gl_texture_image *texImage)
795 {
796 const GLint components = components_in_intformat(internalFormat);
797 GLint compSize;
798 GLint postConvWidth = width;
799
800 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
801 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
802 }
803
804 /* setup the teximage struct's fields */
805 texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
806 if (format == GL_DEPTH_COMPONENT) {
807 texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
808 compSize = sizeof(GLfloat);
809 }
810 else {
811 texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
812 compSize = sizeof(CHAN_TYPE);
813 }
814 texImage->FetchTexel = fetch_1d_texel;
815 set_teximage_component_sizes(texImage);
816
817 /* allocate memory */
818 texImage->Data = (GLchan *) MALLOC(postConvWidth * components * compSize);
819 if (!texImage->Data)
820 return; /* out of memory */
821
822 /* unpack image, apply transfer ops and store in texImage->Data */
823 _mesa_transfer_teximage(ctx, 1, texImage->Format, (GLchan *) texImage->Data,
824 width, 1, 1, 0, 0, 0,
825 0, /* dstRowStride */
826 0, /* dstImageStride */
827 format, type, pixels, packing);
828 }
829
830
831 /*
832 * This is the software fallback for Driver.TexImage2D().
833 * The texture image type will be GLchan.
834 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
835 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
836 *
837 */
838 void
839 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
840 GLint internalFormat,
841 GLint width, GLint height, GLint border,
842 GLenum format, GLenum type, const void *pixels,
843 const struct gl_pixelstore_attrib *packing,
844 struct gl_texture_object *texObj,
845 struct gl_texture_image *texImage)
846 {
847 const GLint components = components_in_intformat(internalFormat);
848 GLint compSize;
849 GLint postConvWidth = width, postConvHeight = height;
850
851 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
852 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
853 &postConvHeight);
854 }
855
856 /* setup the teximage struct's fields */
857 texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
858 if (format == GL_DEPTH_COMPONENT) {
859 texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
860 compSize = sizeof(GLfloat);
861 }
862 else {
863 texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
864 compSize = sizeof(CHAN_TYPE);
865 }
866 texImage->FetchTexel = fetch_2d_texel;
867 set_teximage_component_sizes(texImage);
868
869 /* allocate memory */
870 texImage->Data = (GLchan *) MALLOC(postConvWidth * postConvHeight
871 * components * compSize);
872 if (!texImage->Data)
873 return; /* out of memory */
874
875 /* unpack image, apply transfer ops and store in texImage->Data */
876 _mesa_transfer_teximage(ctx, 2, texImage->Format, (GLchan *) texImage->Data,
877 width, height, 1, 0, 0, 0,
878 texImage->Width * components * sizeof(GLchan),
879 0, /* dstImageStride */
880 format, type, pixels, packing);
881 }
882
883
884
885 /*
886 * This is the software fallback for Driver.TexImage3D().
887 * The texture image type will be GLchan.
888 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
889 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
890 *
891 */
892 void
893 _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
894 GLint internalFormat,
895 GLint width, GLint height, GLint depth, GLint border,
896 GLenum format, GLenum type, const void *pixels,
897 const struct gl_pixelstore_attrib *packing,
898 struct gl_texture_object *texObj,
899 struct gl_texture_image *texImage)
900 {
901 const GLint components = components_in_intformat(internalFormat);
902 GLint compSize;
903
904 /* setup the teximage struct's fields */
905 texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
906 if (format == GL_DEPTH_COMPONENT) {
907 texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
908 compSize = sizeof(GLfloat);
909 }
910 else {
911 texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
912 compSize = sizeof(CHAN_TYPE);
913 }
914 texImage->FetchTexel = fetch_3d_texel;
915 set_teximage_component_sizes(texImage);
916
917 /* allocate memory */
918 texImage->Data = (GLchan *) MALLOC(width * height * depth
919 * components * compSize);
920 if (!texImage->Data)
921 return; /* out of memory */
922
923 /* unpack image, apply transfer ops and store in texImage->Data */
924 _mesa_transfer_teximage(ctx, 3, texImage->Format, (GLchan *) texImage->Data,
925 width, height, depth, 0, 0, 0,
926 texImage->Width * components * sizeof(GLchan),
927 texImage->Width * texImage->Height * components
928 * sizeof(GLchan),
929 format, type, pixels, packing);
930 }
931
932
933
934
935 /*
936 * This is the software fallback for Driver.TexSubImage1D().
937 */
938 void
939 _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
940 GLint xoffset, GLint width,
941 GLenum format, GLenum type, const void *pixels,
942 const struct gl_pixelstore_attrib *packing,
943 struct gl_texture_object *texObj,
944 struct gl_texture_image *texImage)
945 {
946 _mesa_transfer_teximage(ctx, 1, texImage->Format, (GLchan *) texImage->Data,
947 width, 1, 1, /* src size */
948 xoffset, 0, 0, /* dest offsets */
949 0, /* dstRowStride */
950 0, /* dstImageStride */
951 format, type, pixels, packing);
952 }
953
954
955 /*
956 * This is the software fallback for Driver.TexSubImage2D().
957 */
958 void
959 _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
960 GLint xoffset, GLint yoffset,
961 GLint width, GLint height,
962 GLenum format, GLenum type, const void *pixels,
963 const struct gl_pixelstore_attrib *packing,
964 struct gl_texture_object *texObj,
965 struct gl_texture_image *texImage)
966 {
967 const GLint components = components_in_intformat(texImage->IntFormat);
968 const GLint compSize = _mesa_sizeof_type(texImage->Type);
969 _mesa_transfer_teximage(ctx, 2, texImage->Format, (GLchan *) texImage->Data,
970 width, height, 1, /* src size */
971 xoffset, yoffset, 0, /* dest offsets */
972 texImage->Width * components * compSize,
973 0, /* dstImageStride */
974 format, type, pixels, packing);
975 }
976
977
978 /*
979 * This is the software fallback for Driver.TexSubImage3D().
980 */
981 void
982 _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
983 GLint xoffset, GLint yoffset, GLint zoffset,
984 GLint width, GLint height, GLint depth,
985 GLenum format, GLenum type, const void *pixels,
986 const struct gl_pixelstore_attrib *packing,
987 struct gl_texture_object *texObj,
988 struct gl_texture_image *texImage)
989 {
990 const GLint components = components_in_intformat(texImage->IntFormat);
991 const GLint compSize = _mesa_sizeof_type(texImage->Type);
992 _mesa_transfer_teximage(ctx, 3, texImage->Format, (GLchan *) texImage->Data,
993 width, height, depth, /* src size */
994 xoffset, yoffset, xoffset, /* dest offsets */
995 texImage->Width * components * compSize,
996 texImage->Width * texImage->Height * components
997 * compSize,
998 format, type, pixels, packing);
999 }
1000
1001
1002
1003
1004 /*
1005 * Read an RGBA image from the frame buffer.
1006 * This is used by glCopyTex[Sub]Image[12]D().
1007 * Input: ctx - the context
1008 * x, y - lower left corner
1009 * width, height - size of region to read
1010 * Return: pointer to block of GL_RGBA, GLchan data.
1011 */
1012 static GLchan *
1013 read_color_image( GLcontext *ctx, GLint x, GLint y,
1014 GLsizei width, GLsizei height )
1015 {
1016 GLint stride, i;
1017 GLchan *image, *dst;
1018
1019 image = (GLchan *) MALLOC(width * height * 4 * sizeof(GLchan));
1020 if (!image)
1021 return NULL;
1022
1023 /* Select buffer to read from */
1024 (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
1025 ctx->Pixel.DriverReadBuffer );
1026
1027 RENDER_START(ctx);
1028
1029 dst = image;
1030 stride = width * 4;
1031 for (i = 0; i < height; i++) {
1032 _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i,
1033 (GLchan (*)[4]) dst );
1034 dst += stride;
1035 }
1036
1037 RENDER_FINISH(ctx);
1038
1039 /* Read from draw buffer (the default) */
1040 (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
1041 ctx->Color.DriverDrawBuffer );
1042
1043 return image;
1044 }
1045
1046
1047 /*
1048 * As above, but read data from depth buffer.
1049 */
1050 static GLfloat *
1051 read_depth_image( GLcontext *ctx, GLint x, GLint y,
1052 GLsizei width, GLsizei height )
1053 {
1054 GLint i;
1055 GLfloat *image, *dst;
1056
1057 image = (GLfloat *) MALLOC(width * height * sizeof(GLfloat));
1058 if (!image)
1059 return NULL;
1060
1061 RENDER_START(ctx);
1062
1063 dst = image;
1064 for (i = 0; i < height; i++) {
1065 _mesa_read_depth_span_float(ctx, width, x, y + i, dst);
1066 dst += width;
1067 }
1068
1069 RENDER_FINISH(ctx);
1070
1071 return image;
1072 }
1073
1074
1075
1076 static GLboolean
1077 is_depth_format(GLenum format)
1078 {
1079 switch (format) {
1080 case GL_DEPTH_COMPONENT:
1081 case GL_DEPTH_COMPONENT16_SGIX:
1082 case GL_DEPTH_COMPONENT24_SGIX:
1083 case GL_DEPTH_COMPONENT32_SGIX:
1084 return GL_TRUE;
1085 default:
1086 return GL_FALSE;
1087 }
1088 }
1089
1090
1091 /*
1092 * Fallback for Driver.CopyTexImage1D().
1093 */
1094 void
1095 _mesa_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
1096 GLenum internalFormat,
1097 GLint x, GLint y, GLsizei width, GLint border )
1098 {
1099 struct gl_texture_unit *texUnit;
1100 struct gl_texture_object *texObj;
1101 struct gl_texture_image *texImage;
1102
1103 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1104 texObj = _mesa_select_tex_object(ctx, texUnit, target);
1105 ASSERT(texObj);
1106 texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1107 ASSERT(texImage);
1108
1109 ASSERT(ctx->Driver.TexImage1D);
1110
1111 if (is_depth_format(internalFormat)) {
1112 /* read depth image from framebuffer */
1113 GLfloat *image = read_depth_image(ctx, x, y, width, 1);
1114 if (!image) {
1115 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
1116 return;
1117 }
1118
1119 /* call glTexImage1D to redefine the texture */
1120 (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
1121 width, border,
1122 GL_DEPTH_COMPONENT, GL_FLOAT, image,
1123 &_mesa_native_packing, texObj, texImage);
1124 FREE(image);
1125 }
1126 else {
1127 /* read RGBA image from framebuffer */
1128 GLchan *image = read_color_image(ctx, x, y, width, 1);
1129 if (!image) {
1130 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
1131 return;
1132 }
1133
1134 /* call glTexImage1D to redefine the texture */
1135 (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
1136 width, border,
1137 GL_RGBA, CHAN_TYPE, image,
1138 &_mesa_native_packing, texObj, texImage);
1139 FREE(image);
1140 }
1141 }
1142
1143
1144 /*
1145 * Fallback for Driver.CopyTexImage2D().
1146 */
1147 void
1148 _mesa_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
1149 GLenum internalFormat,
1150 GLint x, GLint y, GLsizei width, GLsizei height,
1151 GLint border )
1152 {
1153 struct gl_texture_unit *texUnit;
1154 struct gl_texture_object *texObj;
1155 struct gl_texture_image *texImage;
1156
1157 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1158 texObj = _mesa_select_tex_object(ctx, texUnit, target);
1159 ASSERT(texObj);
1160 texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1161 ASSERT(texImage);
1162
1163 ASSERT(ctx->Driver.TexImage2D);
1164
1165 if (is_depth_format(internalFormat)) {
1166 /* read depth image from framebuffer */
1167 GLfloat *image = read_depth_image(ctx, x, y, width, height);
1168 if (!image) {
1169 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
1170 return;
1171 }
1172
1173 /* call glTexImage2D to redefine the texture */
1174 (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
1175 width, height, border,
1176 GL_DEPTH_COMPONENT, GL_FLOAT, image,
1177 &_mesa_native_packing, texObj, texImage);
1178 FREE(image);
1179 }
1180 else {
1181 /* read RGBA image from framebuffer */
1182 GLchan *image = read_color_image(ctx, x, y, width, height);
1183 if (!image) {
1184 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
1185 return;
1186 }
1187
1188 /* call glTexImage2D to redefine the texture */
1189 (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
1190 width, height, border,
1191 GL_RGBA, CHAN_TYPE, image,
1192 &_mesa_native_packing, texObj, texImage);
1193 FREE(image);
1194 }
1195 }
1196
1197
1198 /*
1199 * Fallback for Driver.CopyTexSubImage1D().
1200 */
1201 void
1202 _mesa_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
1203 GLint xoffset, GLint x, GLint y, GLsizei width)
1204 {
1205 struct gl_texture_unit *texUnit;
1206 struct gl_texture_object *texObj;
1207 struct gl_texture_image *texImage;
1208
1209 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1210 texObj = _mesa_select_tex_object(ctx, texUnit, target);
1211 ASSERT(texObj);
1212 texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1213 ASSERT(texImage);
1214
1215 ASSERT(ctx->Driver.TexImage1D);
1216
1217 if (is_depth_format(texImage->IntFormat)) {
1218 /* read depth image from framebuffer */
1219 GLfloat *image = read_depth_image(ctx, x, y, width, 1);
1220 if (!image) {
1221 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D");
1222 return;
1223 }
1224
1225 /* call glTexImage1D to redefine the texture */
1226 (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
1227 GL_DEPTH_COMPONENT, GL_FLOAT, image,
1228 &_mesa_native_packing, texObj, texImage);
1229 FREE(image);
1230 }
1231 else {
1232 GLchan *image = read_color_image(ctx, x, y, width, 1);
1233 if (!image) {
1234 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" );
1235 return;
1236 }
1237
1238 /* now call glTexSubImage1D to do the real work */
1239 (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
1240 GL_RGBA, CHAN_TYPE, image,
1241 &_mesa_native_packing, texObj, texImage);
1242 FREE(image);
1243 }
1244 }
1245
1246
1247 /*
1248 * Fallback for Driver.CopyTexSubImage2D().
1249 */
1250 void
1251 _mesa_copy_texsubimage2d( GLcontext *ctx,
1252 GLenum target, GLint level,
1253 GLint xoffset, GLint yoffset,
1254 GLint x, GLint y, GLsizei width, GLsizei height )
1255 {
1256 struct gl_texture_unit *texUnit;
1257 struct gl_texture_object *texObj;
1258 struct gl_texture_image *texImage;
1259
1260 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1261 texObj = _mesa_select_tex_object(ctx, texUnit, target);
1262 ASSERT(texObj);
1263 texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1264 ASSERT(texImage);
1265
1266 ASSERT(ctx->Driver.TexImage2D);
1267
1268 if (is_depth_format(texImage->IntFormat)) {
1269 /* read depth image from framebuffer */
1270 GLfloat *image = read_depth_image(ctx, x, y, width, height);
1271 if (!image) {
1272 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D");
1273 return;
1274 }
1275
1276 /* call glTexImage1D to redefine the texture */
1277 (*ctx->Driver.TexSubImage2D)(ctx, target, level,
1278 xoffset, yoffset, width, height,
1279 GL_DEPTH_COMPONENT, GL_FLOAT, image,
1280 &_mesa_native_packing, texObj, texImage);
1281 FREE(image);
1282 }
1283 else {
1284 /* read RGBA image from framebuffer */
1285 GLchan *image = read_color_image(ctx, x, y, width, height);
1286 if (!image) {
1287 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
1288 return;
1289 }
1290
1291 /* now call glTexSubImage2D to do the real work */
1292 (*ctx->Driver.TexSubImage2D)(ctx, target, level,
1293 xoffset, yoffset, width, height,
1294 GL_RGBA, CHAN_TYPE, image,
1295 &_mesa_native_packing, texObj, texImage);
1296 FREE(image);
1297 }
1298 }
1299
1300
1301 /*
1302 * Fallback for Driver.CopyTexSubImage3D().
1303 */
1304 void
1305 _mesa_copy_texsubimage3d( GLcontext *ctx,
1306 GLenum target, GLint level,
1307 GLint xoffset, GLint yoffset, GLint zoffset,
1308 GLint x, GLint y, GLsizei width, GLsizei height )
1309 {
1310 struct gl_texture_unit *texUnit;
1311 struct gl_texture_object *texObj;
1312 struct gl_texture_image *texImage;
1313
1314 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1315 texObj = _mesa_select_tex_object(ctx, texUnit, target);
1316 ASSERT(texObj);
1317 texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1318 ASSERT(texImage);
1319
1320 ASSERT(ctx->Driver.TexImage3D);
1321
1322 if (is_depth_format(texImage->IntFormat)) {
1323 /* read depth image from framebuffer */
1324 GLfloat *image = read_depth_image(ctx, x, y, width, height);
1325 if (!image) {
1326 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D");
1327 return;
1328 }
1329
1330 /* call glTexImage1D to redefine the texture */
1331 (*ctx->Driver.TexSubImage3D)(ctx, target, level,
1332 xoffset, yoffset, zoffset, width, height, 1,
1333 GL_DEPTH_COMPONENT, GL_FLOAT, image,
1334 &_mesa_native_packing, texObj, texImage);
1335 FREE(image);
1336 }
1337 else {
1338 /* read RGBA image from framebuffer */
1339 GLchan *image = read_color_image(ctx, x, y, width, height);
1340 if (!image) {
1341 _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" );
1342 return;
1343 }
1344
1345 /* now call glTexSubImage3D to do the real work */
1346 (*ctx->Driver.TexSubImage3D)(ctx, target, level,
1347 xoffset, yoffset, zoffset, width, height, 1,
1348 GL_RGBA, CHAN_TYPE, image,
1349 &_mesa_native_packing, texObj, texImage);
1350 FREE(image);
1351 }
1352 }
1353
1354
1355
1356 /*
1357 * Fallback for Driver.CompressedTexImage1D()
1358 */
1359 void
1360 _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
1361 GLint internalFormat,
1362 GLint width, GLint border,
1363 GLsizei imageSize, const GLvoid *data,
1364 struct gl_texture_object *texObj,
1365 struct gl_texture_image *texImage)
1366 {
1367 /* Nothing here.
1368 * The device driver has to do it all.
1369 */
1370 }
1371
1372
1373
1374 /*
1375 * Fallback for Driver.CompressedTexImage2D()
1376 */
1377 void
1378 _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
1379 GLint internalFormat,
1380 GLint width, GLint height, GLint border,
1381 GLsizei imageSize, const GLvoid *data,
1382 struct gl_texture_object *texObj,
1383 struct gl_texture_image *texImage)
1384 {
1385 /* Nothing here.
1386 * The device driver has to do it all.
1387 */
1388 }
1389
1390
1391
1392 /*
1393 * Fallback for Driver.CompressedTexImage3D()
1394 */
1395 void
1396 _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
1397 GLint internalFormat,
1398 GLint width, GLint height, GLint depth,
1399 GLint border,
1400 GLsizei imageSize, const GLvoid *data,
1401 struct gl_texture_object *texObj,
1402 struct gl_texture_image *texImage)
1403 {
1404 /* Nothing here.
1405 * The device driver has to do it all.
1406 */
1407 }
1408
1409
1410
1411
1412
1413
1414 /*
1415 * This is the fallback for Driver.TestProxyTexImage().
1416 */
1417 GLboolean
1418 _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
1419 GLint internalFormat, GLenum format, GLenum type,
1420 GLint width, GLint height, GLint depth, GLint border)
1421 {
1422 struct gl_texture_unit *texUnit;
1423 struct gl_texture_object *texObj;
1424 struct gl_texture_image *texImage;
1425 GLint compSize;
1426
1427 (void) format;
1428 (void) type;
1429
1430 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1431 texObj = _mesa_select_tex_object(ctx, texUnit, target);
1432 texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1433
1434 /* We always pass.
1435 * The core Mesa code will have already tested the image size, etc.
1436 * Drivers may have more stringent texture limits to enforce and will
1437 * have to override this function.
1438 */
1439 /* setup the teximage struct's fields */
1440 texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
1441 if (format == GL_DEPTH_COMPONENT) {
1442 texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
1443 compSize = sizeof(GLfloat);
1444 }
1445 else {
1446 texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
1447 compSize = sizeof(CHAN_TYPE);
1448 }
1449 set_teximage_component_sizes(texImage);
1450
1451 return GL_TRUE;
1452 }
1453