More texture image changes.
[mesa.git] / src / mesa / main / texstore.c
1 /* $Id: texstore.c,v 1.22 2001/04/04 21:54:21 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 "texformat.h"
48 #include "teximage.h"
49 #include "texstore.h"
50 #include "texutil.h"
51
52
53 /*
54 * Given an internal texture format enum or 1, 2, 3, 4 return the
55 * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE,
56 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the
57 * number of components for the format. Return -1 if invalid enum.
58 *
59 * GH: Do we really need this? We have the number of bytes per texel
60 * in the texture format structures, so why don't we just use that?
61 */
62 static GLint
63 components_in_intformat( GLint format )
64 {
65 switch (format) {
66 case GL_ALPHA:
67 case GL_ALPHA4:
68 case GL_ALPHA8:
69 case GL_ALPHA12:
70 case GL_ALPHA16:
71 return 1;
72 case 1:
73 case GL_LUMINANCE:
74 case GL_LUMINANCE4:
75 case GL_LUMINANCE8:
76 case GL_LUMINANCE12:
77 case GL_LUMINANCE16:
78 return 1;
79 case 2:
80 case GL_LUMINANCE_ALPHA:
81 case GL_LUMINANCE4_ALPHA4:
82 case GL_LUMINANCE6_ALPHA2:
83 case GL_LUMINANCE8_ALPHA8:
84 case GL_LUMINANCE12_ALPHA4:
85 case GL_LUMINANCE12_ALPHA12:
86 case GL_LUMINANCE16_ALPHA16:
87 return 2;
88 case GL_INTENSITY:
89 case GL_INTENSITY4:
90 case GL_INTENSITY8:
91 case GL_INTENSITY12:
92 case GL_INTENSITY16:
93 return 1;
94 case 3:
95 case GL_RGB:
96 case GL_R3_G3_B2:
97 case GL_RGB4:
98 case GL_RGB5:
99 case GL_RGB8:
100 case GL_RGB10:
101 case GL_RGB12:
102 case GL_RGB16:
103 return 3;
104 case 4:
105 case GL_RGBA:
106 case GL_RGBA2:
107 case GL_RGBA4:
108 case GL_RGB5_A1:
109 case GL_RGBA8:
110 case GL_RGB10_A2:
111 case GL_RGBA12:
112 case GL_RGBA16:
113 return 4;
114 case GL_COLOR_INDEX:
115 case GL_COLOR_INDEX1_EXT:
116 case GL_COLOR_INDEX2_EXT:
117 case GL_COLOR_INDEX4_EXT:
118 case GL_COLOR_INDEX8_EXT:
119 case GL_COLOR_INDEX12_EXT:
120 case GL_COLOR_INDEX16_EXT:
121 return 1;
122 case GL_DEPTH_COMPONENT:
123 case GL_DEPTH_COMPONENT16_SGIX:
124 case GL_DEPTH_COMPONENT24_SGIX:
125 case GL_DEPTH_COMPONENT32_SGIX:
126 return 1;
127 default:
128 return -1; /* error */
129 }
130 }
131
132
133 /*
134 * This function is used to transfer the user's image data into a texture
135 * image buffer. We handle both full texture images and subtexture images.
136 * We also take care of all image transfer operations here, including
137 * convolution, scale/bias, colortables, etc.
138 *
139 * The destination texel channel type is always GLchan.
140 *
141 * A hardware driver may use this as a helper routine to unpack and
142 * apply pixel transfer ops into a temporary image buffer. Then,
143 * convert the temporary image into the special hardware format.
144 *
145 * Input:
146 * dimensions - 1, 2, or 3
147 * texFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA,
148 * GL_RGB or GL_RGBA
149 * texDestAddr - destination image address
150 * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images
151 * dstXoffset, dstYoffset, dstZoffset - position to store the image within
152 * the destination 3D texture
153 * dstRowStride, dstImageStride - dest image strides in bytes
154 * srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc)
155 * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc
156 * srcPacking - describes packing of incoming image.
157 */
158 static void
159 transfer_teximage(GLcontext *ctx, GLuint dimensions,
160 GLenum texDestFormat, GLvoid *texDestAddr,
161 GLint srcWidth, GLint srcHeight, GLint srcDepth,
162 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
163 GLint dstRowStride, GLint dstImageStride,
164 GLenum srcFormat, GLenum srcType,
165 const GLvoid *srcAddr,
166 const struct gl_pixelstore_attrib *srcPacking)
167 {
168 GLint texComponents;
169
170 ASSERT(ctx);
171 ASSERT(dimensions >= 1 && dimensions <= 3);
172 ASSERT(texDestAddr);
173 ASSERT(srcWidth >= 1);
174 ASSERT(srcHeight >= 1);
175 ASSERT(srcDepth >= 1);
176 ASSERT(dstXoffset >= 0);
177 ASSERT(dstYoffset >= 0);
178 ASSERT(dstZoffset >= 0);
179 ASSERT(dstRowStride >= 0);
180 ASSERT(dstImageStride >= 0);
181 ASSERT(srcAddr);
182 ASSERT(srcPacking);
183
184 texComponents = components_in_intformat(texDestFormat);
185
186 /* try common 2D texture cases first */
187 if (!ctx->_ImageTransferState && dimensions == 2 && srcType == CHAN_TYPE) {
188
189 if (srcFormat == texDestFormat) {
190 /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
191 * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy().
192 */
193 const GLchan *src = (const GLchan *) _mesa_image_address(
194 srcPacking, srcAddr, srcWidth, srcHeight,
195 srcFormat, srcType, 0, 0, 0);
196 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
197 srcWidth, srcFormat, srcType);
198 const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan);
199 GLchan *dst = (GLchan *) texDestAddr + dstYoffset * dstRowStride
200 + dstXoffset * texComponents;
201 if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) {
202 MEMCPY(dst, src, srcHeight * widthInBytes);
203 }
204 else {
205 GLint i;
206 for (i = 0; i < srcHeight; i++) {
207 MEMCPY(dst, src, widthInBytes);
208 src += srcRowStride;
209 dst += dstRowStride;
210 }
211 }
212 return; /* all done */
213 }
214 else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) {
215 /* commonly used by Quake */
216 const GLchan *src = (const GLchan *) _mesa_image_address(
217 srcPacking, srcAddr, srcWidth, srcHeight,
218 srcFormat, srcType, 0, 0, 0);
219 const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
220 srcWidth, srcFormat, srcType);
221 GLchan *dst = (GLchan *) texDestAddr + dstYoffset * dstRowStride
222 + dstXoffset * texComponents;
223 GLint i, j;
224 for (i = 0; i < srcHeight; i++) {
225 const GLchan *s = src;
226 GLchan *d = dst;
227 for (j = 0; j < srcWidth; j++) {
228 *d++ = *s++; /*red*/
229 *d++ = *s++; /*green*/
230 *d++ = *s++; /*blue*/
231 s++; /*alpha*/
232 }
233 src += srcRowStride;
234 dst += dstRowStride;
235 }
236 return; /* all done */
237 }
238 }
239
240 /*
241 * General case solutions
242 */
243 if (texDestFormat == GL_COLOR_INDEX) {
244 /* color index texture */
245 const GLenum texType = CHAN_TYPE;
246 GLint img, row;
247 GLchan *dest = (GLchan *) texDestAddr + dstZoffset * dstImageStride
248 + dstYoffset * dstRowStride
249 + dstXoffset * texComponents;
250 for (img = 0; img < srcDepth; img++) {
251 GLchan *destRow = dest;
252 for (row = 0; row < srcHeight; row++) {
253 const GLvoid *src = _mesa_image_address(srcPacking,
254 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
255 _mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
256 srcType, src, srcPacking,
257 ctx->_ImageTransferState);
258 destRow += dstRowStride;
259 }
260 dest += dstImageStride;
261 }
262 }
263 else if (texDestFormat == GL_DEPTH_COMPONENT) {
264 /* Depth texture (shadow maps) */
265 GLint img, row;
266 GLubyte *dest = (GLubyte *) texDestAddr
267 + dstZoffset * dstImageStride
268 + dstYoffset * dstRowStride
269 + dstXoffset * texComponents;
270 for (img = 0; img < srcDepth; img++) {
271 GLubyte *destRow = dest;
272 for (row = 0; row < srcHeight; row++) {
273 const GLvoid *src = _mesa_image_address(srcPacking,
274 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
275 _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow,
276 srcType, src, srcPacking);
277 destRow += dstRowStride;
278 }
279 dest += dstImageStride;
280 }
281 }
282 else {
283 /* regular, color texture */
284 if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) ||
285 (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) ||
286 (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) {
287 /*
288 * Fill texture image with convolution
289 */
290 GLint img, row;
291 GLint convWidth = srcWidth, convHeight = srcHeight;
292 GLfloat *tmpImage, *convImage;
293 tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
294 if (!tmpImage) {
295 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
296 return;
297 }
298 convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat));
299 if (!convImage) {
300 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
301 FREE(tmpImage);
302 return;
303 }
304
305 for (img = 0; img < srcDepth; img++) {
306 const GLfloat *srcf;
307 GLfloat *dstf = tmpImage;
308 GLchan *dest;
309
310 /* unpack and do transfer ops up to convolution */
311 for (row = 0; row < srcHeight; row++) {
312 const GLvoid *src = _mesa_image_address(srcPacking,
313 srcAddr, srcWidth, srcHeight,
314 srcFormat, srcType, img, row, 0);
315 _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
316 srcFormat, srcType, src, srcPacking,
317 ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
318 GL_TRUE);
319 dstf += srcWidth * 4;
320 }
321
322 /* convolve */
323 if (dimensions == 1) {
324 ASSERT(ctx->Pixel.Convolution1DEnabled);
325 _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage);
326 }
327 else {
328 if (ctx->Pixel.Convolution2DEnabled) {
329 _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
330 tmpImage, convImage);
331 }
332 else {
333 ASSERT(ctx->Pixel.Separable2DEnabled);
334 _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
335 tmpImage, convImage);
336 }
337 }
338
339 /* packing and transfer ops after convolution */
340 srcf = convImage;
341 dest = (GLchan *) texDestAddr + (dstZoffset + img) * dstImageStride
342 + dstYoffset * dstRowStride;
343 for (row = 0; row < convHeight; row++) {
344 _mesa_pack_float_rgba_span(ctx, convWidth,
345 (const GLfloat (*)[4]) srcf,
346 texDestFormat, CHAN_TYPE,
347 dest, &_mesa_native_packing,
348 ctx->_ImageTransferState
349 & IMAGE_POST_CONVOLUTION_BITS);
350 srcf += convWidth * 4;
351 dest += dstRowStride;
352 }
353 }
354
355 FREE(convImage);
356 FREE(tmpImage);
357 }
358 else {
359 /*
360 * no convolution
361 */
362 GLint img, row;
363 GLchan *dest = (GLchan *) texDestAddr + dstZoffset * dstImageStride
364 + dstYoffset * dstRowStride
365 + dstXoffset * texComponents;
366 for (img = 0; img < srcDepth; img++) {
367 GLchan *destRow = dest;
368 for (row = 0; row < srcHeight; row++) {
369 const GLvoid *srcRow = _mesa_image_address(srcPacking,
370 srcAddr, srcWidth, srcHeight,
371 srcFormat, srcType, img, row, 0);
372 _mesa_unpack_chan_color_span(ctx, srcWidth, texDestFormat,
373 destRow, srcFormat, srcType, srcRow,
374 srcPacking, ctx->_ImageTransferState);
375 destRow += dstRowStride;
376 }
377 dest += dstImageStride;
378 }
379 }
380 }
381 }
382
383
384
385 /*
386 * Transfer a texture image from user space to <destAddr> applying all
387 * needed image transfer operations and storing the result in the format
388 * specified by <dstFormat>. <dstFormat> may be any format from texformat.h.
389 * Input:
390 * dstRowStride - stride between dest rows in bytes
391 * dstImagetride - stride between dest images in bytes
392 *
393 * XXX this function is a bit more complicated than it should be. If
394 * _mesa_convert_texsubimage[123]d could handle any dest/source formats
395 * or if transfer_teximage() could store in any MESA_FORMAT_* format, we
396 * could simplify things here.
397 */
398 void
399 _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
400 const struct gl_texture_format *dstFormat,
401 GLvoid *dstAddr,
402 GLint srcWidth, GLint srcHeight, GLint srcDepth,
403 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
404 GLint dstRowStride, GLint dstImageStride,
405 GLenum srcFormat, GLenum srcType,
406 const GLvoid *srcAddr,
407 const struct gl_pixelstore_attrib *srcPacking)
408 {
409 const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes;
410 const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes;
411 GLboolean makeTemp;
412
413 /* First, determine if need to make a temporary, intermediate image */
414 if (_mesa_is_hardware_tex_format(dstFormat)) {
415 if (ctx->_ImageTransferState) {
416 makeTemp = GL_TRUE;
417 }
418 else {
419 if (dimensions == 1) {
420 makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat,
421 dstXoffset,
422 srcWidth,
423 srcFormat, srcType,
424 srcPacking, srcAddr,
425 dstAddr);
426 }
427 else if (dimensions == 2) {
428 makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat,
429 dstXoffset, dstYoffset,
430 srcWidth, srcHeight,
431 dstRowStridePixels,
432 srcFormat, srcType,
433 srcPacking, srcAddr,
434 dstAddr);
435 }
436 else {
437 assert(dimensions == 3);
438 makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat,
439 dstXoffset, dstYoffset, dstZoffset,
440 srcWidth, srcHeight, srcDepth,
441 dstRowStridePixels, dstImageStridePixels,
442 srcFormat, srcType,
443 srcPacking, srcAddr, dstAddr);
444 }
445 if (!makeTemp) {
446 /* all done! */
447 return;
448 }
449 }
450 }
451 else {
452 /* software texture format */
453 makeTemp = GL_FALSE;
454 }
455
456
457 if (makeTemp) {
458 GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
459 GLenum tmpFormat;
460 GLuint tmpComps, tmpTexelSize;
461 GLint tmpRowStride, tmpImageStride;
462 GLubyte *tmpImage;
463
464 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
465 _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
466 &postConvHeight);
467 }
468
469 tmpFormat = _mesa_base_tex_format(ctx, dstFormat->IntFormat);
470 tmpComps = _mesa_components_in_format(tmpFormat);
471 tmpTexelSize = tmpComps * sizeof(CHAN_TYPE);
472 tmpRowStride = postConvWidth * tmpTexelSize;
473 tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize;
474 tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight *
475 srcDepth * tmpTexelSize);
476 if (!tmpImage)
477 return;
478
479 transfer_teximage(ctx, dimensions, tmpFormat, tmpImage,
480 srcWidth, srcHeight, srcDepth,
481 0, 0, 0, /* x/y/zoffset */
482 tmpRowStride, tmpImageStride,
483 srcFormat, srcType, srcAddr, srcPacking);
484
485 /* the temp image is our new source image */
486 srcWidth = postConvWidth;
487 srcHeight = postConvHeight;
488 srcFormat = tmpFormat;
489 srcType = CHAN_TYPE;
490 srcAddr = tmpImage;
491 srcPacking = &_mesa_native_packing;
492 }
493
494 if (_mesa_is_hardware_tex_format(dstFormat)) {
495 assert(makeTemp);
496 if (dimensions == 1) {
497 GLboolean b;
498 b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat,
499 dstXoffset,
500 srcWidth,
501 srcFormat, srcType,
502 srcPacking, srcAddr,
503 dstAddr);
504 assert(b);
505 }
506 else if (dimensions == 2) {
507 GLboolean b;
508 b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat,
509 dstXoffset, dstYoffset,
510 srcWidth, srcHeight,
511 dstRowStridePixels,
512 srcFormat, srcType,
513 srcPacking, srcAddr,
514 dstAddr);
515 assert(b);
516 }
517 else {
518 GLboolean b;
519 b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat,
520 dstXoffset, dstYoffset, dstZoffset,
521 srcWidth, srcHeight, srcDepth,
522 dstRowStridePixels, dstImageStridePixels,
523 srcFormat, srcType,
524 srcPacking, srcAddr, dstAddr);
525 assert(b);
526 }
527 FREE((void *) srcAddr); /* the temp image */
528 }
529 else {
530 /* software format */
531 GLenum dstBaseFormat = _mesa_base_tex_format(ctx, dstFormat->IntFormat);
532 assert(!makeTemp);
533 transfer_teximage(ctx, dimensions, dstBaseFormat, dstAddr,
534 srcWidth, srcHeight, srcDepth,
535 dstXoffset, dstYoffset, dstZoffset,
536 dstRowStride, dstImageStride,
537 srcFormat, srcType, srcAddr, srcPacking);
538 }
539 }
540
541
542 /*
543 * This is the software fallback for Driver.TexImage1D().
544 * The texture image type will be GLchan.
545 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
546 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
547 *
548 */
549 void
550 _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
551 GLint internalFormat,
552 GLint width, GLint border,
553 GLenum format, GLenum type, const GLvoid *pixels,
554 const struct gl_pixelstore_attrib *packing,
555 struct gl_texture_object *texObj,
556 struct gl_texture_image *texImage)
557 {
558 GLint postConvWidth = width;
559 GLint texelBytes;
560
561 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
562 _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
563 }
564
565 /* choose the texture format */
566 assert(ctx->Driver.ChooseTextureFormat);
567 texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
568 internalFormat, format, type);
569 assert(texImage->TexFormat);
570
571 texelBytes = texImage->TexFormat->TexelBytes;
572
573 /* allocate memory */
574 texImage->Data = MALLOC(postConvWidth * texelBytes);
575 if (!texImage->Data) {
576 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
577 return;
578 }
579
580 /* unpack image, apply transfer ops and store in texImage->Data */
581 _mesa_transfer_teximage(ctx, 1, texImage->TexFormat, texImage->Data,
582 width, 1, 1, 0, 0, 0,
583 0, /* dstRowStride */
584 0, /* dstImageStride */
585 format, type, pixels, packing);
586 }
587
588
589 /*
590 * This is the software fallback for Driver.TexImage2D().
591 * The texture image type will be GLchan.
592 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
593 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
594 *
595 */
596 void
597 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
598 GLint internalFormat,
599 GLint width, GLint height, GLint border,
600 GLenum format, GLenum type, const void *pixels,
601 const struct gl_pixelstore_attrib *packing,
602 struct gl_texture_object *texObj,
603 struct gl_texture_image *texImage)
604 {
605 GLint postConvWidth = width, postConvHeight = height;
606 GLint texelBytes;
607
608 if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
609 _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
610 &postConvHeight);
611 }
612
613 /* choose the texture format */
614 assert(ctx->Driver.ChooseTextureFormat);
615 texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
616 internalFormat, format, type);
617 assert(texImage->TexFormat);
618
619 texelBytes = texImage->TexFormat->TexelBytes;
620
621 /* allocate memory */
622 texImage->Data = MALLOC(postConvWidth * postConvHeight * texelBytes);
623 if (!texImage->Data) {
624 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
625 return;
626 }
627
628 /* unpack image, apply transfer ops and store in texImage->Data */
629 _mesa_transfer_teximage(ctx, 2, texImage->TexFormat, texImage->Data,
630 width, height, 1, 0, 0, 0,
631 texImage->Width * texelBytes,
632 0, /* dstImageStride */
633 format, type, pixels, packing);
634 }
635
636
637
638 /*
639 * This is the software fallback for Driver.TexImage3D().
640 * The texture image type will be GLchan.
641 * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY,
642 * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA.
643 *
644 */
645 void
646 _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
647 GLint internalFormat,
648 GLint width, GLint height, GLint depth, GLint border,
649 GLenum format, GLenum type, const void *pixels,
650 const struct gl_pixelstore_attrib *packing,
651 struct gl_texture_object *texObj,
652 struct gl_texture_image *texImage)
653 {
654 GLint texelBytes;
655
656 /* choose the texture format */
657 assert(ctx->Driver.ChooseTextureFormat);
658 texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
659 internalFormat, format, type);
660 assert(texImage->TexFormat);
661
662 texelBytes = texImage->TexFormat->TexelBytes;
663
664 /* allocate memory */
665 texImage->Data = MALLOC(width * height * depth * texelBytes);
666 if (!texImage->Data) {
667 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
668 return;
669 }
670
671 /* unpack image, apply transfer ops and store in texImage->Data */
672 _mesa_transfer_teximage(ctx, 3, texImage->TexFormat, texImage->Data,
673 width, height, depth, 0, 0, 0,
674 texImage->Width * texelBytes,
675 texImage->Width * texImage->Height * texelBytes,
676 format, type, pixels, packing);
677 }
678
679
680
681
682 /*
683 * This is the software fallback for Driver.TexSubImage1D().
684 */
685 void
686 _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
687 GLint xoffset, GLint width,
688 GLenum format, GLenum type, const void *pixels,
689 const struct gl_pixelstore_attrib *packing,
690 struct gl_texture_object *texObj,
691 struct gl_texture_image *texImage)
692 {
693 _mesa_transfer_teximage(ctx, 1, texImage->TexFormat, texImage->Data,
694 width, 1, 1, /* src size */
695 xoffset, 0, 0, /* dest offsets */
696 0, /* dstRowStride */
697 0, /* dstImageStride */
698 format, type, pixels, packing);
699 }
700
701
702 /*
703 * This is the software fallback for Driver.TexSubImage2D().
704 */
705 void
706 _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
707 GLint xoffset, GLint yoffset,
708 GLint width, GLint height,
709 GLenum format, GLenum type, const void *pixels,
710 const struct gl_pixelstore_attrib *packing,
711 struct gl_texture_object *texObj,
712 struct gl_texture_image *texImage)
713 {
714 _mesa_transfer_teximage(ctx, 2, texImage->TexFormat, texImage->Data,
715 width, height, 1, /* src size */
716 xoffset, yoffset, 0, /* dest offsets */
717 texImage->Width * texImage->TexFormat->TexelBytes,
718 0, /* dstImageStride */
719 format, type, pixels, packing);
720 }
721
722
723 /*
724 * This is the software fallback for Driver.TexSubImage3D().
725 */
726 void
727 _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
728 GLint xoffset, GLint yoffset, GLint zoffset,
729 GLint width, GLint height, GLint depth,
730 GLenum format, GLenum type, const void *pixels,
731 const struct gl_pixelstore_attrib *packing,
732 struct gl_texture_object *texObj,
733 struct gl_texture_image *texImage)
734 {
735 const GLint texelBytes = texImage->TexFormat->TexelBytes;
736 _mesa_transfer_teximage(ctx, 3, texImage->TexFormat, texImage->Data,
737 width, height, depth, /* src size */
738 xoffset, yoffset, xoffset, /* dest offsets */
739 texImage->Width * texelBytes,
740 texImage->Width * texImage->Height * texelBytes,
741 format, type, pixels, packing);
742 }
743
744
745
746
747 /*
748 * Fallback for Driver.CompressedTexImage1D()
749 */
750 void
751 _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
752 GLint internalFormat,
753 GLint width, GLint border,
754 GLsizei imageSize, const GLvoid *data,
755 struct gl_texture_object *texObj,
756 struct gl_texture_image *texImage)
757 {
758 /* Nothing here.
759 * The device driver has to do it all.
760 */
761 }
762
763
764
765 /*
766 * Fallback for Driver.CompressedTexImage2D()
767 */
768 void
769 _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
770 GLint internalFormat,
771 GLint width, GLint height, GLint border,
772 GLsizei imageSize, const GLvoid *data,
773 struct gl_texture_object *texObj,
774 struct gl_texture_image *texImage)
775 {
776 /* Nothing here.
777 * The device driver has to do it all.
778 */
779 }
780
781
782
783 /*
784 * Fallback for Driver.CompressedTexImage3D()
785 */
786 void
787 _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
788 GLint internalFormat,
789 GLint width, GLint height, GLint depth,
790 GLint border,
791 GLsizei imageSize, const GLvoid *data,
792 struct gl_texture_object *texObj,
793 struct gl_texture_image *texImage)
794 {
795 /* Nothing here.
796 * The device driver has to do it all.
797 */
798 }
799
800
801
802 /*
803 * This is the fallback for Driver.TestProxyTexImage().
804 */
805 GLboolean
806 _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
807 GLint internalFormat, GLenum format, GLenum type,
808 GLint width, GLint height, GLint depth, GLint border)
809 {
810 struct gl_texture_unit *texUnit;
811 struct gl_texture_object *texObj;
812 struct gl_texture_image *texImage;
813
814 (void) format;
815 (void) type;
816
817 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
818 texObj = _mesa_select_tex_object(ctx, texUnit, target);
819 texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
820
821 /* We always pass.
822 * The core Mesa code will have already tested the image size, etc.
823 * Drivers may have more stringent texture limits to enforce and will
824 * have to override this function.
825 */
826 /* choose the texture format */
827 assert(ctx->Driver.ChooseTextureFormat);
828 texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx,
829 internalFormat, format, type);
830 assert(texImage->TexFormat);
831
832 return GL_TRUE;
833 }