Work in glGetTexImage() to return GL_COLOR_INDEX images.
[mesa.git] / src / mesa / main / texstore.c
1 /* $Id: texstore.c,v 1.5 2001/02/17 00:15:39 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 "context.h"
42 #include "convolve.h"
43 #include "image.h"
44 #include "macros.h"
45 #include "mem.h"
46 #include "teximage.h"
47 #include "texstore.h"
48
49
50 /*
51 * Get texture palette entry.
52 */
53 static void
54 palette_sample(GLcontext *ctx,
55 const struct gl_texture_object *tObj,
56 GLint index, GLchan rgba[4] )
57 {
58 const GLchan *palette;
59 GLenum format;
60
61 if (ctx->Texture.SharedPalette) {
62 ASSERT(!ctx->Texture.Palette.FloatTable);
63 palette = (const GLchan *) ctx->Texture.Palette.Table;
64 format = ctx->Texture.Palette.Format;
65 }
66 else {
67 ASSERT(!tObj->Palette.FloatTable);
68 palette = (const GLchan *) tObj->Palette.Table;
69 format = tObj->Palette.Format;
70 }
71
72 switch (format) {
73 case GL_ALPHA:
74 rgba[ACOMP] = palette[index];
75 return;
76 case GL_LUMINANCE:
77 case GL_INTENSITY:
78 rgba[RCOMP] = palette[index];
79 return;
80 case GL_LUMINANCE_ALPHA:
81 rgba[RCOMP] = palette[(index << 1) + 0];
82 rgba[ACOMP] = palette[(index << 1) + 1];
83 return;
84 case GL_RGB:
85 rgba[RCOMP] = palette[index * 3 + 0];
86 rgba[GCOMP] = palette[index * 3 + 1];
87 rgba[BCOMP] = palette[index * 3 + 2];
88 return;
89 case GL_RGBA:
90 rgba[RCOMP] = palette[(index << 2) + 0];
91 rgba[GCOMP] = palette[(index << 2) + 1];
92 rgba[BCOMP] = palette[(index << 2) + 2];
93 rgba[ACOMP] = palette[(index << 2) + 3];
94 return;
95 default:
96 gl_problem(NULL, "Bad palette format in palette_sample");
97 }
98 }
99
100
101
102 /*
103 * Default 1-D texture texel fetch function. This will typically be
104 * overridden by hardware drivers which store their texture images in
105 * special ways.
106 */
107 static void
108 fetch_1d_texel(GLcontext *ctx,
109 const struct gl_texture_object *tObj,
110 const struct gl_texture_image *img,
111 GLint i, GLint j, GLint k, GLchan rgba[4])
112 {
113 const GLchan *data = (GLchan *) img->Data;
114 const GLchan *texel;
115 #ifdef DEBUG
116 GLint width = img->Width;
117 assert(i >= 0);
118 assert(i < width);
119 #endif
120
121 switch (img->Format) {
122 case GL_COLOR_INDEX:
123 {
124 GLint index = data[i];
125 palette_sample(ctx, tObj, index, rgba);
126 return;
127 }
128 case GL_ALPHA:
129 rgba[ACOMP] = data[i];
130 return;
131 case GL_LUMINANCE:
132 case GL_INTENSITY:
133 rgba[RCOMP] = data[i];
134 return;
135 case GL_LUMINANCE_ALPHA:
136 texel = data + i * 2;
137 rgba[RCOMP] = texel[0];
138 rgba[ACOMP] = texel[1];
139 return;
140 case GL_RGB:
141 texel = data + i * 3;
142 rgba[RCOMP] = texel[0];
143 rgba[GCOMP] = texel[1];
144 rgba[BCOMP] = texel[2];
145 return;
146 case GL_RGBA:
147 texel = data + i * 4;
148 rgba[RCOMP] = texel[0];
149 rgba[GCOMP] = texel[1];
150 rgba[BCOMP] = texel[2];
151 rgba[ACOMP] = texel[3];
152 return;
153 case GL_DEPTH_COMPONENT:
154 {
155 const GLfloat *data = (const GLfloat *) img->Data;
156 GLfloat *texel = (GLfloat *) rgba;
157 *texel = data[i];
158 return;
159 }
160 default:
161 gl_problem(NULL, "Bad format in fetch_1d_texel");
162 return;
163 }
164 }
165
166
167 /*
168 * Default 2-D texture texel fetch function.
169 */
170 static void
171 fetch_2d_texel(GLcontext *ctx,
172 const struct gl_texture_object *tObj,
173 const struct gl_texture_image *img,
174 GLint i, GLint j, GLint k, GLchan rgba[4])
175 {
176 const GLint width = img->Width; /* includes border */
177 const GLchan *data = (GLchan *) img->Data;
178 const GLchan *texel;
179
180 #ifdef DEBUG
181 const GLint height = img->Height; /* includes border */
182 assert(i >= 0);
183 assert(i < width);
184 assert(j >= 0);
185 assert(j < height);
186 #endif
187
188 switch (img->Format) {
189 case GL_COLOR_INDEX:
190 {
191 GLint index = data[width *j + i];
192 palette_sample(ctx, tObj, index, rgba );
193 return;
194 }
195 case GL_ALPHA:
196 rgba[ACOMP] = data[width * j + i];
197 return;
198 case GL_LUMINANCE:
199 case GL_INTENSITY:
200 rgba[RCOMP] = data[ width * j + i];
201 return;
202 case GL_LUMINANCE_ALPHA:
203 texel = data + (width * j + i) * 2;
204 rgba[RCOMP] = texel[0];
205 rgba[ACOMP] = texel[1];
206 return;
207 case GL_RGB:
208 texel = data + (width * j + i) * 3;
209 rgba[RCOMP] = texel[0];
210 rgba[GCOMP] = texel[1];
211 rgba[BCOMP] = texel[2];
212 return;
213 case GL_RGBA:
214 texel = data + (width * j + i) * 4;
215 rgba[RCOMP] = texel[0];
216 rgba[GCOMP] = texel[1];
217 rgba[BCOMP] = texel[2];
218 rgba[ACOMP] = texel[3];
219 return;
220 case GL_DEPTH_COMPONENT:
221 {
222 const GLfloat *data = (const GLfloat *) img->Data;
223 GLfloat *texel = (GLfloat *) rgba;
224 *texel = data[width * j + i];
225 return;
226 }
227 default:
228 gl_problem(NULL, "Bad format in fetch_2d_texel");
229 }
230 }
231
232
233 /*
234 * Default 2-D texture texel fetch function.
235 */
236 static void
237 fetch_3d_texel(GLcontext *ctx,
238 const struct gl_texture_object *tObj,
239 const struct gl_texture_image *img,
240 GLint i, GLint j, GLint k, GLchan rgba[4])
241 {
242 const GLint width = img->Width; /* includes border */
243 const GLint height = img->Height; /* includes border */
244 const GLint rectarea = width * height;
245 const GLchan *data = (GLchan *) img->Data;
246 const GLchan *texel;
247
248 #ifdef DEBUG
249 const GLint depth = img->Depth; /* includes border */
250 assert(i >= 0);
251 assert(i < width);
252 assert(j >= 0);
253 assert(j < height);
254 assert(k >= 0);
255 assert(k < depth);
256 #endif
257
258 switch (img->Format) {
259 case GL_COLOR_INDEX:
260 {
261 GLint index = data[ rectarea * k + width * j + i ];
262 palette_sample(ctx, tObj, index, rgba );
263 return;
264 }
265 case GL_ALPHA:
266 rgba[ACOMP] = data[ rectarea * k + width * j + i ];
267 return;
268 case GL_LUMINANCE:
269 case GL_INTENSITY:
270 rgba[RCOMP] = data[ rectarea * k + width * j + i ];
271 return;
272 case GL_LUMINANCE_ALPHA:
273 texel = data + ( rectarea * k + width * j + i) * 2;
274 rgba[RCOMP] = texel[0];
275 rgba[ACOMP] = texel[1];
276 return;
277 case GL_RGB:
278 texel = data + (rectarea * k + width * j + i) * 3;
279 rgba[RCOMP] = texel[0];
280 rgba[GCOMP] = texel[1];
281 rgba[BCOMP] = texel[2];
282 return;
283 case GL_RGBA:
284 texel = data + (rectarea * k + width * j + i) * 4;
285 rgba[RCOMP] = texel[0];
286 rgba[GCOMP] = texel[1];
287 rgba[BCOMP] = texel[2];
288 rgba[ACOMP] = texel[3];
289 return;
290 case GL_DEPTH_COMPONENT:
291 {
292 const GLfloat *data = (const GLfloat *) img->Data;
293 GLfloat *texel = (GLfloat *) rgba;
294 *texel = data[rectarea * k + width * j + i];
295 return;
296 }
297 default:
298 gl_problem(NULL, "Bad format in fetch_3d_texel");
299 }
300 }
301
302
303
304 /*
305 * Examine the texImage->Format field and set the Red, Green, Blue, etc
306 * texel component sizes to default values.
307 * These fields are set only here by core Mesa but device drivers may
308 * overwritting these fields to indicate true texel resolution.
309 */
310 static void
311 set_teximage_component_sizes( struct gl_texture_image *texImage )
312 {
313 switch (texImage->Format) {
314 case GL_ALPHA:
315 texImage->RedBits = 0;
316 texImage->GreenBits = 0;
317 texImage->BlueBits = 0;
318 texImage->AlphaBits = 8 * sizeof(GLchan);
319 texImage->IntensityBits = 0;
320 texImage->LuminanceBits = 0;
321 texImage->IndexBits = 0;
322 texImage->DepthBits = 0;
323 break;
324 case GL_LUMINANCE:
325 texImage->RedBits = 0;
326 texImage->GreenBits = 0;
327 texImage->BlueBits = 0;
328 texImage->AlphaBits = 0;
329 texImage->IntensityBits = 0;
330 texImage->LuminanceBits = 8 * sizeof(GLchan);
331 texImage->IndexBits = 0;
332 texImage->DepthBits = 0;
333 break;
334 case GL_LUMINANCE_ALPHA:
335 texImage->RedBits = 0;
336 texImage->GreenBits = 0;
337 texImage->BlueBits = 0;
338 texImage->AlphaBits = 8 * sizeof(GLchan);
339 texImage->IntensityBits = 0;
340 texImage->LuminanceBits = 8 * sizeof(GLchan);
341 texImage->IndexBits = 0;
342 texImage->DepthBits = 0;
343 break;
344 case GL_INTENSITY:
345 texImage->RedBits = 0;
346 texImage->GreenBits = 0;
347 texImage->BlueBits = 0;
348 texImage->AlphaBits = 0;
349 texImage->IntensityBits = 8 * sizeof(GLchan);
350 texImage->LuminanceBits = 0;
351 texImage->IndexBits = 0;
352 texImage->DepthBits = 0;
353 break;
354 case GL_RED:
355 texImage->RedBits = 8 * sizeof(GLchan);
356 texImage->GreenBits = 0;
357 texImage->BlueBits = 0;
358 texImage->AlphaBits = 0;
359 texImage->IntensityBits = 0;
360 texImage->LuminanceBits = 0;
361 texImage->IndexBits = 0;
362 texImage->DepthBits = 0;
363 break;
364 case GL_GREEN:
365 texImage->RedBits = 0;
366 texImage->GreenBits = 8 * sizeof(GLchan);
367 texImage->BlueBits = 0;
368 texImage->AlphaBits = 0;
369 texImage->IntensityBits = 0;
370 texImage->LuminanceBits = 0;
371 texImage->IndexBits = 0;
372 texImage->DepthBits = 0;
373 break;
374 case GL_BLUE:
375 texImage->RedBits = 0;
376 texImage->GreenBits = 0;
377 texImage->BlueBits = 8 * sizeof(GLchan);
378 texImage->AlphaBits = 0;
379 texImage->IntensityBits = 0;
380 texImage->LuminanceBits = 0;
381 texImage->IndexBits = 0;
382 texImage->DepthBits = 0;
383 break;
384 case GL_RGB:
385 case GL_BGR:
386 texImage->RedBits = 8 * sizeof(GLchan);
387 texImage->GreenBits = 8 * sizeof(GLchan);
388 texImage->BlueBits = 8 * sizeof(GLchan);
389 texImage->AlphaBits = 0;
390 texImage->IntensityBits = 0;
391 texImage->LuminanceBits = 0;
392 texImage->IndexBits = 0;
393 texImage->DepthBits = 0;
394 break;
395 case GL_RGBA:
396 case GL_BGRA:
397 case GL_ABGR_EXT:
398 texImage->RedBits = 8 * sizeof(GLchan);
399 texImage->GreenBits = 8 * sizeof(GLchan);
400 texImage->BlueBits = 8 * sizeof(GLchan);
401 texImage->AlphaBits = 8 * sizeof(GLchan);
402 texImage->IntensityBits = 0;
403 texImage->LuminanceBits = 0;
404 texImage->IndexBits = 0;
405 texImage->DepthBits = 0;
406 break;
407 case GL_COLOR_INDEX:
408 texImage->RedBits = 0;
409 texImage->GreenBits = 0;
410 texImage->BlueBits = 0;
411 texImage->AlphaBits = 0;
412 texImage->IntensityBits = 0;
413 texImage->LuminanceBits = 0;
414 texImage->IndexBits = 8 * sizeof(GLchan);
415 texImage->DepthBits = 0;
416 break;
417 case GL_DEPTH_COMPONENT:
418 texImage->RedBits = 0;
419 texImage->GreenBits = 0;
420 texImage->BlueBits = 0;
421 texImage->AlphaBits = 0;
422 texImage->IntensityBits = 0;
423 texImage->LuminanceBits = 0;
424 texImage->IndexBits = 0;
425 texImage->DepthBits = 8 * sizeof(GLfloat);
426 break;
427 default:
428 gl_problem(NULL, "unexpected format in set_teximage_component_sizes");
429 }
430 }
431
432
433
434 /*
435 * Given an internal texture format enum or 1, 2, 3, 4 return the
436 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
437 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
438 * number of components for the format. Return -1 if invalid enum.
439 */
440 static GLint
441 components_in_intformat( GLint format )
442 {
443 switch (format) {
444 case GL_ALPHA:
445 case GL_ALPHA4:
446 case GL_ALPHA8:
447 case GL_ALPHA12:
448 case GL_ALPHA16:
449 return 1;
450 case 1:
451 case GL_LUMINANCE:
452 case GL_LUMINANCE4:
453 case GL_LUMINANCE8:
454 case GL_LUMINANCE12:
455 case GL_LUMINANCE16:
456 return 1;
457 case 2:
458 case GL_LUMINANCE_ALPHA:
459 case GL_LUMINANCE4_ALPHA4:
460 case GL_LUMINANCE6_ALPHA2:
461 case GL_LUMINANCE8_ALPHA8:
462 case GL_LUMINANCE12_ALPHA4:
463 case GL_LUMINANCE12_ALPHA12:
464 case GL_LUMINANCE16_ALPHA16:
465 return 2;
466 case GL_INTENSITY:
467 case GL_INTENSITY4:
468 case GL_INTENSITY8:
469 case GL_INTENSITY12:
470 case GL_INTENSITY16:
471 return 1;
472 case 3:
473 case GL_RGB:
474 case GL_R3_G3_B2:
475 case GL_RGB4:
476 case GL_RGB5:
477 case GL_RGB8:
478 case GL_RGB10:
479 case GL_RGB12:
480 case GL_RGB16:
481 return 3;
482 case 4:
483 case GL_RGBA:
484 case GL_RGBA2:
485 case GL_RGBA4:
486 case GL_RGB5_A1:
487 case GL_RGBA8:
488 case GL_RGB10_A2:
489 case GL_RGBA12:
490 case GL_RGBA16:
491 return 4;
492 case GL_COLOR_INDEX:
493 case GL_COLOR_INDEX1_EXT:
494 case GL_COLOR_INDEX2_EXT:
495 case GL_COLOR_INDEX4_EXT:
496 case GL_COLOR_INDEX8_EXT:
497 case GL_COLOR_INDEX12_EXT:
498 case GL_COLOR_INDEX16_EXT:
499 return 1;
500 case GL_DEPTH_COMPONENT:
501 case GL_DEPTH_COMPONENT16_SGIX:
502 case GL_DEPTH_COMPONENT24_SGIX:
503 case GL_DEPTH_COMPONENT32_SGIX:
504 return 1;
505 default:
506 return -1; /* error */
507 }
508 }
509
510
511 /*
512 * This function is used to transfer the user's image data into a texture
513 * image buffer. We handle both full texture images and subtexture images.
514 * We also take care of all image transfer operations here, including
515 * convolution, scale/bias, colortables, etc.
516 *
517 * The destination texel channel type is always GLchan.
518 *
519 * A hardware driver may use this as a helper routine to unpack and
520 * apply pixel transfer ops into a temporary image buffer. Then,
521 * convert the temporary image into the special hardware format.
522 *
523 * Input:
524 * dimensions - 1, 2, or 3
525 * texFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA,
526 * GL_RGB or GL_RGBA
527 * texAddr - destination image address
528 * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images
529 * dstXoffset, dstYoffset, dstZoffset - position to store the image within
530 * the destination 3D texture
531 * dstRowStride, dstImageStride - dest image strides in GLchan's
532 * srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc)
533 * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc
534 * srcPacking - describes packing of incoming image.
535 */
536 void
537 _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
538 GLenum texFormat, GLchan *texAddr,
539 GLint srcWidth, GLint srcHeight, GLint srcDepth,
540 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
541 GLint dstRowStride, GLint dstImageStride,
542 GLenum srcFormat, GLenum srcType,
543 const GLvoid *srcAddr,
544 const struct gl_pixelstore_attrib *srcPacking)
545 {
546 GLint texComponents;
547
548 ASSERT(ctx);
549 ASSERT(dimensions >= 1 && dimensions <= 3);
550 ASSERT(texAddr);
551 ASSERT(srcWidth >= 1);
552 ASSERT(srcHeight >= 1);
553 ASSERT(srcDepth >= 1);
554 ASSERT(dstXoffset >= 0);
555 ASSERT(dstYoffset >= 0);
556 ASSERT(dstZoffset >= 0);
557 ASSERT(dstRowStride >= 0);
558 ASSERT(dstImageStride >= 0);
559 ASSERT(srcAddr);
560 ASSERT(srcPacking);
561
562 texComponents = components_in_intformat(texFormat);
563
564 /* try common 2D texture cases first */
565 if (!ctx->_ImageTransferState && dimensions == 2 && srcType == CHAN_TYPE) {
566
567 if (srcFormat == texFormat) {
568 /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
569 * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy().
570 */
571 const GLchan *src = (const GLchan *) _mesa_image_address(
572 srcPacking, srcAddr, srcWidth, srcHeight,
573 srcFormat, srcType, 0, 0, 0);
574 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
575 srcWidth, srcFormat, srcType);
576 const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan);
577 GLchan *dst = texAddr + dstYoffset * dstRowStride
578 + dstXoffset * texComponents;
579 if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
580 MEMCPY(dst, src, srcHeight * widthInBytes);
581 }
582 else {
583 GLint i;
584 for (i = 0; i < srcHeight; i++) {
585 MEMCPY(dst, src, widthInBytes);
586 src += srcRowStride;
587 dst += dstRowStride;
588 }
589 }
590 return; /* all done */
591 }
592 else if (srcFormat == GL_RGBA && texFormat == GL_RGB) {
593 /* commonly used by Quake */
594 const GLchan *src = (const GLchan *) _mesa_image_address(
595 srcPacking, srcAddr, srcWidth, srcHeight,
596 srcFormat, srcType, 0, 0, 0);
597 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
598 srcWidth, srcFormat, srcType);
599 GLchan *dst = texAddr + dstYoffset * dstRowStride
600 + dstXoffset * texComponents;
601 GLint i, j;
602 for (i = 0; i < srcHeight; i++) {
603 const GLchan *s = src;
604 GLchan *d = dst;
605 for (j = 0; j < srcWidth; j++) {
606 *d++ = *s++; /*red*/
607 *d++ = *s++; /*green*/
608 *d++ = *s++; /*blue*/
609 s++; /*alpha*/
610 }
611 src += srcRowStride;
612 dst += dstRowStride;
613 }
614 return; /* all done */
615 }
616 }
617
618 /*
619 * General case solutions
620 */
621 if (texFormat == GL_COLOR_INDEX) {
622 /* color index texture */
623 const GLenum texType = CHAN_TYPE;
624 GLint img, row;
625 GLchan *dest = texAddr + dstZoffset * dstImageStride
626 + dstYoffset * dstRowStride
627 + dstXoffset * texComponents;
628 for (img = 0; img < srcDepth; img++) {
629 GLchan *destRow = dest;
630 for (row = 0; row < srcHeight; row++) {
631 const GLvoid *src = _mesa_image_address(srcPacking,
632 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
633 _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
634 srcType, src, srcPacking,
635 ctx->_ImageTransferState);
636 destRow += dstRowStride;
637 }
638 dest += dstImageStride;
639 }
640 }
641 else if (texFormat == GL_DEPTH_COMPONENT) {
642 /* Depth texture (shadow maps) */
643 const GLenum texType = GL_FLOAT;
644 GLint img, row;
645 GLfloat *dest = (GLfloat *) texAddr + dstZoffset * dstImageStride
646 + dstYoffset * dstRowStride
647 + dstXoffset * texComponents;
648 for (img = 0; img < srcDepth; img++) {
649 GLfloat *destRow = dest;
650 for (row = 0; row < srcHeight; row++) {
651 const GLvoid *src = _mesa_image_address(srcPacking,
652 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
653 (void) src;
654 (void) texType;
655 /* XXX destRow: GLfloat vs. GLdepth? */
656 /*
657 _mesa_unpack_depth_span(ctx, srcWidth, texType, destRow,
658 srcType, src, srcPacking,
659 ctx->_ImageTransferState);
660 */
661 destRow += dstRowStride;
662 }
663 dest += dstImageStride;
664 }
665 }
666 else {
667 /* regular, color texture */
668 if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
669 (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
670 (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
671 /*
672 * Fill texture image with convolution
673 */
674 GLint img, row;
675 GLint convWidth = srcWidth, convHeight = srcHeight;
676 GLfloat *tmpImage, *convImage;
677 tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
678 if (!tmpImage) {
679 gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
680 return;
681 }
682 convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
683 if (!convImage) {
684 gl_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
685 FREE(tmpImage);
686 return;
687 }
688
689 for (img = 0; img < srcDepth; img++) {
690 const GLfloat *srcf;
691 GLfloat *dstf = tmpImage;
692 GLchan *dest;
693
694 /* unpack and do transfer ops up to convolution */
695 for (row = 0; row < srcHeight; row++) {
696 const GLvoid *src = _mesa_image_address(srcPacking,
697 srcAddr, srcWidth, srcHeight,
698 srcFormat, srcType, img, row, 0);
699 _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
700 srcFormat, srcType, src, srcPacking,
701 ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
702 GL_TRUE);
703 dstf += srcWidth * 4;
704 }
705
706 /* convolve */
707 if (dimensions == 1) {
708 ASSERT(ctx->Pixel.Convolution1DEnabled);
709 _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
710 }
711 else {
712 if (ctx->Pixel.Convolution2DEnabled) {
713 _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
714 tmpImage, convImage);
715 }
716 else {
717 ASSERT(ctx->Pixel.Separable2DEnabled);
718 _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
719 tmpImage, convImage);
720 }
721 }
722
723 /* packing and transfer ops after convolution */
724 srcf = convImage;
725 dest = texAddr + (dstZoffset + img) * dstImageStride
726 + dstYoffset * dstRowStride;
727 for (row = 0; row < convHeight; row++) {
728 _mesa_pack_float_rgba_span(ctx, convWidth,
729 (const GLfloat (*)[4]) srcf,
730 texFormat, CHAN_TYPE,
731 dest, &_mesa_native_packing,
732 ctx->_ImageTransferState
733 & IMAGE_POST_CONVOLUTION_BITS);
734 srcf += convWidth * 4;
735 dest += dstRowStride;
736 }
737 }
738
739 FREE(convImage);
740 FREE(tmpImage);
741 }
742 else {
743 /*
744 * no convolution
745 */
746 GLint img, row;
747 GLchan *dest = texAddr + dstZoffset * dstImageStride
748 + dstYoffset * dstRowStride
749 + dstXoffset * texComponents;
750 for (img = 0; img < srcDepth; img++) {
751 GLchan *destRow = dest;
752 for (row = 0; row < srcHeight; row++) {
753 const GLvoid *srcRow = _mesa_image_address(srcPacking,
754 srcAddr, srcWidth, srcHeight,
755 srcFormat, srcType, img, row, 0);
756 _mesa_unpack_chan_color_span(ctx, srcWidth, texFormat, destRow,
757 srcFormat, srcType, srcRow, srcPacking,
758 ctx->_ImageTransferState);
759 destRow += dstRowStride;
760 }
761 dest += dstImageStride;
762 }
763 }
764 }
765 }
766
767
768
769 /*
770 * This is the software fallback for Driver.TexImage1D().
771 * The texture image type will be GLchan.
772 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
773 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
774 *
775 */
776 void
777 _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
778 GLint internalFormat,
779 GLint width, GLint border,
780 GLenum format, GLenum type, const GLvoid *pixels,
781 const struct gl_pixelstore_attrib *packing,
782 struct gl_texture_object *texObj,
783 struct gl_texture_image *texImage)
784 {
785 const GLint components = components_in_intformat(internalFormat);
786 GLint compSize;
787 GLint postConvWidth = width;
788
789 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
790 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
791 }
792
793 /* setup the teximage struct's fields */
794 texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
795 if (format == GL_DEPTH_COMPONENT) {
796 texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
797 compSize = sizeof(GLfloat);
798 }
799 else {
800 texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
801 compSize = sizeof(CHAN_TYPE);
802 }
803 texImage->FetchTexel = fetch_1d_texel;
804 set_teximage_component_sizes(texImage);
805
806 /* allocate memory */
807 texImage->Data = (GLchan *) MALLOC(postConvWidth * components * compSize);
808 if (!texImage->Data)
809 return; /* out of memory */
810
811 /* unpack image, apply transfer ops and store in texImage->Data */
812 _mesa_transfer_teximage(ctx, 1, texImage->Format, texImage->Data,
813 width, 1, 1, 0, 0, 0,
814 0, /* dstRowStride */
815 0, /* dstImageStride */
816 format, type, pixels, packing);
817 }
818
819
820 /*
821 * This is the software fallback for Driver.TexImage2D().
822 * The texture image type will be GLchan.
823 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
824 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
825 *
826 */
827 void
828 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
829 GLint internalFormat,
830 GLint width, GLint height, GLint border,
831 GLenum format, GLenum type, const void *pixels,
832 const struct gl_pixelstore_attrib *packing,
833 struct gl_texture_object *texObj,
834 struct gl_texture_image *texImage)
835 {
836 const GLint components = components_in_intformat(internalFormat);
837 GLint compSize;
838 GLint postConvWidth = width, postConvHeight = height;
839
840 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
841 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
842 &postConvHeight);
843 }
844
845 /* setup the teximage struct's fields */
846 texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
847 if (format == GL_DEPTH_COMPONENT) {
848 texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
849 compSize = sizeof(GLfloat);
850 }
851 else {
852 texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
853 compSize = sizeof(CHAN_TYPE);
854 }
855 texImage->FetchTexel = fetch_2d_texel;
856 set_teximage_component_sizes(texImage);
857
858 /* allocate memory */
859 texImage->Data = (GLchan *) MALLOC(postConvWidth * postConvHeight
860 * components * compSize);
861 if (!texImage->Data)
862 return; /* out of memory */
863
864 /* unpack image, apply transfer ops and store in texImage->Data */
865 _mesa_transfer_teximage(ctx, 2, texImage->Format, texImage->Data,
866 width, height, 1, 0, 0, 0,
867 texImage->Width * components * sizeof(GLchan),
868 0, /* dstImageStride */
869 format, type, pixels, packing);
870 }
871
872
873
874 /*
875 * This is the software fallback for Driver.TexImage3D().
876 * The texture image type will be GLchan.
877 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
878 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
879 *
880 */
881 void
882 _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
883 GLint internalFormat,
884 GLint width, GLint height, GLint depth, GLint border,
885 GLenum format, GLenum type, const void *pixels,
886 const struct gl_pixelstore_attrib *packing,
887 struct gl_texture_object *texObj,
888 struct gl_texture_image *texImage)
889 {
890 const GLint components = components_in_intformat(internalFormat);
891 GLint compSize;
892
893 /* setup the teximage struct's fields */
894 texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
895 if (format == GL_DEPTH_COMPONENT) {
896 texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
897 compSize = sizeof(GLfloat);
898 }
899 else {
900 texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
901 compSize = sizeof(CHAN_TYPE);
902 }
903 texImage->FetchTexel = fetch_3d_texel;
904 set_teximage_component_sizes(texImage);
905
906 /* allocate memory */
907 texImage->Data = (GLchan *) MALLOC(width * height * depth
908 * components * compSize);
909 if (!texImage->Data)
910 return; /* out of memory */
911
912 /* unpack image, apply transfer ops and store in texImage->Data */
913 _mesa_transfer_teximage(ctx, 3, texImage->Format, texImage->Data,
914 width, height, depth, 0, 0, 0,
915 texImage->Width * components * sizeof(GLchan),
916 texImage->Width * texImage->Height * components
917 * sizeof(GLchan),
918 format, type, pixels, packing);
919 }
920
921
922
923
924 /*
925 * This is the software fallback for Driver.TexSubImage1D().
926 */
927 void
928 _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
929 GLint xoffset, GLint width,
930 GLenum format, GLenum type, const void *pixels,
931 const struct gl_pixelstore_attrib *packing,
932 struct gl_texture_object *texObj,
933 struct gl_texture_image *texImage)
934 {
935 _mesa_transfer_teximage(ctx, 1, texImage->Format, texImage->Data,
936 width, 1, 1, /* src size */
937 xoffset, 0, 0, /* dest offsets */
938 0, /* dstRowStride */
939 0, /* dstImageStride */
940 format, type, pixels, packing);
941 }
942
943
944 /*
945 * This is the software fallback for Driver.TexSubImage2D().
946 */
947 void
948 _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
949 GLint xoffset, GLint yoffset,
950 GLint width, GLint height,
951 GLenum format, GLenum type, const void *pixels,
952 const struct gl_pixelstore_attrib *packing,
953 struct gl_texture_object *texObj,
954 struct gl_texture_image *texImage)
955 {
956 const GLint components = components_in_intformat(texImage->IntFormat);
957 const GLint compSize = _mesa_sizeof_type(texImage->Type);
958 _mesa_transfer_teximage(ctx, 2, texImage->Format, texImage->Data,
959 width, height, 1, /* src size */
960 xoffset, yoffset, 0, /* dest offsets */
961 texImage->Width * components * compSize,
962 0, /* dstImageStride */
963 format, type, pixels, packing);
964 }
965
966
967 /*
968 * This is the software fallback for Driver.TexSubImage3D().
969 */
970 void
971 _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
972 GLint xoffset, GLint yoffset, GLint zoffset,
973 GLint width, GLint height, GLint depth,
974 GLenum format, GLenum type, const void *pixels,
975 const struct gl_pixelstore_attrib *packing,
976 struct gl_texture_object *texObj,
977 struct gl_texture_image *texImage)
978 {
979 const GLint components = components_in_intformat(texImage->IntFormat);
980 const GLint compSize = _mesa_sizeof_type(texImage->Type);
981 _mesa_transfer_teximage(ctx, 3, texImage->Format, texImage->Data,
982 width, height, depth, /* src size */
983 xoffset, yoffset, xoffset, /* dest offsets */
984 texImage->Width * components * compSize,
985 texImage->Width * texImage->Height * components
986 * compSize,
987 format, type, pixels, packing);
988 }
989
990
991
992 /*
993 * Fallback for Driver.CompressedTexImage1D()
994 */
995 void
996 _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
997 GLint internalFormat,
998 GLint width, GLint border,
999 GLsizei imageSize, const GLvoid *data,
1000 struct gl_texture_object *texObj,
1001 struct gl_texture_image *texImage)
1002 {
1003 /* Nothing here.
1004 * The device driver has to do it all.
1005 */
1006 }
1007
1008
1009
1010 /*
1011 * Fallback for Driver.CompressedTexImage2D()
1012 */
1013 void
1014 _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
1015 GLint internalFormat,
1016 GLint width, GLint height, GLint border,
1017 GLsizei imageSize, const GLvoid *data,
1018 struct gl_texture_object *texObj,
1019 struct gl_texture_image *texImage)
1020 {
1021 /* Nothing here.
1022 * The device driver has to do it all.
1023 */
1024 }
1025
1026
1027
1028 /*
1029 * Fallback for Driver.CompressedTexImage3D()
1030 */
1031 void
1032 _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
1033 GLint internalFormat,
1034 GLint width, GLint height, GLint depth,
1035 GLint border,
1036 GLsizei imageSize, const GLvoid *data,
1037 struct gl_texture_object *texObj,
1038 struct gl_texture_image *texImage)
1039 {
1040 /* Nothing here.
1041 * The device driver has to do it all.
1042 */
1043 }
1044
1045
1046
1047
1048
1049
1050 /*
1051 * This is the fallback for Driver.TestProxyTexImage().
1052 */
1053 GLboolean
1054 _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
1055 GLint internalFormat, GLenum format, GLenum type,
1056 GLint width, GLint height, GLint depth, GLint border)
1057 {
1058 struct gl_texture_unit *texUnit;
1059 struct gl_texture_object *texObj;
1060 struct gl_texture_image *texImage;
1061 GLint compSize;
1062
1063 (void) format;
1064 (void) type;
1065
1066 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1067 texObj = _mesa_select_tex_object(ctx, texUnit, target);
1068 texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
1069
1070 /* We always pass.
1071 * The core Mesa code will have already tested the image size, etc.
1072 * Drivers may have more stringent texture limits to enforce and will
1073 * have to override this function.
1074 */
1075 /* setup the teximage struct's fields */
1076 texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
1077 if (format == GL_DEPTH_COMPONENT) {
1078 texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
1079 compSize = sizeof(GLfloat);
1080 }
1081 else {
1082 texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
1083 compSize = sizeof(CHAN_TYPE);
1084 }
1085 set_teximage_component_sizes(texImage);
1086
1087 return GL_TRUE;
1088 }
1089