Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 1
/*
2
 * Mesa 3-D graphics library
3
 * Version:  7.5
4
 *
5
 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6
 * Copyright (c) 2008-2009  VMware, Inc.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 * copy of this software and associated documentation files (the "Software"),
10
 * to deal in the Software without restriction, including without limitation
11
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
 * and/or sell copies of the Software, and to permit persons to whom the
13
 * Software is furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included
16
 * in all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 */
25
 
26
/*
27
 * Authors:
28
 *   Brian Paul
29
 */
30
 
31
/**
32
 * The GL texture image functions in teximage.c basically just do
33
 * error checking and data structure allocation.  They in turn call
34
 * device driver functions which actually copy/convert/store the user's
35
 * texture image data.
36
 *
37
 * However, most device drivers will be able to use the fallback functions
38
 * in this file.  That is, most drivers will have the following bit of
39
 * code:
40
 *   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
41
 *   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
42
 *   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
43
 *   etc...
44
 *
45
 * Texture image processing is actually kind of complicated.  We have to do:
46
 *    Format/type conversions
47
 *    pixel unpacking
48
 *    pixel transfer (scale, bais, lookup, etc)
49
 *
50
 * These functions can handle most everything, including processing full
51
 * images and sub-images.
52
 */
53
 
54
 
55
#include "glheader.h"
56
#include "bufferobj.h"
57
#include "colormac.h"
58
#include "image.h"
59
#include "macros.h"
60
#include "mipmap.h"
61
#include "pack.h"
62
#include "imports.h"
63
#include "pack.h"
64
#include "texcompress.h"
65
#include "texcompress_fxt1.h"
66
#include "texcompress_s3tc.h"
67
#include "teximage.h"
68
#include "texstore.h"
69
#include "enums.h"
70
 
71
 
72
enum {
73
   ZERO = 4,
74
   ONE = 5
75
};
76
 
77
 
78
/**
79
 * Texture image storage function.
80
 */
81
typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
82
 
83
 
84
/**
85
 * Return GL_TRUE if the given image format is one that be converted
86
 * to another format by swizzling.
87
 */
88
static GLboolean
89
can_swizzle(GLenum logicalBaseFormat)
90
{
91
   switch (logicalBaseFormat) {
92
   case GL_RGBA:
93
   case GL_RGB:
94
   case GL_LUMINANCE_ALPHA:
95
   case GL_INTENSITY:
96
   case GL_ALPHA:
97
   case GL_LUMINANCE:
98
   case GL_RED:
99
   case GL_GREEN:
100
   case GL_BLUE:
101
   case GL_BGR:
102
   case GL_BGRA:
103
   case GL_ABGR_EXT:
104
   case GL_RG:
105
      return GL_TRUE;
106
   default:
107
      return GL_FALSE;
108
   }
109
}
110
 
111
 
112
 
113
enum {
114
   IDX_LUMINANCE = 0,
115
   IDX_ALPHA,
116
   IDX_INTENSITY,
117
   IDX_LUMINANCE_ALPHA,
118
   IDX_RGB,
119
   IDX_RGBA,
120
   IDX_RED,
121
   IDX_GREEN,
122
   IDX_BLUE,
123
   IDX_BGR,
124
   IDX_BGRA,
125
   IDX_ABGR,
126
   IDX_RG,
127
   MAX_IDX
128
};
129
 
130
#define MAP1(x)       MAP4(x, ZERO, ZERO, ZERO)
131
#define MAP2(x,y)     MAP4(x, y, ZERO, ZERO)
132
#define MAP3(x,y,z)   MAP4(x, y, z, ZERO)
133
#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
134
 
135
 
136
static const struct {
137
   GLubyte format_idx;
138
   GLubyte to_rgba[6];
139
   GLubyte from_rgba[6];
140
} mappings[MAX_IDX] =
141
{
142
   {
143
      IDX_LUMINANCE,
144
      MAP4(0,0,0,ONE),
145
      MAP1(0)
146
   },
147
 
148
   {
149
      IDX_ALPHA,
150
      MAP4(ZERO, ZERO, ZERO, 0),
151
      MAP1(3)
152
   },
153
 
154
   {
155
      IDX_INTENSITY,
156
      MAP4(0, 0, 0, 0),
157
      MAP1(0),
158
   },
159
 
160
   {
161
      IDX_LUMINANCE_ALPHA,
162
      MAP4(0,0,0,1),
163
      MAP2(0,3)
164
   },
165
 
166
   {
167
      IDX_RGB,
168
      MAP4(0,1,2,ONE),
169
      MAP3(0,1,2)
170
   },
171
 
172
   {
173
      IDX_RGBA,
174
      MAP4(0,1,2,3),
175
      MAP4(0,1,2,3),
176
   },
177
 
178
   {
179
      IDX_RED,
180
      MAP4(0, ZERO, ZERO, ONE),
181
      MAP1(0),
182
   },
183
 
184
   {
185
      IDX_GREEN,
186
      MAP4(ZERO, 0, ZERO, ONE),
187
      MAP1(1),
188
   },
189
 
190
   {
191
      IDX_BLUE,
192
      MAP4(ZERO, ZERO, 0, ONE),
193
      MAP1(2),
194
   },
195
 
196
   {
197
      IDX_BGR,
198
      MAP4(2,1,0,ONE),
199
      MAP3(2,1,0)
200
   },
201
 
202
   {
203
      IDX_BGRA,
204
      MAP4(2,1,0,3),
205
      MAP4(2,1,0,3)
206
   },
207
 
208
   {
209
      IDX_ABGR,
210
      MAP4(3,2,1,0),
211
      MAP4(3,2,1,0)
212
   },
213
 
214
   {
215
      IDX_RG,
216
      MAP4(0, 1, ZERO, ONE),
217
      MAP2(0, 1)
218
   },
219
};
220
 
221
 
222
 
223
/**
224
 * Convert a GL image format enum to an IDX_* value (see above).
225
 */
226
static int
227
get_map_idx(GLenum value)
228
{
229
   switch (value) {
230
   case GL_LUMINANCE: return IDX_LUMINANCE;
231
   case GL_ALPHA: return IDX_ALPHA;
232
   case GL_INTENSITY: return IDX_INTENSITY;
233
   case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
234
   case GL_RGB: return IDX_RGB;
235
   case GL_RGBA: return IDX_RGBA;
236
   case GL_RED: return IDX_RED;
237
   case GL_GREEN: return IDX_GREEN;
238
   case GL_BLUE: return IDX_BLUE;
239
   case GL_BGR: return IDX_BGR;
240
   case GL_BGRA: return IDX_BGRA;
241
   case GL_ABGR_EXT: return IDX_ABGR;
242
   case GL_RG: return IDX_RG;
243
   default:
244
      _mesa_problem(NULL, "Unexpected inFormat");
245
      return 0;
246
   }
247
}
248
 
249
 
250
/**
251
 * When promoting texture formats (see below) we need to compute the
252
 * mapping of dest components back to source components.
253
 * This function does that.
254
 * \param inFormat  the incoming format of the texture
255
 * \param outFormat  the final texture format
256
 * \return map[6]  a full 6-component map
257
 */
258
static void
259
compute_component_mapping(GLenum inFormat, GLenum outFormat,
260
			  GLubyte *map)
261
{
262
   const int inFmt = get_map_idx(inFormat);
263
   const int outFmt = get_map_idx(outFormat);
264
   const GLubyte *in2rgba = mappings[inFmt].to_rgba;
265
   const GLubyte *rgba2out = mappings[outFmt].from_rgba;
266
   int i;
267
 
268
   for (i = 0; i < 4; i++)
269
      map[i] = in2rgba[rgba2out[i]];
270
 
271
   map[ZERO] = ZERO;
272
   map[ONE] = ONE;
273
 
274
#if 0
275
   printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
276
	  inFormat, _mesa_lookup_enum_by_nr(inFormat),
277
	  outFormat, _mesa_lookup_enum_by_nr(outFormat),
278
	  map[0],
279
	  map[1],
280
	  map[2],
281
	  map[3],
282
	  map[4],
283
	  map[5]);
284
#endif
285
}
286
 
287
 
288
/**
289
 * Make a temporary (color) texture image with GLfloat components.
290
 * Apply all needed pixel unpacking and pixel transfer operations.
291
 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
292
 * Suppose the user specifies GL_LUMINANCE as the internal texture format
293
 * but the graphics hardware doesn't support luminance textures.  So, we might
294
 * use an RGB hardware format instead.
295
 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
296
 *
297
 * \param ctx  the rendering context
298
 * \param dims  image dimensions: 1, 2 or 3
299
 * \param logicalBaseFormat  basic texture derived from the user's
300
 *    internal texture format value
301
 * \param textureBaseFormat  the actual basic format of the texture
302
 * \param srcWidth  source image width
303
 * \param srcHeight  source image height
304
 * \param srcDepth  source image depth
305
 * \param srcFormat  source image format
306
 * \param srcType  source image type
307
 * \param srcAddr  source image address
308
 * \param srcPacking  source image pixel packing
309
 * \return resulting image with format = textureBaseFormat and type = GLfloat.
310
 */
311
static GLfloat *
312
make_temp_float_image(struct gl_context *ctx, GLuint dims,
313
                      GLenum logicalBaseFormat,
314
                      GLenum textureBaseFormat,
315
                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
316
                      GLenum srcFormat, GLenum srcType,
317
                      const GLvoid *srcAddr,
318
                      const struct gl_pixelstore_attrib *srcPacking,
319
                      GLbitfield transferOps)
320
{
321
   GLfloat *tempImage;
322
   const GLint components = _mesa_components_in_format(logicalBaseFormat);
323
   const GLint srcStride =
324
      _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
325
   GLfloat *dst;
326
   GLint img, row;
327
 
328
   ASSERT(dims >= 1 && dims <= 3);
329
 
330
   ASSERT(logicalBaseFormat == GL_RGBA ||
331
          logicalBaseFormat == GL_RGB ||
332
          logicalBaseFormat == GL_RG ||
333
          logicalBaseFormat == GL_RED ||
334
          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
335
          logicalBaseFormat == GL_LUMINANCE ||
336
          logicalBaseFormat == GL_ALPHA ||
337
          logicalBaseFormat == GL_INTENSITY ||
338
          logicalBaseFormat == GL_COLOR_INDEX ||
339
          logicalBaseFormat == GL_DEPTH_COMPONENT);
340
 
341
   ASSERT(textureBaseFormat == GL_RGBA ||
342
          textureBaseFormat == GL_RGB ||
343
          textureBaseFormat == GL_RG ||
344
          textureBaseFormat == GL_RED ||
345
          textureBaseFormat == GL_LUMINANCE_ALPHA ||
346
          textureBaseFormat == GL_LUMINANCE ||
347
          textureBaseFormat == GL_ALPHA ||
348
          textureBaseFormat == GL_INTENSITY ||
349
          textureBaseFormat == GL_COLOR_INDEX ||
350
          textureBaseFormat == GL_DEPTH_COMPONENT);
351
 
352
   tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
353
				  * components * sizeof(GLfloat));
354
   if (!tempImage)
355
      return NULL;
356
 
357
   dst = tempImage;
358
   for (img = 0; img < srcDepth; img++) {
359
      const GLubyte *src
360
	 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
361
						 srcWidth, srcHeight,
362
						 srcFormat, srcType,
363
						 img, 0, 0);
364
      for (row = 0; row < srcHeight; row++) {
365
	 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
366
				       dst, srcFormat, srcType, src,
367
				       srcPacking, transferOps);
368
	 dst += srcWidth * components;
369
	 src += srcStride;
370
      }
371
   }
372
 
373
   if (logicalBaseFormat != textureBaseFormat) {
374
      /* more work */
375
      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
376
      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
377
      GLfloat *newImage;
378
      GLint i, n;
379
      GLubyte map[6];
380
 
381
      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
382
      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
383
             textureBaseFormat == GL_LUMINANCE_ALPHA);
384
 
385
      /* The actual texture format should have at least as many components
386
       * as the logical texture format.
387
       */
388
      ASSERT(texComponents >= logComponents);
389
 
390
      newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
391
                                          * texComponents * sizeof(GLfloat));
392
      if (!newImage) {
393
         free(tempImage);
394
         return NULL;
395
      }
396
 
397
      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
398
 
399
      n = srcWidth * srcHeight * srcDepth;
400
      for (i = 0; i < n; i++) {
401
         GLint k;
402
         for (k = 0; k < texComponents; k++) {
403
            GLint j = map[k];
404
            if (j == ZERO)
405
               newImage[i * texComponents + k] = 0.0F;
406
            else if (j == ONE)
407
               newImage[i * texComponents + k] = 1.0F;
408
            else
409
               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
410
         }
411
      }
412
 
413
      free(tempImage);
414
      tempImage = newImage;
415
   }
416
 
417
   return tempImage;
418
}
419
 
420
 
421
/**
422
 * Make temporary image with uint pixel values.  Used for unsigned
423
 * integer-valued textures.
424
 */
425
static GLuint *
426
make_temp_uint_image(struct gl_context *ctx, GLuint dims,
427
                     GLenum logicalBaseFormat,
428
                     GLenum textureBaseFormat,
429
                     GLint srcWidth, GLint srcHeight, GLint srcDepth,
430
                     GLenum srcFormat, GLenum srcType,
431
                     const GLvoid *srcAddr,
432
                     const struct gl_pixelstore_attrib *srcPacking)
433
{
434
   GLuint *tempImage;
435
   const GLint components = _mesa_components_in_format(logicalBaseFormat);
436
   const GLint srcStride =
437
      _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
438
   GLuint *dst;
439
   GLint img, row;
440
 
441
   ASSERT(dims >= 1 && dims <= 3);
442
 
443
   ASSERT(logicalBaseFormat == GL_RGBA ||
444
          logicalBaseFormat == GL_RGB ||
445
          logicalBaseFormat == GL_RG ||
446
          logicalBaseFormat == GL_RED ||
447
          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
448
          logicalBaseFormat == GL_LUMINANCE ||
449
          logicalBaseFormat == GL_INTENSITY ||
450
          logicalBaseFormat == GL_ALPHA);
451
 
452
   ASSERT(textureBaseFormat == GL_RGBA ||
453
          textureBaseFormat == GL_RGB ||
454
          textureBaseFormat == GL_RG ||
455
          textureBaseFormat == GL_RED ||
456
          textureBaseFormat == GL_LUMINANCE_ALPHA ||
457
          textureBaseFormat == GL_LUMINANCE ||
458
          textureBaseFormat == GL_ALPHA);
459
 
460
   tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
461
                                 * components * sizeof(GLuint));
462
   if (!tempImage)
463
      return NULL;
464
 
465
   dst = tempImage;
466
   for (img = 0; img < srcDepth; img++) {
467
      const GLubyte *src
468
	 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
469
						 srcWidth, srcHeight,
470
						 srcFormat, srcType,
471
						 img, 0, 0);
472
      for (row = 0; row < srcHeight; row++) {
473
	 _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
474
                                      dst, srcFormat, srcType, src,
475
                                      srcPacking);
476
	 dst += srcWidth * components;
477
	 src += srcStride;
478
      }
479
   }
480
 
481
   if (logicalBaseFormat != textureBaseFormat) {
482
      /* more work */
483
      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
484
      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
485
      GLuint *newImage;
486
      GLint i, n;
487
      GLubyte map[6];
488
 
489
      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
490
      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
491
             textureBaseFormat == GL_LUMINANCE_ALPHA);
492
 
493
      /* The actual texture format should have at least as many components
494
       * as the logical texture format.
495
       */
496
      ASSERT(texComponents >= logComponents);
497
 
498
      newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
499
                                   * texComponents * sizeof(GLuint));
500
      if (!newImage) {
501
         free(tempImage);
502
         return NULL;
503
      }
504
 
505
      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
506
 
507
      n = srcWidth * srcHeight * srcDepth;
508
      for (i = 0; i < n; i++) {
509
         GLint k;
510
         for (k = 0; k < texComponents; k++) {
511
            GLint j = map[k];
512
            if (j == ZERO)
513
               newImage[i * texComponents + k] = 0.0F;
514
            else if (j == ONE)
515
               newImage[i * texComponents + k] = 1.0F;
516
            else
517
               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
518
         }
519
      }
520
 
521
      free(tempImage);
522
      tempImage = newImage;
523
   }
524
 
525
   return tempImage;
526
}
527
 
528
 
529
 
530
/**
531
 * Make a temporary (color) texture image with GLchan components.
532
 * Apply all needed pixel unpacking and pixel transfer operations.
533
 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
534
 * Suppose the user specifies GL_LUMINANCE as the internal texture format
535
 * but the graphics hardware doesn't support luminance textures.  So, we might
536
 * use an RGB hardware format instead.
537
 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
538
 *
539
 * \param ctx  the rendering context
540
 * \param dims  image dimensions: 1, 2 or 3
541
 * \param logicalBaseFormat  basic texture derived from the user's
542
 *    internal texture format value
543
 * \param textureBaseFormat  the actual basic format of the texture
544
 * \param srcWidth  source image width
545
 * \param srcHeight  source image height
546
 * \param srcDepth  source image depth
547
 * \param srcFormat  source image format
548
 * \param srcType  source image type
549
 * \param srcAddr  source image address
550
 * \param srcPacking  source image pixel packing
551
 * \return resulting image with format = textureBaseFormat and type = GLchan.
552
 */
553
GLchan *
554
_mesa_make_temp_chan_image(struct gl_context *ctx, GLuint dims,
555
                           GLenum logicalBaseFormat,
556
                           GLenum textureBaseFormat,
557
                           GLint srcWidth, GLint srcHeight, GLint srcDepth,
558
                           GLenum srcFormat, GLenum srcType,
559
                           const GLvoid *srcAddr,
560
                           const struct gl_pixelstore_attrib *srcPacking)
561
{
562
   GLuint transferOps = ctx->_ImageTransferState;
563
   const GLint components = _mesa_components_in_format(logicalBaseFormat);
564
   GLint img, row;
565
   GLchan *tempImage, *dst;
566
 
567
   ASSERT(dims >= 1 && dims <= 3);
568
 
569
   ASSERT(logicalBaseFormat == GL_RGBA ||
570
          logicalBaseFormat == GL_RGB ||
571
          logicalBaseFormat == GL_RG ||
572
          logicalBaseFormat == GL_RED ||
573
          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
574
          logicalBaseFormat == GL_LUMINANCE ||
575
          logicalBaseFormat == GL_ALPHA ||
576
          logicalBaseFormat == GL_INTENSITY);
577
 
578
   ASSERT(textureBaseFormat == GL_RGBA ||
579
          textureBaseFormat == GL_RGB ||
580
          textureBaseFormat == GL_RG ||
581
          textureBaseFormat == GL_RED ||
582
          textureBaseFormat == GL_LUMINANCE_ALPHA ||
583
          textureBaseFormat == GL_LUMINANCE ||
584
          textureBaseFormat == GL_ALPHA ||
585
          textureBaseFormat == GL_INTENSITY);
586
 
587
   /* unpack and transfer the source image */
588
   tempImage = (GLchan *) malloc(srcWidth * srcHeight * srcDepth
589
                                       * components * sizeof(GLchan));
590
   if (!tempImage) {
591
      return NULL;
592
   }
593
 
594
   dst = tempImage;
595
   for (img = 0; img < srcDepth; img++) {
596
      const GLint srcStride =
597
         _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
598
      const GLubyte *src =
599
         (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
600
                                               srcWidth, srcHeight,
601
                                               srcFormat, srcType,
602
                                               img, 0, 0);
603
      for (row = 0; row < srcHeight; row++) {
604
         _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
605
                                      srcFormat, srcType, src, srcPacking,
606
                                      transferOps);
607
         dst += srcWidth * components;
608
         src += srcStride;
609
      }
610
   }
611
 
612
   if (logicalBaseFormat != textureBaseFormat) {
613
      /* one more conversion step */
614
      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
615
      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
616
      GLchan *newImage;
617
      GLint i, n;
618
      GLubyte map[6];
619
 
620
      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
621
      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
622
             textureBaseFormat == GL_LUMINANCE_ALPHA);
623
 
624
      /* The actual texture format should have at least as many components
625
       * as the logical texture format.
626
       */
627
      ASSERT(texComponents >= logComponents);
628
 
629
      newImage = (GLchan *) malloc(srcWidth * srcHeight * srcDepth
630
                                         * texComponents * sizeof(GLchan));
631
      if (!newImage) {
632
         free(tempImage);
633
         return NULL;
634
      }
635
 
636
      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
637
 
638
      n = srcWidth * srcHeight * srcDepth;
639
      for (i = 0; i < n; i++) {
640
         GLint k;
641
         for (k = 0; k < texComponents; k++) {
642
            GLint j = map[k];
643
            if (j == ZERO)
644
               newImage[i * texComponents + k] = 0;
645
            else if (j == ONE)
646
               newImage[i * texComponents + k] = CHAN_MAX;
647
            else
648
               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
649
         }
650
      }
651
 
652
      free(tempImage);
653
      tempImage = newImage;
654
   }
655
 
656
   return tempImage;
657
}
658
 
659
 
660
/**
661
 * Copy GLubyte pixels from  to  with swizzling.
662
 * \param dst  destination pixels
663
 * \param dstComponents  number of color components in destination pixels
664
 * \param src  source pixels
665
 * \param srcComponents  number of color components in source pixels
666
 * \param map  the swizzle mapping.  map[X] says where to find the X component
667
 *             in the source image's pixels.  For example, if the source image
668
 *             is GL_BGRA and X = red, map[0] yields 2.
669
 * \param count  number of pixels to copy/swizzle.
670
 */
671
static void
672
swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
673
             GLuint srcComponents, const GLubyte *map, GLuint count)
674
{
675
#define SWZ_CPY(dst, src, count, dstComps, srcComps) \
676
   do {                                              \
677
      GLuint i;                                      \
678
      for (i = 0; i < count; i++) {                  \
679
         GLuint j;                                   \
680
         if (srcComps == 4) {                        \
681
            COPY_4UBV(tmp, src);                     \
682
         }                                           \
683
         else {                                      \
684
            for (j = 0; j < srcComps; j++) {         \
685
               tmp[j] = src[j];                      \
686
            }                                        \
687
         }                                           \
688
         src += srcComps;                            \
689
         for (j = 0; j < dstComps; j++) {            \
690
            dst[j] = tmp[map[j]];                    \
691
         }                                           \
692
         dst += dstComps;                            \
693
      }                                              \
694
   } while (0)
695
 
696
   GLubyte tmp[6];
697
 
698
   tmp[ZERO] = 0x0;
699
   tmp[ONE] = 0xff;
700
 
701
   ASSERT(srcComponents <= 4);
702
   ASSERT(dstComponents <= 4);
703
 
704
   switch (dstComponents) {
705
   case 4:
706
      switch (srcComponents) {
707
      case 4:
708
         SWZ_CPY(dst, src, count, 4, 4);
709
         break;
710
      case 3:
711
         SWZ_CPY(dst, src, count, 4, 3);
712
         break;
713
      case 2:
714
         SWZ_CPY(dst, src, count, 4, 2);
715
         break;
716
      case 1:
717
         SWZ_CPY(dst, src, count, 4, 1);
718
         break;
719
      default:
720
         ;
721
      }
722
      break;
723
   case 3:
724
      switch (srcComponents) {
725
      case 4:
726
         SWZ_CPY(dst, src, count, 3, 4);
727
         break;
728
      case 3:
729
         SWZ_CPY(dst, src, count, 3, 3);
730
         break;
731
      case 2:
732
         SWZ_CPY(dst, src, count, 3, 2);
733
         break;
734
      case 1:
735
         SWZ_CPY(dst, src, count, 3, 1);
736
         break;
737
      default:
738
         ;
739
      }
740
      break;
741
   case 2:
742
      switch (srcComponents) {
743
      case 4:
744
         SWZ_CPY(dst, src, count, 2, 4);
745
         break;
746
      case 3:
747
         SWZ_CPY(dst, src, count, 2, 3);
748
         break;
749
      case 2:
750
         SWZ_CPY(dst, src, count, 2, 2);
751
         break;
752
      case 1:
753
         SWZ_CPY(dst, src, count, 2, 1);
754
         break;
755
      default:
756
         ;
757
      }
758
      break;
759
   case 1:
760
      switch (srcComponents) {
761
      case 4:
762
         SWZ_CPY(dst, src, count, 1, 4);
763
         break;
764
      case 3:
765
         SWZ_CPY(dst, src, count, 1, 3);
766
         break;
767
      case 2:
768
         SWZ_CPY(dst, src, count, 1, 2);
769
         break;
770
      case 1:
771
         SWZ_CPY(dst, src, count, 1, 1);
772
         break;
773
      default:
774
         ;
775
      }
776
      break;
777
   default:
778
      ;
779
   }
780
#undef SWZ_CPY
781
}
782
 
783
 
784
 
785
static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
786
static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
787
 
788
 
789
/**
790
 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
791
 * mapping array depending on endianness.
792
 */
793
static const GLubyte *
794
type_mapping( GLenum srcType )
795
{
796
   switch (srcType) {
797
   case GL_BYTE:
798
   case GL_UNSIGNED_BYTE:
799
      return map_identity;
800
   case GL_UNSIGNED_INT_8_8_8_8:
801
      return _mesa_little_endian() ? map_3210 : map_identity;
802
   case GL_UNSIGNED_INT_8_8_8_8_REV:
803
      return _mesa_little_endian() ? map_identity : map_3210;
804
   default:
805
      return NULL;
806
   }
807
}
808
 
809
 
810
/**
811
 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
812
 * mapping array depending on pixelstore byte swapping state.
813
 */
814
static const GLubyte *
815
byteswap_mapping( GLboolean swapBytes,
816
		  GLenum srcType )
817
{
818
   if (!swapBytes)
819
      return map_identity;
820
 
821
   switch (srcType) {
822
   case GL_BYTE:
823
   case GL_UNSIGNED_BYTE:
824
      return map_identity;
825
   case GL_UNSIGNED_INT_8_8_8_8:
826
   case GL_UNSIGNED_INT_8_8_8_8_REV:
827
      return map_3210;
828
   default:
829
      return NULL;
830
   }
831
}
832
 
833
 
834
 
835
/**
836
 * Transfer a GLubyte texture image with component swizzling.
837
 */
838
static void
839
_mesa_swizzle_ubyte_image(struct gl_context *ctx,
840
			  GLuint dimensions,
841
			  GLenum srcFormat,
842
			  GLenum srcType,
843
 
844
			  GLenum baseInternalFormat,
845
 
846
			  const GLubyte *rgba2dst,
847
			  GLuint dstComponents,
848
 
849
			  GLvoid *dstAddr,
850
			  GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
851
			  GLint dstRowStride,
852
                          const GLuint *dstImageOffsets,
853
 
854
			  GLint srcWidth, GLint srcHeight, GLint srcDepth,
855
			  const GLvoid *srcAddr,
856
			  const struct gl_pixelstore_attrib *srcPacking )
857
{
858
   GLint srcComponents = _mesa_components_in_format(srcFormat);
859
   const GLubyte *srctype2ubyte, *swap;
860
   GLubyte map[4], src2base[6], base2rgba[6];
861
   GLint i;
862
   const GLint srcRowStride =
863
      _mesa_image_row_stride(srcPacking, srcWidth,
864
                             srcFormat, GL_UNSIGNED_BYTE);
865
   const GLint srcImageStride
866
      = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
867
                                 GL_UNSIGNED_BYTE);
868
   const GLubyte *srcImage
869
      = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
870
                                              srcWidth, srcHeight, srcFormat,
871
                                              GL_UNSIGNED_BYTE, 0, 0, 0);
872
 
873
   (void) ctx;
874
 
875
   /* Translate from src->baseInternal->GL_RGBA->dst.  This will
876
    * correctly deal with RGBA->RGB->RGBA conversions where the final
877
    * A value must be 0xff regardless of the incoming alpha values.
878
    */
879
   compute_component_mapping(srcFormat, baseInternalFormat, src2base);
880
   compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
881
   swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
882
   srctype2ubyte = type_mapping(srcType);
883
 
884
 
885
   for (i = 0; i < 4; i++)
886
      map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
887
 
888
/*    printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]);  */
889
 
890
   if (srcComponents == dstComponents &&
891
       srcRowStride == dstRowStride &&
892
       srcRowStride == srcWidth * srcComponents &&
893
       dimensions < 3) {
894
      /* 1 and 2D images only */
895
      GLubyte *dstImage = (GLubyte *) dstAddr
896
         + dstYoffset * dstRowStride
897
         + dstXoffset * dstComponents;
898
      swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
899
		   srcWidth * srcHeight);
900
   }
901
   else {
902
      GLint img, row;
903
      for (img = 0; img < srcDepth; img++) {
904
         const GLubyte *srcRow = srcImage;
905
         GLubyte *dstRow = (GLubyte *) dstAddr
906
            + dstImageOffsets[dstZoffset + img] * dstComponents
907
            + dstYoffset * dstRowStride
908
            + dstXoffset * dstComponents;
909
         for (row = 0; row < srcHeight; row++) {
910
	    swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
911
            dstRow += dstRowStride;
912
            srcRow += srcRowStride;
913
         }
914
         srcImage += srcImageStride;
915
      }
916
   }
917
}
918
 
919
 
920
/**
921
 * Teximage storage routine for when a simple memcpy will do.
922
 * No pixel transfer operations or special texel encodings allowed.
923
 * 1D, 2D and 3D images supported.
924
 */
925
static void
926
memcpy_texture(struct gl_context *ctx,
927
	       GLuint dimensions,
928
               gl_format dstFormat,
929
               GLvoid *dstAddr,
930
               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
931
               GLint dstRowStride,
932
               const GLuint *dstImageOffsets,
933
               GLint srcWidth, GLint srcHeight, GLint srcDepth,
934
               GLenum srcFormat, GLenum srcType,
935
               const GLvoid *srcAddr,
936
               const struct gl_pixelstore_attrib *srcPacking)
937
{
938
   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
939
                                                     srcFormat, srcType);
940
   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
941
                                      srcWidth, srcHeight, srcFormat, srcType);
942
   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
943
        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
944
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
945
   const GLint bytesPerRow = srcWidth * texelBytes;
946
 
947
#if 0
948
   /* XXX update/re-enable for dstImageOffsets array */
949
   const GLint bytesPerImage = srcHeight * bytesPerRow;
950
   const GLint bytesPerTexture = srcDepth * bytesPerImage;
951
   GLubyte *dstImage = (GLubyte *) dstAddr
952
                     + dstZoffset * dstImageStride
953
                     + dstYoffset * dstRowStride
954
                     + dstXoffset * texelBytes;
955
 
956
   if (dstRowStride == srcRowStride &&
957
       dstRowStride == bytesPerRow &&
958
       ((dstImageStride == srcImageStride &&
959
         dstImageStride == bytesPerImage) ||
960
        (srcDepth == 1))) {
961
      /* one big memcpy */
962
      ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
963
   }
964
   else
965
   {
966
      GLint img, row;
967
      for (img = 0; img < srcDepth; img++) {
968
         const GLubyte *srcRow = srcImage;
969
         GLubyte *dstRow = dstImage;
970
         for (row = 0; row < srcHeight; row++) {
971
            ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
972
            dstRow += dstRowStride;
973
            srcRow += srcRowStride;
974
         }
975
         srcImage += srcImageStride;
976
         dstImage += dstImageStride;
977
      }
978
   }
979
#endif
980
 
981
   GLint img, row;
982
   for (img = 0; img < srcDepth; img++) {
983
      const GLubyte *srcRow = srcImage;
984
      GLubyte *dstRow = (GLubyte *) dstAddr
985
         + dstImageOffsets[dstZoffset + img] * texelBytes
986
         + dstYoffset * dstRowStride
987
         + dstXoffset * texelBytes;
988
      for (row = 0; row < srcHeight; row++) {
989
         ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
990
         dstRow += dstRowStride;
991
         srcRow += srcRowStride;
992
      }
993
      srcImage += srcImageStride;
994
   }
995
}
996
 
997
 
998
 
999
/**
1000
 * Store a 32-bit integer depth component texture image.
1001
 */
1002
static GLboolean
1003
_mesa_texstore_z32(TEXSTORE_PARAMS)
1004
{
1005
   const GLuint depthScale = 0xffffffff;
1006
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1007
   (void) dims;
1008
   ASSERT(dstFormat == MESA_FORMAT_Z32);
1009
   ASSERT(texelBytes == sizeof(GLuint));
1010
 
1011
   if (ctx->Pixel.DepthScale == 1.0f &&
1012
       ctx->Pixel.DepthBias == 0.0f &&
1013
       !srcPacking->SwapBytes &&
1014
       baseInternalFormat == GL_DEPTH_COMPONENT &&
1015
       srcFormat == GL_DEPTH_COMPONENT &&
1016
       srcType == GL_UNSIGNED_INT) {
1017
      /* simple memcpy path */
1018
      memcpy_texture(ctx, dims,
1019
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1020
                     dstRowStride,
1021
                     dstImageOffsets,
1022
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1023
                     srcAddr, srcPacking);
1024
   }
1025
   else {
1026
      /* general path */
1027
      GLint img, row;
1028
      for (img = 0; img < srcDepth; img++) {
1029
         GLubyte *dstRow = (GLubyte *) dstAddr
1030
            + dstImageOffsets[dstZoffset + img] * texelBytes
1031
            + dstYoffset * dstRowStride
1032
            + dstXoffset * texelBytes;
1033
         for (row = 0; row < srcHeight; row++) {
1034
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1035
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1036
            _mesa_unpack_depth_span(ctx, srcWidth,
1037
                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
1038
                                    depthScale, srcType, src, srcPacking);
1039
            dstRow += dstRowStride;
1040
         }
1041
      }
1042
   }
1043
   return GL_TRUE;
1044
}
1045
 
1046
 
1047
/**
1048
 * Store a 24-bit integer depth component texture image.
1049
 */
1050
static GLboolean
1051
_mesa_texstore_x8_z24(TEXSTORE_PARAMS)
1052
{
1053
   const GLuint depthScale = 0xffffff;
1054
   const GLuint texelBytes = 4;
1055
 
1056
   (void) dims;
1057
   ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
1058
 
1059
   {
1060
      /* general path */
1061
      GLint img, row;
1062
      for (img = 0; img < srcDepth; img++) {
1063
         GLubyte *dstRow = (GLubyte *) dstAddr
1064
            + dstImageOffsets[dstZoffset + img] * texelBytes
1065
            + dstYoffset * dstRowStride
1066
            + dstXoffset * texelBytes;
1067
         for (row = 0; row < srcHeight; row++) {
1068
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1069
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1070
            _mesa_unpack_depth_span(ctx, srcWidth,
1071
                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
1072
                                    depthScale, srcType, src, srcPacking);
1073
            dstRow += dstRowStride;
1074
         }
1075
      }
1076
   }
1077
   return GL_TRUE;
1078
}
1079
 
1080
 
1081
/**
1082
 * Store a 24-bit integer depth component texture image.
1083
 */
1084
static GLboolean
1085
_mesa_texstore_z24_x8(TEXSTORE_PARAMS)
1086
{
1087
   const GLuint depthScale = 0xffffff;
1088
   const GLuint texelBytes = 4;
1089
 
1090
   (void) dims;
1091
   ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
1092
 
1093
   {
1094
      /* general path */
1095
      GLint img, row;
1096
      for (img = 0; img < srcDepth; img++) {
1097
         GLubyte *dstRow = (GLubyte *) dstAddr
1098
            + dstImageOffsets[dstZoffset + img] * texelBytes
1099
            + dstYoffset * dstRowStride
1100
            + dstXoffset * texelBytes;
1101
         for (row = 0; row < srcHeight; row++) {
1102
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1103
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1104
            GLuint *dst = (GLuint *) dstRow;
1105
            GLint i;
1106
            _mesa_unpack_depth_span(ctx, srcWidth,
1107
                                    GL_UNSIGNED_INT, dst,
1108
                                    depthScale, srcType, src, srcPacking);
1109
            for (i = 0; i < srcWidth; i++)
1110
               dst[i] <<= 8;
1111
            dstRow += dstRowStride;
1112
         }
1113
      }
1114
   }
1115
   return GL_TRUE;
1116
}
1117
 
1118
 
1119
/**
1120
 * Store a 16-bit integer depth component texture image.
1121
 */
1122
static GLboolean
1123
_mesa_texstore_z16(TEXSTORE_PARAMS)
1124
{
1125
   const GLuint depthScale = 0xffff;
1126
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1127
   (void) dims;
1128
   ASSERT(dstFormat == MESA_FORMAT_Z16);
1129
   ASSERT(texelBytes == sizeof(GLushort));
1130
 
1131
   if (ctx->Pixel.DepthScale == 1.0f &&
1132
       ctx->Pixel.DepthBias == 0.0f &&
1133
       !srcPacking->SwapBytes &&
1134
       baseInternalFormat == GL_DEPTH_COMPONENT &&
1135
       srcFormat == GL_DEPTH_COMPONENT &&
1136
       srcType == GL_UNSIGNED_SHORT) {
1137
      /* simple memcpy path */
1138
      memcpy_texture(ctx, dims,
1139
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1140
                     dstRowStride,
1141
                     dstImageOffsets,
1142
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1143
                     srcAddr, srcPacking);
1144
   }
1145
   else {
1146
      /* general path */
1147
      GLint img, row;
1148
      for (img = 0; img < srcDepth; img++) {
1149
         GLubyte *dstRow = (GLubyte *) dstAddr
1150
            + dstImageOffsets[dstZoffset + img] * texelBytes
1151
            + dstYoffset * dstRowStride
1152
            + dstXoffset * texelBytes;
1153
         for (row = 0; row < srcHeight; row++) {
1154
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1155
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1156
            GLushort *dst16 = (GLushort *) dstRow;
1157
            _mesa_unpack_depth_span(ctx, srcWidth,
1158
                                    GL_UNSIGNED_SHORT, dst16, depthScale,
1159
                                    srcType, src, srcPacking);
1160
            dstRow += dstRowStride;
1161
         }
1162
      }
1163
   }
1164
   return GL_TRUE;
1165
}
1166
 
1167
 
1168
/**
1169
 * Store an rgb565 or rgb565_rev texture image.
1170
 */
1171
static GLboolean
1172
_mesa_texstore_rgb565(TEXSTORE_PARAMS)
1173
{
1174
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1175
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1176
 
1177
   ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
1178
          dstFormat == MESA_FORMAT_RGB565_REV);
1179
   ASSERT(texelBytes == 2);
1180
 
1181
   if (!ctx->_ImageTransferState &&
1182
       !srcPacking->SwapBytes &&
1183
       dstFormat == MESA_FORMAT_RGB565 &&
1184
       baseInternalFormat == GL_RGB &&
1185
       srcFormat == GL_RGB &&
1186
       srcType == GL_UNSIGNED_SHORT_5_6_5) {
1187
      /* simple memcpy path */
1188
      memcpy_texture(ctx, dims,
1189
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1190
                     dstRowStride,
1191
                     dstImageOffsets,
1192
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1193
                     srcAddr, srcPacking);
1194
   }
1195
   else if (!ctx->_ImageTransferState &&
1196
            !srcPacking->SwapBytes &&
1197
            baseInternalFormat == GL_RGB &&
1198
            srcFormat == GL_RGB &&
1199
            srcType == GL_UNSIGNED_BYTE &&
1200
            dims == 2) {
1201
      /* do optimized tex store */
1202
      const GLint srcRowStride =
1203
         _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1204
      const GLubyte *src = (const GLubyte *)
1205
         _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
1206
                             srcFormat, srcType, 0, 0, 0);
1207
      GLubyte *dst = (GLubyte *) dstAddr
1208
                   + dstYoffset * dstRowStride
1209
                   + dstXoffset * texelBytes;
1210
      GLint row, col;
1211
      for (row = 0; row < srcHeight; row++) {
1212
         const GLubyte *srcUB = (const GLubyte *) src;
1213
         GLushort *dstUS = (GLushort *) dst;
1214
         /* check for byteswapped format */
1215
         if (dstFormat == MESA_FORMAT_RGB565) {
1216
            for (col = 0; col < srcWidth; col++) {
1217
               dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
1218
               srcUB += 3;
1219
            }
1220
         }
1221
         else {
1222
            for (col = 0; col < srcWidth; col++) {
1223
               dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1224
               srcUB += 3;
1225
            }
1226
         }
1227
         dst += dstRowStride;
1228
         src += srcRowStride;
1229
      }
1230
   }
1231
   else {
1232
      /* general path */
1233
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1234
                                                 baseInternalFormat,
1235
                                                 baseFormat,
1236
                                                 srcWidth, srcHeight, srcDepth,
1237
                                                 srcFormat, srcType, srcAddr,
1238
                                                 srcPacking);
1239
      const GLchan *src = tempImage;
1240
      GLint img, row, col;
1241
      if (!tempImage)
1242
         return GL_FALSE;
1243
      for (img = 0; img < srcDepth; img++) {
1244
         GLubyte *dstRow = (GLubyte *) dstAddr
1245
            + dstImageOffsets[dstZoffset + img] * texelBytes
1246
            + dstYoffset * dstRowStride
1247
            + dstXoffset * texelBytes;
1248
         for (row = 0; row < srcHeight; row++) {
1249
            GLushort *dstUS = (GLushort *) dstRow;
1250
            /* check for byteswapped format */
1251
            if (dstFormat == MESA_FORMAT_RGB565) {
1252
               for (col = 0; col < srcWidth; col++) {
1253
                  dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
1254
                                               CHAN_TO_UBYTE(src[GCOMP]),
1255
                                               CHAN_TO_UBYTE(src[BCOMP]) );
1256
                  src += 3;
1257
               }
1258
            }
1259
            else {
1260
               for (col = 0; col < srcWidth; col++) {
1261
                  dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
1262
                                                   CHAN_TO_UBYTE(src[GCOMP]),
1263
                                                   CHAN_TO_UBYTE(src[BCOMP]) );
1264
                  src += 3;
1265
               }
1266
            }
1267
            dstRow += dstRowStride;
1268
         }
1269
      }
1270
      free((void *) tempImage);
1271
   }
1272
   return GL_TRUE;
1273
}
1274
 
1275
 
1276
/**
1277
 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1278
 */
1279
static GLboolean
1280
_mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1281
{
1282
   const GLboolean littleEndian = _mesa_little_endian();
1283
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1284
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1285
 
1286
   ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
1287
          dstFormat == MESA_FORMAT_RGBA8888_REV);
1288
   ASSERT(texelBytes == 4);
1289
 
1290
   if (!ctx->_ImageTransferState &&
1291
       !srcPacking->SwapBytes &&
1292
       dstFormat == MESA_FORMAT_RGBA8888 &&
1293
       baseInternalFormat == GL_RGBA &&
1294
      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1295
       (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1296
       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1297
       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) {
1298
       /* simple memcpy path */
1299
      memcpy_texture(ctx, dims,
1300
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1301
                     dstRowStride,
1302
                     dstImageOffsets,
1303
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1304
                     srcAddr, srcPacking);
1305
   }
1306
   else if (!ctx->_ImageTransferState &&
1307
       !srcPacking->SwapBytes &&
1308
       dstFormat == MESA_FORMAT_RGBA8888_REV &&
1309
       baseInternalFormat == GL_RGBA &&
1310
      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1311
       (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1312
       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1313
       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) {
1314
      /* simple memcpy path */
1315
      memcpy_texture(ctx, dims,
1316
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1317
                     dstRowStride,
1318
                     dstImageOffsets,
1319
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1320
                     srcAddr, srcPacking);
1321
   }
1322
   else if (!ctx->_ImageTransferState &&
1323
	    (srcType == GL_UNSIGNED_BYTE ||
1324
	     srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1325
	     srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1326
	    can_swizzle(baseInternalFormat) &&
1327
	    can_swizzle(srcFormat)) {
1328
 
1329
      GLubyte dstmap[4];
1330
 
1331
      /* dstmap - how to swizzle from RGBA to dst format:
1332
       */
1333
      if ((littleEndian && dstFormat == MESA_FORMAT_RGBA8888) ||
1334
	  (!littleEndian && dstFormat == MESA_FORMAT_RGBA8888_REV)) {
1335
	 dstmap[3] = 0;
1336
	 dstmap[2] = 1;
1337
	 dstmap[1] = 2;
1338
	 dstmap[0] = 3;
1339
      }
1340
      else {
1341
	 dstmap[3] = 3;
1342
	 dstmap[2] = 2;
1343
	 dstmap[1] = 1;
1344
	 dstmap[0] = 0;
1345
      }
1346
 
1347
      _mesa_swizzle_ubyte_image(ctx, dims,
1348
				srcFormat,
1349
				srcType,
1350
				baseInternalFormat,
1351
				dstmap, 4,
1352
				dstAddr, dstXoffset, dstYoffset, dstZoffset,
1353
				dstRowStride, dstImageOffsets,
1354
				srcWidth, srcHeight, srcDepth, srcAddr,
1355
				srcPacking);
1356
   }
1357
   else {
1358
      /* general path */
1359
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1360
                                                 baseInternalFormat,
1361
                                                 baseFormat,
1362
                                                 srcWidth, srcHeight, srcDepth,
1363
                                                 srcFormat, srcType, srcAddr,
1364
                                                 srcPacking);
1365
      const GLchan *src = tempImage;
1366
      GLint img, row, col;
1367
      if (!tempImage)
1368
         return GL_FALSE;
1369
      for (img = 0; img < srcDepth; img++) {
1370
         GLubyte *dstRow = (GLubyte *) dstAddr
1371
            + dstImageOffsets[dstZoffset + img] * texelBytes
1372
            + dstYoffset * dstRowStride
1373
            + dstXoffset * texelBytes;
1374
         for (row = 0; row < srcHeight; row++) {
1375
            GLuint *dstUI = (GLuint *) dstRow;
1376
            if (dstFormat == MESA_FORMAT_RGBA8888) {
1377
               for (col = 0; col < srcWidth; col++) {
1378
                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
1379
                                                CHAN_TO_UBYTE(src[GCOMP]),
1380
                                                CHAN_TO_UBYTE(src[BCOMP]),
1381
                                                CHAN_TO_UBYTE(src[ACOMP]) );
1382
                  src += 4;
1383
               }
1384
            }
1385
            else {
1386
               for (col = 0; col < srcWidth; col++) {
1387
                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
1388
                                                    CHAN_TO_UBYTE(src[GCOMP]),
1389
                                                    CHAN_TO_UBYTE(src[BCOMP]),
1390
                                                    CHAN_TO_UBYTE(src[ACOMP]) );
1391
                  src += 4;
1392
               }
1393
            }
1394
            dstRow += dstRowStride;
1395
         }
1396
      }
1397
      free((void *) tempImage);
1398
   }
1399
   return GL_TRUE;
1400
}
1401
 
1402
 
1403
static GLboolean
1404
_mesa_texstore_argb8888(TEXSTORE_PARAMS)
1405
{
1406
   const GLboolean littleEndian = _mesa_little_endian();
1407
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1408
   const GLenum baseFormat = GL_RGBA;
1409
 
1410
   ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
1411
          dstFormat == MESA_FORMAT_ARGB8888_REV ||
1412
          dstFormat == MESA_FORMAT_XRGB8888 ||
1413
          dstFormat == MESA_FORMAT_XRGB8888_REV );
1414
   ASSERT(texelBytes == 4);
1415
 
1416
   if (!ctx->_ImageTransferState &&
1417
       !srcPacking->SwapBytes &&
1418
       (dstFormat == MESA_FORMAT_ARGB8888 ||
1419
        dstFormat == MESA_FORMAT_XRGB8888) &&
1420
       baseInternalFormat == GL_RGBA &&
1421
       srcFormat == GL_BGRA &&
1422
       ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1423
        srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1424
      /* simple memcpy path (little endian) */
1425
      memcpy_texture(ctx, dims,
1426
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1427
                     dstRowStride,
1428
                     dstImageOffsets,
1429
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1430
                     srcAddr, srcPacking);
1431
   }
1432
   else if (!ctx->_ImageTransferState &&
1433
       !srcPacking->SwapBytes &&
1434
       (dstFormat == MESA_FORMAT_ARGB8888_REV ||
1435
        dstFormat == MESA_FORMAT_XRGB8888_REV) &&
1436
       baseInternalFormat == GL_RGBA &&
1437
       srcFormat == GL_BGRA &&
1438
       ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1439
        srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1440
      /* simple memcpy path (big endian) */
1441
      memcpy_texture(ctx, dims,
1442
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1443
                     dstRowStride,
1444
                     dstImageOffsets,
1445
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1446
                     srcAddr, srcPacking);
1447
   }
1448
   else if (!ctx->_ImageTransferState &&
1449
            !srcPacking->SwapBytes &&
1450
	    (dstFormat == MESA_FORMAT_ARGB8888 ||
1451
             dstFormat == MESA_FORMAT_XRGB8888) &&
1452
            srcFormat == GL_RGB &&
1453
	    (baseInternalFormat == GL_RGBA ||
1454
	     baseInternalFormat == GL_RGB) &&
1455
            srcType == GL_UNSIGNED_BYTE) {
1456
      int img, row, col;
1457
      for (img = 0; img < srcDepth; img++) {
1458
         const GLint srcRowStride =
1459
            _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1460
         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1461
                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1462
         GLubyte *dstRow = (GLubyte *) dstAddr
1463
            + dstImageOffsets[dstZoffset + img] * texelBytes
1464
            + dstYoffset * dstRowStride
1465
            + dstXoffset * texelBytes;
1466
         for (row = 0; row < srcHeight; row++) {
1467
            GLuint *d4 = (GLuint *) dstRow;
1468
            for (col = 0; col < srcWidth; col++) {
1469
               d4[col] = PACK_COLOR_8888(0xff,
1470
                                         srcRow[col * 3 + RCOMP],
1471
                                         srcRow[col * 3 + GCOMP],
1472
                                         srcRow[col * 3 + BCOMP]);
1473
            }
1474
            dstRow += dstRowStride;
1475
            srcRow += srcRowStride;
1476
         }
1477
      }
1478
   }
1479
   else if (!ctx->_ImageTransferState &&
1480
            !srcPacking->SwapBytes &&
1481
	    dstFormat == MESA_FORMAT_ARGB8888 &&
1482
            srcFormat == GL_RGBA &&
1483
	    baseInternalFormat == GL_RGBA &&
1484
            srcType == GL_UNSIGNED_BYTE) {
1485
      /* same as above case, but src data has alpha too */
1486
      GLint img, row, col;
1487
      /* For some reason, streaming copies to write-combined regions
1488
       * are extremely sensitive to the characteristics of how the
1489
       * source data is retrieved.  By reordering the source reads to
1490
       * be in-order, the speed of this operation increases by half.
1491
       * Strangely the same isn't required for the RGB path, above.
1492
       */
1493
      for (img = 0; img < srcDepth; img++) {
1494
         const GLint srcRowStride =
1495
            _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1496
         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1497
                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1498
         GLubyte *dstRow = (GLubyte *) dstAddr
1499
            + dstImageOffsets[dstZoffset + img] * texelBytes
1500
            + dstYoffset * dstRowStride
1501
            + dstXoffset * texelBytes;
1502
         for (row = 0; row < srcHeight; row++) {
1503
            GLuint *d4 = (GLuint *) dstRow;
1504
            for (col = 0; col < srcWidth; col++) {
1505
               d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
1506
                                         srcRow[col * 4 + RCOMP],
1507
                                         srcRow[col * 4 + GCOMP],
1508
                                         srcRow[col * 4 + BCOMP]);
1509
            }
1510
            dstRow += dstRowStride;
1511
            srcRow += srcRowStride;
1512
         }
1513
      }
1514
   }
1515
   else if (!ctx->_ImageTransferState &&
1516
	    (srcType == GL_UNSIGNED_BYTE ||
1517
	     srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1518
	     srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1519
	    can_swizzle(baseInternalFormat) &&
1520
	    can_swizzle(srcFormat)) {
1521
 
1522
      GLubyte dstmap[4];
1523
 
1524
      /* dstmap - how to swizzle from RGBA to dst format:
1525
       */
1526
      if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1527
          (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
1528
	  (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1529
	  (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
1530
	 dstmap[3] = 3;		/* alpha */
1531
	 dstmap[2] = 0;		/* red */
1532
	 dstmap[1] = 1;		/* green */
1533
	 dstmap[0] = 2;		/* blue */
1534
      }
1535
      else {
1536
	 assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1537
		(!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1538
		(littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
1539
		(!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
1540
	 dstmap[3] = 2;
1541
	 dstmap[2] = 1;
1542
	 dstmap[1] = 0;
1543
	 dstmap[0] = 3;
1544
      }
1545
 
1546
      _mesa_swizzle_ubyte_image(ctx, dims,
1547
				srcFormat,
1548
				srcType,
1549
				baseInternalFormat,
1550
				dstmap, 4,
1551
				dstAddr, dstXoffset, dstYoffset, dstZoffset,
1552
				dstRowStride,
1553
                                dstImageOffsets,
1554
				srcWidth, srcHeight, srcDepth, srcAddr,
1555
				srcPacking);
1556
   }
1557
   else {
1558
      /* general path */
1559
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1560
                                                 baseInternalFormat,
1561
                                                 baseFormat,
1562
                                                 srcWidth, srcHeight, srcDepth,
1563
                                                 srcFormat, srcType, srcAddr,
1564
                                                 srcPacking);
1565
      const GLchan *src = tempImage;
1566
      GLint img, row, col;
1567
      if (!tempImage)
1568
         return GL_FALSE;
1569
      for (img = 0; img < srcDepth; img++) {
1570
         GLubyte *dstRow = (GLubyte *) dstAddr
1571
            + dstImageOffsets[dstZoffset + img] * texelBytes
1572
            + dstYoffset * dstRowStride
1573
            + dstXoffset * texelBytes;
1574
         for (row = 0; row < srcHeight; row++) {
1575
            GLuint *dstUI = (GLuint *) dstRow;
1576
            if (dstFormat == MESA_FORMAT_ARGB8888) {
1577
               for (col = 0; col < srcWidth; col++) {
1578
                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1579
                                                CHAN_TO_UBYTE(src[RCOMP]),
1580
                                                CHAN_TO_UBYTE(src[GCOMP]),
1581
                                                CHAN_TO_UBYTE(src[BCOMP]) );
1582
                  src += 4;
1583
               }
1584
            }
1585
            else if (dstFormat == MESA_FORMAT_XRGB8888) {
1586
               for (col = 0; col < srcWidth; col++) {
1587
                  dstUI[col] = PACK_COLOR_8888( 0xff,
1588
                                                CHAN_TO_UBYTE(src[RCOMP]),
1589
                                                CHAN_TO_UBYTE(src[GCOMP]),
1590
                                                CHAN_TO_UBYTE(src[BCOMP]) );
1591
                  src += 4;
1592
               }
1593
            }
1594
            else {
1595
               for (col = 0; col < srcWidth; col++) {
1596
                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1597
                                                    CHAN_TO_UBYTE(src[RCOMP]),
1598
                                                    CHAN_TO_UBYTE(src[GCOMP]),
1599
                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1600
                  src += 4;
1601
               }
1602
            }
1603
            dstRow += dstRowStride;
1604
         }
1605
      }
1606
      free((void *) tempImage);
1607
   }
1608
   return GL_TRUE;
1609
}
1610
 
1611
 
1612
static GLboolean
1613
_mesa_texstore_rgb888(TEXSTORE_PARAMS)
1614
{
1615
   const GLboolean littleEndian = _mesa_little_endian();
1616
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1617
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1618
 
1619
   ASSERT(dstFormat == MESA_FORMAT_RGB888);
1620
   ASSERT(texelBytes == 3);
1621
 
1622
   if (!ctx->_ImageTransferState &&
1623
       !srcPacking->SwapBytes &&
1624
       baseInternalFormat == GL_RGB &&
1625
       srcFormat == GL_BGR &&
1626
       srcType == GL_UNSIGNED_BYTE &&
1627
       littleEndian) {
1628
      /* simple memcpy path */
1629
      memcpy_texture(ctx, dims,
1630
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1631
                     dstRowStride,
1632
                     dstImageOffsets,
1633
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1634
                     srcAddr, srcPacking);
1635
   }
1636
   else if (!ctx->_ImageTransferState &&
1637
            !srcPacking->SwapBytes &&
1638
            srcFormat == GL_RGBA &&
1639
            srcType == GL_UNSIGNED_BYTE) {
1640
      /* extract RGB from RGBA */
1641
      GLint img, row, col;
1642
      for (img = 0; img < srcDepth; img++) {
1643
         const GLint srcRowStride =
1644
            _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1645
         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1646
                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1647
         GLubyte *dstRow = (GLubyte *) dstAddr
1648
            + dstImageOffsets[dstZoffset + img] * texelBytes
1649
            + dstYoffset * dstRowStride
1650
            + dstXoffset * texelBytes;
1651
         for (row = 0; row < srcHeight; row++) {
1652
            for (col = 0; col < srcWidth; col++) {
1653
               dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1654
               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1655
               dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1656
            }
1657
            dstRow += dstRowStride;
1658
            srcRow += srcRowStride;
1659
         }
1660
      }
1661
   }
1662
   else if (!ctx->_ImageTransferState &&
1663
	    srcType == GL_UNSIGNED_BYTE &&
1664
	    can_swizzle(baseInternalFormat) &&
1665
	    can_swizzle(srcFormat)) {
1666
 
1667
      GLubyte dstmap[4];
1668
 
1669
      /* dstmap - how to swizzle from RGBA to dst format:
1670
       */
1671
      dstmap[0] = 2;
1672
      dstmap[1] = 1;
1673
      dstmap[2] = 0;
1674
      dstmap[3] = ONE;		/* ? */
1675
 
1676
      _mesa_swizzle_ubyte_image(ctx, dims,
1677
				srcFormat,
1678
				srcType,
1679
				baseInternalFormat,
1680
				dstmap, 3,
1681
				dstAddr, dstXoffset, dstYoffset, dstZoffset,
1682
				dstRowStride, dstImageOffsets,
1683
				srcWidth, srcHeight, srcDepth, srcAddr,
1684
				srcPacking);
1685
   }
1686
   else {
1687
      /* general path */
1688
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1689
                                                 baseInternalFormat,
1690
                                                 baseFormat,
1691
                                                 srcWidth, srcHeight, srcDepth,
1692
                                                 srcFormat, srcType, srcAddr,
1693
                                                 srcPacking);
1694
      const GLchan *src = (const GLchan *) tempImage;
1695
      GLint img, row, col;
1696
      if (!tempImage)
1697
         return GL_FALSE;
1698
      for (img = 0; img < srcDepth; img++) {
1699
         GLubyte *dstRow = (GLubyte *) dstAddr
1700
            + dstImageOffsets[dstZoffset + img] * texelBytes
1701
            + dstYoffset * dstRowStride
1702
            + dstXoffset * texelBytes;
1703
         for (row = 0; row < srcHeight; row++) {
1704
#if 0
1705
            if (littleEndian) {
1706
               for (col = 0; col < srcWidth; col++) {
1707
                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1708
                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1709
                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1710
                  srcUB += 3;
1711
               }
1712
            }
1713
            else {
1714
               for (col = 0; col < srcWidth; col++) {
1715
                  dstRow[col * 3 + 0] = srcUB[BCOMP];
1716
                  dstRow[col * 3 + 1] = srcUB[GCOMP];
1717
                  dstRow[col * 3 + 2] = srcUB[RCOMP];
1718
                  srcUB += 3;
1719
               }
1720
            }
1721
#else
1722
            for (col = 0; col < srcWidth; col++) {
1723
               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1724
               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1725
               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1726
               src += 3;
1727
            }
1728
#endif
1729
            dstRow += dstRowStride;
1730
         }
1731
      }
1732
      free((void *) tempImage);
1733
   }
1734
   return GL_TRUE;
1735
}
1736
 
1737
 
1738
static GLboolean
1739
_mesa_texstore_bgr888(TEXSTORE_PARAMS)
1740
{
1741
   const GLboolean littleEndian = _mesa_little_endian();
1742
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1743
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1744
 
1745
   ASSERT(dstFormat == MESA_FORMAT_BGR888);
1746
   ASSERT(texelBytes == 3);
1747
 
1748
   if (!ctx->_ImageTransferState &&
1749
       !srcPacking->SwapBytes &&
1750
       baseInternalFormat == GL_RGB &&
1751
       srcFormat == GL_RGB &&
1752
       srcType == GL_UNSIGNED_BYTE &&
1753
       littleEndian) {
1754
      /* simple memcpy path */
1755
      memcpy_texture(ctx, dims,
1756
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1757
                     dstRowStride,
1758
                     dstImageOffsets,
1759
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1760
                     srcAddr, srcPacking);
1761
   }
1762
   else if (!ctx->_ImageTransferState &&
1763
            !srcPacking->SwapBytes &&
1764
            srcFormat == GL_RGBA &&
1765
            srcType == GL_UNSIGNED_BYTE) {
1766
      /* extract BGR from RGBA */
1767
      int img, row, col;
1768
      for (img = 0; img < srcDepth; img++) {
1769
         const GLint srcRowStride =
1770
            _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1771
         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1772
                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1773
         GLubyte *dstRow = (GLubyte *) dstAddr
1774
            + dstImageOffsets[dstZoffset + img] * texelBytes
1775
            + dstYoffset * dstRowStride
1776
            + dstXoffset * texelBytes;
1777
         for (row = 0; row < srcHeight; row++) {
1778
            for (col = 0; col < srcWidth; col++) {
1779
               dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1780
               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1781
               dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1782
            }
1783
            dstRow += dstRowStride;
1784
            srcRow += srcRowStride;
1785
         }
1786
      }
1787
   }
1788
   else if (!ctx->_ImageTransferState &&
1789
	    srcType == GL_UNSIGNED_BYTE &&
1790
	    can_swizzle(baseInternalFormat) &&
1791
	    can_swizzle(srcFormat)) {
1792
 
1793
      GLubyte dstmap[4];
1794
 
1795
      /* dstmap - how to swizzle from RGBA to dst format:
1796
       */
1797
      dstmap[0] = 0;
1798
      dstmap[1] = 1;
1799
      dstmap[2] = 2;
1800
      dstmap[3] = ONE;		/* ? */
1801
 
1802
      _mesa_swizzle_ubyte_image(ctx, dims,
1803
				srcFormat,
1804
				srcType,
1805
				baseInternalFormat,
1806
				dstmap, 3,
1807
				dstAddr, dstXoffset, dstYoffset, dstZoffset,
1808
				dstRowStride, dstImageOffsets,
1809
				srcWidth, srcHeight, srcDepth, srcAddr,
1810
				srcPacking);
1811
   }
1812
   else {
1813
      /* general path */
1814
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1815
                                                 baseInternalFormat,
1816
                                                 baseFormat,
1817
                                                 srcWidth, srcHeight, srcDepth,
1818
                                                 srcFormat, srcType, srcAddr,
1819
                                                 srcPacking);
1820
      const GLchan *src = (const GLchan *) tempImage;
1821
      GLint img, row, col;
1822
      if (!tempImage)
1823
         return GL_FALSE;
1824
      for (img = 0; img < srcDepth; img++) {
1825
         GLubyte *dstRow = (GLubyte *) dstAddr
1826
            + dstImageOffsets[dstZoffset + img] * texelBytes
1827
            + dstYoffset * dstRowStride
1828
            + dstXoffset * texelBytes;
1829
         for (row = 0; row < srcHeight; row++) {
1830
            for (col = 0; col < srcWidth; col++) {
1831
               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1832
               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1833
               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1834
               src += 3;
1835
            }
1836
            dstRow += dstRowStride;
1837
         }
1838
      }
1839
      free((void *) tempImage);
1840
   }
1841
   return GL_TRUE;
1842
}
1843
 
1844
 
1845
static GLboolean
1846
_mesa_texstore_argb4444(TEXSTORE_PARAMS)
1847
{
1848
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1849
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1850
 
1851
   ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
1852
          dstFormat == MESA_FORMAT_ARGB4444_REV);
1853
   ASSERT(texelBytes == 2);
1854
 
1855
   if (!ctx->_ImageTransferState &&
1856
       !srcPacking->SwapBytes &&
1857
       dstFormat == MESA_FORMAT_ARGB4444 &&
1858
       baseInternalFormat == GL_RGBA &&
1859
       srcFormat == GL_BGRA &&
1860
       srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1861
      /* simple memcpy path */
1862
      memcpy_texture(ctx, dims,
1863
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1864
                     dstRowStride,
1865
                     dstImageOffsets,
1866
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1867
                     srcAddr, srcPacking);
1868
   }
1869
   else {
1870
      /* general path */
1871
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1872
                                                 baseInternalFormat,
1873
                                                 baseFormat,
1874
                                                 srcWidth, srcHeight, srcDepth,
1875
                                                 srcFormat, srcType, srcAddr,
1876
                                                 srcPacking);
1877
      const GLchan *src = tempImage;
1878
      GLint img, row, col;
1879
      if (!tempImage)
1880
         return GL_FALSE;
1881
      for (img = 0; img < srcDepth; img++) {
1882
         GLubyte *dstRow = (GLubyte *) dstAddr
1883
            + dstImageOffsets[dstZoffset + img] * texelBytes
1884
            + dstYoffset * dstRowStride
1885
            + dstXoffset * texelBytes;
1886
         for (row = 0; row < srcHeight; row++) {
1887
            GLushort *dstUS = (GLushort *) dstRow;
1888
            if (dstFormat == MESA_FORMAT_ARGB4444) {
1889
               for (col = 0; col < srcWidth; col++) {
1890
                  dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1891
                                                CHAN_TO_UBYTE(src[RCOMP]),
1892
                                                CHAN_TO_UBYTE(src[GCOMP]),
1893
                                                CHAN_TO_UBYTE(src[BCOMP]) );
1894
                  src += 4;
1895
               }
1896
            }
1897
            else {
1898
               for (col = 0; col < srcWidth; col++) {
1899
                  dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1900
                                                    CHAN_TO_UBYTE(src[RCOMP]),
1901
                                                    CHAN_TO_UBYTE(src[GCOMP]),
1902
                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1903
                  src += 4;
1904
               }
1905
            }
1906
            dstRow += dstRowStride;
1907
         }
1908
      }
1909
      free((void *) tempImage);
1910
   }
1911
   return GL_TRUE;
1912
}
1913
 
1914
static GLboolean
1915
_mesa_texstore_rgba5551(TEXSTORE_PARAMS)
1916
{
1917
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1918
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1919
 
1920
   ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
1921
   ASSERT(texelBytes == 2);
1922
 
1923
   if (!ctx->_ImageTransferState &&
1924
       !srcPacking->SwapBytes &&
1925
       dstFormat == MESA_FORMAT_RGBA5551 &&
1926
       baseInternalFormat == GL_RGBA &&
1927
       srcFormat == GL_RGBA &&
1928
       srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
1929
      /* simple memcpy path */
1930
      memcpy_texture(ctx, dims,
1931
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1932
                     dstRowStride,
1933
                     dstImageOffsets,
1934
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1935
                     srcAddr, srcPacking);
1936
   }
1937
   else {
1938
      /* general path */
1939
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1940
                                                 baseInternalFormat,
1941
                                                 baseFormat,
1942
                                                 srcWidth, srcHeight, srcDepth,
1943
                                                 srcFormat, srcType, srcAddr,
1944
                                                 srcPacking);
1945
      const GLchan *src =tempImage;
1946
      GLint img, row, col;
1947
      if (!tempImage)
1948
         return GL_FALSE;
1949
      for (img = 0; img < srcDepth; img++) {
1950
         GLubyte *dstRow = (GLubyte *) dstAddr
1951
            + dstImageOffsets[dstZoffset + img] * texelBytes
1952
            + dstYoffset * dstRowStride
1953
            + dstXoffset * texelBytes;
1954
         for (row = 0; row < srcHeight; row++) {
1955
            GLushort *dstUS = (GLushort *) dstRow;
1956
	    for (col = 0; col < srcWidth; col++) {
1957
	       dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]),
1958
					     CHAN_TO_UBYTE(src[GCOMP]),
1959
					     CHAN_TO_UBYTE(src[BCOMP]),
1960
					     CHAN_TO_UBYTE(src[ACOMP]) );
1961
	      src += 4;
1962
	    }
1963
            dstRow += dstRowStride;
1964
         }
1965
      }
1966
      free((void *) tempImage);
1967
   }
1968
   return GL_TRUE;
1969
}
1970
 
1971
static GLboolean
1972
_mesa_texstore_argb1555(TEXSTORE_PARAMS)
1973
{
1974
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1975
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1976
 
1977
   ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
1978
          dstFormat == MESA_FORMAT_ARGB1555_REV);
1979
   ASSERT(texelBytes == 2);
1980
 
1981
   if (!ctx->_ImageTransferState &&
1982
       !srcPacking->SwapBytes &&
1983
       dstFormat == MESA_FORMAT_ARGB1555 &&
1984
       baseInternalFormat == GL_RGBA &&
1985
       srcFormat == GL_BGRA &&
1986
       srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1987
      /* simple memcpy path */
1988
      memcpy_texture(ctx, dims,
1989
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1990
                     dstRowStride,
1991
                     dstImageOffsets,
1992
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1993
                     srcAddr, srcPacking);
1994
   }
1995
   else {
1996
      /* general path */
1997
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1998
                                                 baseInternalFormat,
1999
                                                 baseFormat,
2000
                                                 srcWidth, srcHeight, srcDepth,
2001
                                                 srcFormat, srcType, srcAddr,
2002
                                                 srcPacking);
2003
      const GLchan *src =tempImage;
2004
      GLint img, row, col;
2005
      if (!tempImage)
2006
         return GL_FALSE;
2007
      for (img = 0; img < srcDepth; img++) {
2008
         GLubyte *dstRow = (GLubyte *) dstAddr
2009
            + dstImageOffsets[dstZoffset + img] * texelBytes
2010
            + dstYoffset * dstRowStride
2011
            + dstXoffset * texelBytes;
2012
         for (row = 0; row < srcHeight; row++) {
2013
            GLushort *dstUS = (GLushort *) dstRow;
2014
            if (dstFormat == MESA_FORMAT_ARGB1555) {
2015
               for (col = 0; col < srcWidth; col++) {
2016
                  dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
2017
                                                CHAN_TO_UBYTE(src[RCOMP]),
2018
                                                CHAN_TO_UBYTE(src[GCOMP]),
2019
                                                CHAN_TO_UBYTE(src[BCOMP]) );
2020
                  src += 4;
2021
               }
2022
            }
2023
            else {
2024
               for (col = 0; col < srcWidth; col++) {
2025
                  dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
2026
                                                    CHAN_TO_UBYTE(src[RCOMP]),
2027
                                                    CHAN_TO_UBYTE(src[GCOMP]),
2028
                                                    CHAN_TO_UBYTE(src[BCOMP]) );
2029
                  src += 4;
2030
               }
2031
            }
2032
            dstRow += dstRowStride;
2033
         }
2034
      }
2035
      free((void *) tempImage);
2036
   }
2037
   return GL_TRUE;
2038
}
2039
 
2040
 
2041
/**
2042
 * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
2043
 */
2044
static GLboolean
2045
_mesa_texstore_unorm88(TEXSTORE_PARAMS)
2046
{
2047
   const GLboolean littleEndian = _mesa_little_endian();
2048
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2049
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2050
 
2051
   ASSERT(dstFormat == MESA_FORMAT_AL88 ||
2052
          dstFormat == MESA_FORMAT_AL88_REV ||
2053
          dstFormat == MESA_FORMAT_RG88 ||
2054
          dstFormat == MESA_FORMAT_RG88_REV);
2055
   ASSERT(texelBytes == 2);
2056
 
2057
   if (!ctx->_ImageTransferState &&
2058
       !srcPacking->SwapBytes &&
2059
       (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_RG88) &&
2060
       baseInternalFormat == srcFormat &&
2061
       srcType == GL_UNSIGNED_BYTE &&
2062
       littleEndian) {
2063
      /* simple memcpy path */
2064
      memcpy_texture(ctx, dims,
2065
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2066
                     dstRowStride,
2067
                     dstImageOffsets,
2068
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2069
                     srcAddr, srcPacking);
2070
   }
2071
   else if (!ctx->_ImageTransferState &&
2072
	    littleEndian &&
2073
	    srcType == GL_UNSIGNED_BYTE &&
2074
	    can_swizzle(baseInternalFormat) &&
2075
	    can_swizzle(srcFormat)) {
2076
      GLubyte dstmap[4];
2077
 
2078
      /* dstmap - how to swizzle from RGBA to dst format:
2079
       */
2080
      if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
2081
	 if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
2082
	     (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
2083
	    dstmap[0] = 0;
2084
	    dstmap[1] = 3;
2085
	 }
2086
	 else {
2087
	    dstmap[0] = 3;
2088
	    dstmap[1] = 0;
2089
	 }
2090
      }
2091
      else {
2092
	 if ((littleEndian && dstFormat == MESA_FORMAT_RG88) ||
2093
	     (!littleEndian && dstFormat == MESA_FORMAT_RG88_REV)) {
2094
	    dstmap[0] = 0;
2095
	    dstmap[1] = 1;
2096
	 }
2097
	 else {
2098
	    dstmap[0] = 1;
2099
	    dstmap[1] = 0;
2100
	 }
2101
      }
2102
      dstmap[2] = ZERO;		/* ? */
2103
      dstmap[3] = ONE;		/* ? */
2104
 
2105
      _mesa_swizzle_ubyte_image(ctx, dims,
2106
				srcFormat,
2107
				srcType,
2108
				baseInternalFormat,
2109
				dstmap, 2,
2110
				dstAddr, dstXoffset, dstYoffset, dstZoffset,
2111
				dstRowStride, dstImageOffsets,
2112
				srcWidth, srcHeight, srcDepth, srcAddr,
2113
				srcPacking);
2114
   }
2115
   else {
2116
      /* general path */
2117
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2118
                                                 baseInternalFormat,
2119
                                                 baseFormat,
2120
                                                 srcWidth, srcHeight, srcDepth,
2121
                                                 srcFormat, srcType, srcAddr,
2122
                                                 srcPacking);
2123
      const GLchan *src = tempImage;
2124
      GLint img, row, col;
2125
      if (!tempImage)
2126
         return GL_FALSE;
2127
      for (img = 0; img < srcDepth; img++) {
2128
         GLubyte *dstRow = (GLubyte *) dstAddr
2129
            + dstImageOffsets[dstZoffset + img] * texelBytes
2130
            + dstYoffset * dstRowStride
2131
            + dstXoffset * texelBytes;
2132
         for (row = 0; row < srcHeight; row++) {
2133
            GLushort *dstUS = (GLushort *) dstRow;
2134
            if (dstFormat == MESA_FORMAT_AL88 ||
2135
		dstFormat == MESA_FORMAT_RG88) {
2136
               for (col = 0; col < srcWidth; col++) {
2137
                  /* src[0] is luminance, src[1] is alpha */
2138
                 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
2139
                                             CHAN_TO_UBYTE(src[0]) );
2140
                 src += 2;
2141
               }
2142
            }
2143
            else {
2144
               for (col = 0; col < srcWidth; col++) {
2145
                  /* src[0] is luminance, src[1] is alpha */
2146
                 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
2147
                                                 CHAN_TO_UBYTE(src[0]) );
2148
                 src += 2;
2149
               }
2150
            }
2151
            dstRow += dstRowStride;
2152
         }
2153
      }
2154
      free((void *) tempImage);
2155
   }
2156
   return GL_TRUE;
2157
}
2158
 
2159
 
2160
/**
2161
 * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
2162
 */
2163
static GLboolean
2164
_mesa_texstore_unorm1616(TEXSTORE_PARAMS)
2165
{
2166
   const GLboolean littleEndian = _mesa_little_endian();
2167
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2168
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2169
 
2170
   ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
2171
          dstFormat == MESA_FORMAT_AL1616_REV ||
2172
	  dstFormat == MESA_FORMAT_RG1616 ||
2173
          dstFormat == MESA_FORMAT_RG1616_REV);
2174
   ASSERT(texelBytes == 4);
2175
 
2176
   if (!ctx->_ImageTransferState &&
2177
       !srcPacking->SwapBytes &&
2178
       (dstFormat == MESA_FORMAT_AL1616 || dstFormat == MESA_FORMAT_RG1616) &&
2179
       baseInternalFormat == srcFormat &&
2180
       srcType == GL_UNSIGNED_SHORT &&
2181
       littleEndian) {
2182
      /* simple memcpy path */
2183
      memcpy_texture(ctx, dims,
2184
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2185
                     dstRowStride,
2186
                     dstImageOffsets,
2187
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2188
                     srcAddr, srcPacking);
2189
   }
2190
   else {
2191
      /* general path */
2192
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2193
                                                 baseInternalFormat,
2194
                                                 baseFormat,
2195
                                                 srcWidth, srcHeight, srcDepth,
2196
                                                 srcFormat, srcType, srcAddr,
2197
                                                 srcPacking,
2198
                                                 ctx->_ImageTransferState);
2199
      const GLfloat *src = tempImage;
2200
      GLint img, row, col;
2201
      if (!tempImage)
2202
         return GL_FALSE;
2203
      for (img = 0; img < srcDepth; img++) {
2204
         GLubyte *dstRow = (GLubyte *) dstAddr
2205
            + dstImageOffsets[dstZoffset + img] * texelBytes
2206
            + dstYoffset * dstRowStride
2207
            + dstXoffset * texelBytes;
2208
         for (row = 0; row < srcHeight; row++) {
2209
            GLuint *dstUI = (GLuint *) dstRow;
2210
            if (dstFormat == MESA_FORMAT_AL1616 ||
2211
		dstFormat == MESA_FORMAT_RG1616) {
2212
               for (col = 0; col < srcWidth; col++) {
2213
		  GLushort l, a;
2214
 
2215
		  UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
2216
		  UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
2217
		  dstUI[col] = PACK_COLOR_1616(a, l);
2218
		  src += 2;
2219
               }
2220
            }
2221
            else {
2222
               for (col = 0; col < srcWidth; col++) {
2223
		  GLushort l, a;
2224
 
2225
		  UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
2226
		  UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
2227
		  dstUI[col] = PACK_COLOR_1616_REV(a, l);
2228
		  src += 2;
2229
               }
2230
            }
2231
            dstRow += dstRowStride;
2232
         }
2233
      }
2234
      free((void *) tempImage);
2235
   }
2236
   return GL_TRUE;
2237
}
2238
 
2239
 
2240
static GLboolean
2241
_mesa_texstore_r16(TEXSTORE_PARAMS)
2242
{
2243
   const GLboolean littleEndian = _mesa_little_endian();
2244
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2245
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2246
 
2247
   ASSERT(dstFormat == MESA_FORMAT_R16);
2248
   ASSERT(texelBytes == 2);
2249
 
2250
   if (!ctx->_ImageTransferState &&
2251
       !srcPacking->SwapBytes &&
2252
       dstFormat == MESA_FORMAT_R16 &&
2253
       baseInternalFormat == GL_RED &&
2254
       srcFormat == GL_RED &&
2255
       srcType == GL_UNSIGNED_SHORT &&
2256
       littleEndian) {
2257
      /* simple memcpy path */
2258
      memcpy_texture(ctx, dims,
2259
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2260
                     dstRowStride,
2261
                     dstImageOffsets,
2262
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2263
                     srcAddr, srcPacking);
2264
   }
2265
   else {
2266
      /* general path */
2267
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2268
                                                 baseInternalFormat,
2269
                                                 baseFormat,
2270
                                                 srcWidth, srcHeight, srcDepth,
2271
                                                 srcFormat, srcType, srcAddr,
2272
                                                 srcPacking,
2273
                                                 ctx->_ImageTransferState);
2274
      const GLfloat *src = tempImage;
2275
      GLint img, row, col;
2276
      if (!tempImage)
2277
         return GL_FALSE;
2278
      for (img = 0; img < srcDepth; img++) {
2279
         GLubyte *dstRow = (GLubyte *) dstAddr
2280
            + dstImageOffsets[dstZoffset + img] * texelBytes
2281
            + dstYoffset * dstRowStride
2282
            + dstXoffset * texelBytes;
2283
         for (row = 0; row < srcHeight; row++) {
2284
            GLushort *dstUS = (GLushort *) dstRow;
2285
	    for (col = 0; col < srcWidth; col++) {
2286
	       GLushort r;
2287
 
2288
	       UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
2289
	       dstUS[col] = r;
2290
	       src += 1;
2291
	    }
2292
            dstRow += dstRowStride;
2293
         }
2294
      }
2295
      free((void *) tempImage);
2296
   }
2297
   return GL_TRUE;
2298
}
2299
 
2300
 
2301
static GLboolean
2302
_mesa_texstore_rgba_16(TEXSTORE_PARAMS)
2303
{
2304
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2305
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2306
 
2307
   ASSERT(dstFormat == MESA_FORMAT_RGBA_16);
2308
   ASSERT(texelBytes == 8);
2309
 
2310
   if (!ctx->_ImageTransferState &&
2311
       !srcPacking->SwapBytes &&
2312
       baseInternalFormat == GL_RGBA &&
2313
       srcFormat == GL_RGBA &&
2314
       srcType == GL_UNSIGNED_SHORT) {
2315
      /* simple memcpy path */
2316
      memcpy_texture(ctx, dims,
2317
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2318
                     dstRowStride,
2319
                     dstImageOffsets,
2320
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2321
                     srcAddr, srcPacking);
2322
   }
2323
   else {
2324
      /* general path */
2325
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2326
                                                 baseInternalFormat,
2327
                                                 baseFormat,
2328
                                                 srcWidth, srcHeight, srcDepth,
2329
                                                 srcFormat, srcType, srcAddr,
2330
                                                 srcPacking,
2331
                                                 ctx->_ImageTransferState);
2332
      const GLfloat *src = tempImage;
2333
      GLint img, row, col;
2334
      if (!tempImage)
2335
         return GL_FALSE;
2336
      for (img = 0; img < srcDepth; img++) {
2337
         GLubyte *dstRow = (GLubyte *) dstAddr
2338
            + dstImageOffsets[dstZoffset + img] * texelBytes
2339
            + dstYoffset * dstRowStride
2340
            + dstXoffset * texelBytes;
2341
         for (row = 0; row < srcHeight; row++) {
2342
            GLushort *dstUS = (GLushort *) dstRow;
2343
            for (col = 0; col < srcWidth; col++) {
2344
               GLushort r, g, b, a;
2345
 
2346
               UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
2347
               UNCLAMPED_FLOAT_TO_USHORT(g, src[1]);
2348
               UNCLAMPED_FLOAT_TO_USHORT(b, src[2]);
2349
               UNCLAMPED_FLOAT_TO_USHORT(a, src[3]);
2350
               dstUS[col*4+0] = r;
2351
               dstUS[col*4+1] = g;
2352
               dstUS[col*4+2] = b;
2353
               dstUS[col*4+3] = a;
2354
               src += 4;
2355
            }
2356
            dstRow += dstRowStride;
2357
         }
2358
      }
2359
      free((void *) tempImage);
2360
   }
2361
   return GL_TRUE;
2362
}
2363
 
2364
 
2365
static GLboolean
2366
_mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
2367
{
2368
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2369
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2370
 
2371
   ASSERT(dstFormat == MESA_FORMAT_SIGNED_R_16 ||
2372
          dstFormat == MESA_FORMAT_SIGNED_RG_16 ||
2373
          dstFormat == MESA_FORMAT_SIGNED_RGB_16 ||
2374
          dstFormat == MESA_FORMAT_SIGNED_RGBA_16);
2375
 
2376
   if (!ctx->_ImageTransferState &&
2377
       !srcPacking->SwapBytes &&
2378
       baseInternalFormat == GL_RGBA &&
2379
       dstFormat == MESA_FORMAT_SIGNED_RGBA_16 &&
2380
       srcFormat == GL_RGBA &&
2381
       srcType == GL_SHORT) {
2382
      /* simple memcpy path */
2383
      memcpy_texture(ctx, dims,
2384
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2385
                     dstRowStride,
2386
                     dstImageOffsets,
2387
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2388
                     srcAddr, srcPacking);
2389
   }
2390
   else {
2391
      /* general path */
2392
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2393
                                                 baseInternalFormat,
2394
                                                 baseFormat,
2395
                                                 srcWidth, srcHeight, srcDepth,
2396
                                                 srcFormat, srcType, srcAddr,
2397
                                                 srcPacking,
2398
                                                 ctx->_ImageTransferState);
2399
      const GLfloat *src = tempImage;
2400
      const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2;
2401
      GLint img, row, col;
2402
 
2403
      if (!tempImage)
2404
         return GL_FALSE;
2405
 
2406
      /* Note: tempImage is always float[4] / RGBA.  We convert to 1, 2,
2407
       * 3 or 4 components/pixel here.
2408
       */
2409
      for (img = 0; img < srcDepth; img++) {
2410
         GLubyte *dstRow = (GLubyte *) dstAddr
2411
            + dstImageOffsets[dstZoffset + img] * texelBytes
2412
            + dstYoffset * dstRowStride
2413
            + dstXoffset * texelBytes;
2414
         for (row = 0; row < srcHeight; row++) {
2415
            GLshort *dstRowS = (GLshort *) dstRow;
2416
            for (col = 0; col < srcWidth; col++) {
2417
               GLuint c;
2418
               for (c = 0; c < comps; c++) {
2419
                  GLshort p;
2420
                  UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]);
2421
                  dstRowS[col * comps + c] = p;
2422
               }
2423
            }
2424
            dstRow += dstRowStride;
2425
            src += 4 * srcWidth;
2426
         }
2427
      }
2428
      free((void *) tempImage);
2429
   }
2430
   return GL_TRUE;
2431
}
2432
 
2433
 
2434
static GLboolean
2435
_mesa_texstore_rgb332(TEXSTORE_PARAMS)
2436
{
2437
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2438
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2439
 
2440
   ASSERT(dstFormat == MESA_FORMAT_RGB332);
2441
   ASSERT(texelBytes == 1);
2442
 
2443
   if (!ctx->_ImageTransferState &&
2444
       !srcPacking->SwapBytes &&
2445
       baseInternalFormat == GL_RGB &&
2446
       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
2447
      /* simple memcpy path */
2448
      memcpy_texture(ctx, dims,
2449
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2450
                     dstRowStride,
2451
                     dstImageOffsets,
2452
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2453
                     srcAddr, srcPacking);
2454
   }
2455
   else {
2456
      /* general path */
2457
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2458
                                                 baseInternalFormat,
2459
                                                 baseFormat,
2460
                                                 srcWidth, srcHeight, srcDepth,
2461
                                                 srcFormat, srcType, srcAddr,
2462
                                                 srcPacking);
2463
      const GLchan *src = tempImage;
2464
      GLint img, row, col;
2465
      if (!tempImage)
2466
         return GL_FALSE;
2467
      for (img = 0; img < srcDepth; img++) {
2468
         GLubyte *dstRow = (GLubyte *) dstAddr
2469
            + dstImageOffsets[dstZoffset + img] * texelBytes
2470
            + dstYoffset * dstRowStride
2471
            + dstXoffset * texelBytes;
2472
         for (row = 0; row < srcHeight; row++) {
2473
            for (col = 0; col < srcWidth; col++) {
2474
               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
2475
                                             CHAN_TO_UBYTE(src[GCOMP]),
2476
                                             CHAN_TO_UBYTE(src[BCOMP]) );
2477
               src += 3;
2478
            }
2479
            dstRow += dstRowStride;
2480
         }
2481
      }
2482
      free((void *) tempImage);
2483
   }
2484
   return GL_TRUE;
2485
}
2486
 
2487
 
2488
/**
2489
 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2490
 */
2491
static GLboolean
2492
_mesa_texstore_a8(TEXSTORE_PARAMS)
2493
{
2494
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2495
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2496
 
2497
   ASSERT(dstFormat == MESA_FORMAT_A8 ||
2498
          dstFormat == MESA_FORMAT_L8 ||
2499
          dstFormat == MESA_FORMAT_I8 ||
2500
          dstFormat == MESA_FORMAT_R8);
2501
   ASSERT(texelBytes == 1);
2502
 
2503
   if (!ctx->_ImageTransferState &&
2504
       !srcPacking->SwapBytes &&
2505
       baseInternalFormat == srcFormat &&
2506
       srcType == GL_UNSIGNED_BYTE) {
2507
      /* simple memcpy path */
2508
      memcpy_texture(ctx, dims,
2509
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2510
                     dstRowStride,
2511
                     dstImageOffsets,
2512
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2513
                     srcAddr, srcPacking);
2514
   }
2515
   else if (!ctx->_ImageTransferState &&
2516
	    srcType == GL_UNSIGNED_BYTE &&
2517
	    can_swizzle(baseInternalFormat) &&
2518
	    can_swizzle(srcFormat)) {
2519
      GLubyte dstmap[4];
2520
 
2521
      /* dstmap - how to swizzle from RGBA to dst format:
2522
       */
2523
      if (dstFormat == MESA_FORMAT_A8) {
2524
	 dstmap[0] = 3;
2525
      }
2526
      else {
2527
	 dstmap[0] = 0;
2528
      }
2529
      dstmap[1] = ZERO;		/* ? */
2530
      dstmap[2] = ZERO;		/* ? */
2531
      dstmap[3] = ONE;		/* ? */
2532
 
2533
      _mesa_swizzle_ubyte_image(ctx, dims,
2534
				srcFormat,
2535
				srcType,
2536
				baseInternalFormat,
2537
				dstmap, 1,
2538
				dstAddr, dstXoffset, dstYoffset, dstZoffset,
2539
				dstRowStride, dstImageOffsets,
2540
				srcWidth, srcHeight, srcDepth, srcAddr,
2541
				srcPacking);
2542
   }
2543
   else {
2544
      /* general path */
2545
      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2546
                                                 baseInternalFormat,
2547
                                                 baseFormat,
2548
                                                 srcWidth, srcHeight, srcDepth,
2549
                                                 srcFormat, srcType, srcAddr,
2550
                                                 srcPacking);
2551
      const GLchan *src = tempImage;
2552
      GLint img, row, col;
2553
      if (!tempImage)
2554
         return GL_FALSE;
2555
      for (img = 0; img < srcDepth; img++) {
2556
         GLubyte *dstRow = (GLubyte *) dstAddr
2557
            + dstImageOffsets[dstZoffset + img] * texelBytes
2558
            + dstYoffset * dstRowStride
2559
            + dstXoffset * texelBytes;
2560
         for (row = 0; row < srcHeight; row++) {
2561
            for (col = 0; col < srcWidth; col++) {
2562
               dstRow[col] = CHAN_TO_UBYTE(src[col]);
2563
            }
2564
            dstRow += dstRowStride;
2565
            src += srcWidth;
2566
         }
2567
      }
2568
      free((void *) tempImage);
2569
   }
2570
   return GL_TRUE;
2571
}
2572
 
2573
 
2574
 
2575
static GLboolean
2576
_mesa_texstore_ci8(TEXSTORE_PARAMS)
2577
{
2578
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2579
 
2580
   (void) dims; (void) baseInternalFormat;
2581
   ASSERT(dstFormat == MESA_FORMAT_CI8);
2582
   ASSERT(texelBytes == 1);
2583
   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
2584
 
2585
   if (!ctx->_ImageTransferState &&
2586
       !srcPacking->SwapBytes &&
2587
       srcFormat == GL_COLOR_INDEX &&
2588
       srcType == GL_UNSIGNED_BYTE) {
2589
      /* simple memcpy path */
2590
      memcpy_texture(ctx, dims,
2591
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2592
                     dstRowStride,
2593
                     dstImageOffsets,
2594
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2595
                     srcAddr, srcPacking);
2596
   }
2597
   else {
2598
      /* general path */
2599
      GLint img, row;
2600
      for (img = 0; img < srcDepth; img++) {
2601
         GLubyte *dstRow = (GLubyte *) dstAddr
2602
            + dstImageOffsets[dstZoffset + img] * texelBytes
2603
            + dstYoffset * dstRowStride
2604
            + dstXoffset * texelBytes;
2605
         for (row = 0; row < srcHeight; row++) {
2606
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
2607
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
2608
            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
2609
                                    srcType, src, srcPacking,
2610
                                    ctx->_ImageTransferState);
2611
            dstRow += dstRowStride;
2612
         }
2613
      }
2614
   }
2615
   return GL_TRUE;
2616
}
2617
 
2618
 
2619
/**
2620
 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2621
 */
2622
static GLboolean
2623
_mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2624
{
2625
   const GLboolean littleEndian = _mesa_little_endian();
2626
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2627
 
2628
   (void) ctx; (void) dims; (void) baseInternalFormat;
2629
 
2630
   ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
2631
          (dstFormat == MESA_FORMAT_YCBCR_REV));
2632
   ASSERT(texelBytes == 2);
2633
   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2634
   ASSERT(srcFormat == GL_YCBCR_MESA);
2635
   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2636
          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2637
   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2638
 
2639
   /* always just memcpy since no pixel transfer ops apply */
2640
   memcpy_texture(ctx, dims,
2641
                  dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2642
                  dstRowStride,
2643
                  dstImageOffsets,
2644
                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2645
                  srcAddr, srcPacking);
2646
 
2647
   /* Check if we need byte swapping */
2648
   /* XXX the logic here _might_ be wrong */
2649
   if (srcPacking->SwapBytes ^
2650
       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2651
       (dstFormat == MESA_FORMAT_YCBCR_REV) ^
2652
       !littleEndian) {
2653
      GLint img, row;
2654
      for (img = 0; img < srcDepth; img++) {
2655
         GLubyte *dstRow = (GLubyte *) dstAddr
2656
            + dstImageOffsets[dstZoffset + img] * texelBytes
2657
            + dstYoffset * dstRowStride
2658
            + dstXoffset * texelBytes;
2659
         for (row = 0; row < srcHeight; row++) {
2660
            _mesa_swap2((GLushort *) dstRow, srcWidth);
2661
            dstRow += dstRowStride;
2662
         }
2663
      }
2664
   }
2665
   return GL_TRUE;
2666
}
2667
 
2668
static GLboolean
2669
_mesa_texstore_dudv8(TEXSTORE_PARAMS)
2670
{
2671
   const GLboolean littleEndian = _mesa_little_endian();
2672
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2673
 
2674
   ASSERT(dstFormat == MESA_FORMAT_DUDV8);
2675
   ASSERT(texelBytes == 2);
2676
   ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
2677
   ASSERT((srcFormat == GL_DU8DV8_ATI) ||
2678
	  (srcFormat == GL_DUDV_ATI));
2679
   ASSERT(baseInternalFormat == GL_DUDV_ATI);
2680
 
2681
   if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
2682
       littleEndian) {
2683
      /* simple memcpy path */
2684
      memcpy_texture(ctx, dims,
2685
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2686
                     dstRowStride,
2687
                     dstImageOffsets,
2688
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2689
                     srcAddr, srcPacking);
2690
   }
2691
   else if (srcType == GL_BYTE) {
2692
      GLubyte dstmap[4];
2693
 
2694
      /* dstmap - how to swizzle from RGBA to dst format:
2695
       */
2696
      if (littleEndian) {
2697
	 dstmap[0] = 0;
2698
	 dstmap[1] = 3;
2699
      }
2700
      else {
2701
	 dstmap[0] = 3;
2702
	 dstmap[1] = 0;
2703
      }
2704
      dstmap[2] = ZERO;		/* ? */
2705
      dstmap[3] = ONE;		/* ? */
2706
 
2707
      _mesa_swizzle_ubyte_image(ctx, dims,
2708
				GL_LUMINANCE_ALPHA, /* hack */
2709
				GL_UNSIGNED_BYTE, /* hack */
2710
				GL_LUMINANCE_ALPHA, /* hack */
2711
				dstmap, 2,
2712
				dstAddr, dstXoffset, dstYoffset, dstZoffset,
2713
				dstRowStride, dstImageOffsets,
2714
				srcWidth, srcHeight, srcDepth, srcAddr,
2715
				srcPacking);
2716
   }
2717
   else {
2718
      /* general path - note this is defined for 2d textures only */
2719
      const GLint components = _mesa_components_in_format(baseInternalFormat);
2720
      const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
2721
                                                     srcFormat, srcType);
2722
      GLbyte *tempImage, *dst, *src;
2723
      GLint row;
2724
 
2725
      tempImage = (GLbyte *) malloc(srcWidth * srcHeight * srcDepth
2726
                                          * components * sizeof(GLbyte));
2727
      if (!tempImage)
2728
         return GL_FALSE;
2729
 
2730
      src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2731
                                           srcWidth, srcHeight,
2732
                                           srcFormat, srcType,
2733
                                           0, 0, 0);
2734
 
2735
      dst = tempImage;
2736
      for (row = 0; row < srcHeight; row++) {
2737
         _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
2738
                                     dst, srcFormat, srcType, src,
2739
                                     srcPacking, 0);
2740
         dst += srcWidth * components;
2741
         src += srcStride;
2742
      }
2743
 
2744
      src = tempImage;
2745
      dst = (GLbyte *) dstAddr
2746
            + dstYoffset * dstRowStride
2747
            + dstXoffset * texelBytes;
2748
      for (row = 0; row < srcHeight; row++) {
2749
         memcpy(dst, src, srcWidth * texelBytes);
2750
         dst += dstRowStride;
2751
         src += srcWidth * texelBytes;
2752
      }
2753
      free((void *) tempImage);
2754
   }
2755
   return GL_TRUE;
2756
}
2757
 
2758
 
2759
/**
2760
 * Store a texture in MESA_FORMAT_SIGNED_R8 format.
2761
 */
2762
static GLboolean
2763
_mesa_texstore_signed_r8(TEXSTORE_PARAMS)
2764
{
2765
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2766
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2767
 
2768
   ASSERT(dstFormat == MESA_FORMAT_SIGNED_R8);
2769
   ASSERT(texelBytes == 1);
2770
 
2771
   /* XXX look at adding optimized paths */
2772
   {
2773
      /* general path */
2774
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2775
                                                 baseInternalFormat,
2776
                                                 baseFormat,
2777
                                                 srcWidth, srcHeight, srcDepth,
2778
                                                 srcFormat, srcType, srcAddr,
2779
                                                 srcPacking,
2780
                                                 ctx->_ImageTransferState);
2781
      const GLfloat *srcRow = tempImage;
2782
      GLint img, row, col;
2783
      if (!tempImage)
2784
         return GL_FALSE;
2785
      for (img = 0; img < srcDepth; img++) {
2786
         GLubyte *dstRow = (GLubyte *) dstAddr
2787
            + dstImageOffsets[dstZoffset + img] * texelBytes
2788
            + dstYoffset * dstRowStride
2789
            + dstXoffset * texelBytes;
2790
         for (row = 0; row < srcHeight; row++) {
2791
            GLubyte *dstB = (GLubyte *) dstRow;
2792
            for (col = 0; col < srcWidth; col++) {
2793
               dstB[col] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2794
            }
2795
            dstRow += dstRowStride;
2796
         }
2797
      }
2798
      free((void *) tempImage);
2799
   }
2800
   return GL_TRUE;
2801
}
2802
 
2803
 
2804
/**
2805
 * Store a texture in MESA_FORMAT_SIGNED_RG88 format.
2806
 */
2807
static GLboolean
2808
_mesa_texstore_signed_rg88(TEXSTORE_PARAMS)
2809
{
2810
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2811
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2812
 
2813
   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG88);
2814
   ASSERT(texelBytes == 1);
2815
 
2816
   /* XXX look at adding optimized paths */
2817
   {
2818
      /* general path */
2819
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2820
                                                 baseInternalFormat,
2821
                                                 baseFormat,
2822
                                                 srcWidth, srcHeight, srcDepth,
2823
                                                 srcFormat, srcType, srcAddr,
2824
                                                 srcPacking,
2825
                                                 ctx->_ImageTransferState);
2826
      const GLfloat *srcRow = tempImage;
2827
      GLint img, row, col;
2828
      if (!tempImage)
2829
         return GL_FALSE;
2830
      for (img = 0; img < srcDepth; img++) {
2831
         GLubyte *dstRow = (GLubyte *) dstAddr
2832
            + dstImageOffsets[dstZoffset + img] * texelBytes
2833
            + dstYoffset * dstRowStride
2834
            + dstXoffset * texelBytes;
2835
         for (row = 0; row < srcHeight; row++) {
2836
            GLushort *dstUS = (GLushort *) dstRow;
2837
            for (col = 0; col < srcWidth; col++) {
2838
               dstUS[col] = PACK_COLOR_88(FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2839
                                          FLOAT_TO_BYTE_TEX(srcRow[GCOMP]));
2840
            }
2841
            dstRow += dstRowStride;
2842
         }
2843
      }
2844
      free((void *) tempImage);
2845
   }
2846
   return GL_TRUE;
2847
}
2848
 
2849
 
2850
/**
2851
 * Store a texture in MESA_FORMAT_SIGNED_RGBX8888.
2852
 */
2853
static GLboolean
2854
_mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
2855
{
2856
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2857
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2858
 
2859
   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888);
2860
   ASSERT(texelBytes == 4);
2861
 
2862
   {
2863
      /* general path */
2864
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2865
                                                 baseInternalFormat,
2866
                                                 baseFormat,
2867
                                                 srcWidth, srcHeight, srcDepth,
2868
                                                 srcFormat, srcType, srcAddr,
2869
                                                 srcPacking,
2870
                                                 ctx->_ImageTransferState);
2871
      const GLfloat *srcRow = tempImage;
2872
      GLint img, row, col;
2873
      if (!tempImage)
2874
         return GL_FALSE;
2875
      for (img = 0; img < srcDepth; img++) {
2876
         GLubyte *dstRow = (GLubyte *) dstAddr
2877
            + dstImageOffsets[dstZoffset + img] * texelBytes
2878
            + dstYoffset * dstRowStride
2879
            + dstXoffset * texelBytes;
2880
         for (row = 0; row < srcHeight; row++) {
2881
            GLuint *dstUI = (GLuint *) dstRow;
2882
            for (col = 0; col < srcWidth; col++) {
2883
               dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2884
                                             FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
2885
                                             FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
2886
                                             0xff );
2887
               srcRow += 4;
2888
            }
2889
            dstRow += dstRowStride;
2890
         }
2891
      }
2892
      free((void *) tempImage);
2893
   }
2894
   return GL_TRUE;
2895
}
2896
 
2897
 
2898
 
2899
/**
2900
 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or
2901
 * MESA_FORMAT_SIGNED_RGBA8888_REV
2902
 */
2903
static GLboolean
2904
_mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
2905
{
2906
   const GLboolean littleEndian = _mesa_little_endian();
2907
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2908
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2909
 
2910
   ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
2911
          dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
2912
   ASSERT(texelBytes == 4);
2913
 
2914
   if (!ctx->_ImageTransferState &&
2915
       !srcPacking->SwapBytes &&
2916
       dstFormat == MESA_FORMAT_SIGNED_RGBA8888 &&
2917
       baseInternalFormat == GL_RGBA &&
2918
      ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
2919
       (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
2920
       /* simple memcpy path */
2921
      memcpy_texture(ctx, dims,
2922
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2923
                     dstRowStride,
2924
                     dstImageOffsets,
2925
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2926
                     srcAddr, srcPacking);
2927
   }
2928
   else if (!ctx->_ImageTransferState &&
2929
       !srcPacking->SwapBytes &&
2930
       dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV &&
2931
       baseInternalFormat == GL_RGBA &&
2932
      ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) ||
2933
       (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
2934
      /* simple memcpy path */
2935
      memcpy_texture(ctx, dims,
2936
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2937
                     dstRowStride,
2938
                     dstImageOffsets,
2939
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2940
                     srcAddr, srcPacking);
2941
   }
2942
   else if (!ctx->_ImageTransferState &&
2943
	    (srcType == GL_BYTE) &&
2944
	    can_swizzle(baseInternalFormat) &&
2945
	    can_swizzle(srcFormat)) {
2946
 
2947
      GLubyte dstmap[4];
2948
 
2949
      /* dstmap - how to swizzle from RGBA to dst format:
2950
       */
2951
      if ((littleEndian && dstFormat == MESA_FORMAT_SIGNED_RGBA8888) ||
2952
	  (!littleEndian && dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV)) {
2953
	 dstmap[3] = 0;
2954
	 dstmap[2] = 1;
2955
	 dstmap[1] = 2;
2956
	 dstmap[0] = 3;
2957
      }
2958
      else {
2959
	 dstmap[3] = 3;
2960
	 dstmap[2] = 2;
2961
	 dstmap[1] = 1;
2962
	 dstmap[0] = 0;
2963
      }
2964
 
2965
      _mesa_swizzle_ubyte_image(ctx, dims,
2966
				srcFormat,
2967
				srcType,
2968
				baseInternalFormat,
2969
				dstmap, 4,
2970
				dstAddr, dstXoffset, dstYoffset, dstZoffset,
2971
				dstRowStride, dstImageOffsets,
2972
				srcWidth, srcHeight, srcDepth, srcAddr,
2973
				srcPacking);
2974
   }
2975
   else {
2976
      /* general path */
2977
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2978
                                                 baseInternalFormat,
2979
                                                 baseFormat,
2980
                                                 srcWidth, srcHeight, srcDepth,
2981
                                                 srcFormat, srcType, srcAddr,
2982
                                                 srcPacking,
2983
                                                 ctx->_ImageTransferState);
2984
      const GLfloat *srcRow = tempImage;
2985
      GLint img, row, col;
2986
      if (!tempImage)
2987
         return GL_FALSE;
2988
      for (img = 0; img < srcDepth; img++) {
2989
         GLubyte *dstRow = (GLubyte *) dstAddr
2990
            + dstImageOffsets[dstZoffset + img] * texelBytes
2991
            + dstYoffset * dstRowStride
2992
            + dstXoffset * texelBytes;
2993
         for (row = 0; row < srcHeight; row++) {
2994
            GLuint *dstUI = (GLuint *) dstRow;
2995
            if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) {
2996
               for (col = 0; col < srcWidth; col++) {
2997
                  dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2998
                                                FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
2999
                                                FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
3000
                                                FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
3001
                  srcRow += 4;
3002
               }
3003
            }
3004
            else {
3005
               for (col = 0; col < srcWidth; col++) {
3006
                  dstUI[col] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
3007
                                                    FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
3008
                                                    FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
3009
                                                    FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
3010
                  srcRow += 4;
3011
               }
3012
            }
3013
            dstRow += dstRowStride;
3014
         }
3015
      }
3016
      free((void *) tempImage);
3017
   }
3018
   return GL_TRUE;
3019
}
3020
 
3021
 
3022
/**
3023
 * Store a combined depth/stencil texture image.
3024
 */
3025
static GLboolean
3026
_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
3027
{
3028
   const GLuint depthScale = 0xffffff;
3029
   const GLint srcRowStride
3030
      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
3031
      / sizeof(GLuint);
3032
   GLint img, row;
3033
 
3034
   ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
3035
   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
3036
   ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
3037
 
3038
   if (srcFormat != GL_DEPTH_COMPONENT && ctx->Pixel.DepthScale == 1.0f &&
3039
       ctx->Pixel.DepthBias == 0.0f &&
3040
       !srcPacking->SwapBytes) {
3041
      /* simple path */
3042
      memcpy_texture(ctx, dims,
3043
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3044
                     dstRowStride,
3045
                     dstImageOffsets,
3046
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3047
                     srcAddr, srcPacking);
3048
   }
3049
   else if (srcFormat == GL_DEPTH_COMPONENT) {
3050
      /* In case we only upload depth we need to preserve the stencil */
3051
      for (img = 0; img < srcDepth; img++) {
3052
	 GLuint *dstRow = (GLuint *) dstAddr
3053
            + dstImageOffsets[dstZoffset + img]
3054
            + dstYoffset * dstRowStride / sizeof(GLuint)
3055
            + dstXoffset;
3056
         const GLuint *src
3057
            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
3058
                  srcWidth, srcHeight,
3059
                  srcFormat, srcType,
3060
                  img, 0, 0);
3061
         for (row = 0; row < srcHeight; row++) {
3062
            GLuint depth[MAX_WIDTH];
3063
	    GLubyte stencil[MAX_WIDTH];
3064
            GLint i;
3065
	    GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
3066
 
3067
	    if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
3068
	       keepstencil = GL_TRUE;
3069
	    }
3070
            else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
3071
	       keepdepth = GL_TRUE;
3072
	    }
3073
 
3074
	    if (keepdepth == GL_FALSE)
3075
	       /* the 24 depth bits will be in the low position: */
3076
	       _mesa_unpack_depth_span(ctx, srcWidth,
3077
				       GL_UNSIGNED_INT, /* dst type */
3078
				       keepstencil ? depth : dstRow, /* dst addr */
3079
				       depthScale,
3080
				       srcType, src, srcPacking);
3081
 
3082
	    if (keepstencil == GL_FALSE)
3083
	       /* get the 8-bit stencil values */
3084
	       _mesa_unpack_stencil_span(ctx, srcWidth,
3085
					 GL_UNSIGNED_BYTE, /* dst type */
3086
					 stencil, /* dst addr */
3087
					 srcType, src, srcPacking,
3088
					 ctx->_ImageTransferState);
3089
 
3090
	    for (i = 0; i < srcWidth; i++) {
3091
	       if (keepstencil)
3092
		  dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
3093
	       else
3094
		  dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
3095
	    }
3096
 
3097
            src += srcRowStride;
3098
            dstRow += dstRowStride / sizeof(GLuint);
3099
         }
3100
      }
3101
   }
3102
   return GL_TRUE;
3103
}
3104
 
3105
 
3106
/**
3107
 * Store a combined depth/stencil texture image.
3108
 */
3109
static GLboolean
3110
_mesa_texstore_s8_z24(TEXSTORE_PARAMS)
3111
{
3112
   const GLuint depthScale = 0xffffff;
3113
   const GLint srcRowStride
3114
      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
3115
      / sizeof(GLuint);
3116
   GLint img, row;
3117
 
3118
   ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
3119
   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
3120
          srcFormat == GL_DEPTH_COMPONENT ||
3121
          srcFormat == GL_STENCIL_INDEX);
3122
   ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
3123
          srcType == GL_UNSIGNED_INT_24_8_EXT);
3124
 
3125
   for (img = 0; img < srcDepth; img++) {
3126
      GLuint *dstRow = (GLuint *) dstAddr
3127
	 + dstImageOffsets[dstZoffset + img]
3128
	 + dstYoffset * dstRowStride / sizeof(GLuint)
3129
	 + dstXoffset;
3130
      const GLuint *src
3131
	 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
3132
						srcWidth, srcHeight,
3133
						srcFormat, srcType,
3134
						img, 0, 0);
3135
      for (row = 0; row < srcHeight; row++) {
3136
	 GLuint depth[MAX_WIDTH];
3137
	 GLubyte stencil[MAX_WIDTH];
3138
	 GLint i;
3139
	 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
3140
 
3141
	 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
3142
	    keepstencil = GL_TRUE;
3143
	 }
3144
         else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
3145
	    keepdepth = GL_TRUE;
3146
	 }
3147
 
3148
	 if (keepdepth == GL_FALSE)
3149
	    /* the 24 depth bits will be in the low position: */
3150
	    _mesa_unpack_depth_span(ctx, srcWidth,
3151
				    GL_UNSIGNED_INT, /* dst type */
3152
				    keepstencil ? depth : dstRow, /* dst addr */
3153
				    depthScale,
3154
				    srcType, src, srcPacking);
3155
 
3156
	 if (keepstencil == GL_FALSE)
3157
	    /* get the 8-bit stencil values */
3158
	    _mesa_unpack_stencil_span(ctx, srcWidth,
3159
				      GL_UNSIGNED_BYTE, /* dst type */
3160
				      stencil, /* dst addr */
3161
				      srcType, src, srcPacking,
3162
				      ctx->_ImageTransferState);
3163
 
3164
	 /* merge stencil values into depth values */
3165
	 for (i = 0; i < srcWidth; i++) {
3166
	    if (keepstencil)
3167
	       dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
3168
	    else
3169
	       dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
3170
 
3171
	 }
3172
	 src += srcRowStride;
3173
	 dstRow += dstRowStride / sizeof(GLuint);
3174
      }
3175
   }
3176
   return GL_TRUE;
3177
}
3178
 
3179
 
3180
/**
3181
 * Store simple 8-bit/value stencil texture data.
3182
 */
3183
static GLboolean
3184
_mesa_texstore_s8(TEXSTORE_PARAMS)
3185
{
3186
   ASSERT(dstFormat == MESA_FORMAT_S8);
3187
   ASSERT(srcFormat == GL_STENCIL_INDEX);
3188
 
3189
   if (!ctx->_ImageTransferState &&
3190
       !srcPacking->SwapBytes &&
3191
       baseInternalFormat == srcFormat &&
3192
       srcType == GL_UNSIGNED_BYTE) {
3193
      /* simple memcpy path */
3194
      memcpy_texture(ctx, dims,
3195
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3196
                     dstRowStride,
3197
                     dstImageOffsets,
3198
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3199
                     srcAddr, srcPacking);
3200
   }
3201
   else {
3202
      const GLint srcRowStride
3203
	 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
3204
	 / sizeof(GLuint);
3205
      GLint img, row;
3206
 
3207
      for (img = 0; img < srcDepth; img++) {
3208
         GLubyte *dstRow = (GLubyte *) dstAddr
3209
            + dstImageOffsets[dstZoffset + img]
3210
            + dstYoffset * dstRowStride / sizeof(GLuint)
3211
            + dstXoffset;
3212
         const GLuint *src
3213
            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
3214
                                                   srcWidth, srcHeight,
3215
                                                   srcFormat, srcType,
3216
                                                   img, 0, 0);
3217
         for (row = 0; row < srcHeight; row++) {
3218
            GLubyte stencil[MAX_WIDTH];
3219
            GLint i;
3220
 
3221
            /* get the 8-bit stencil values */
3222
            _mesa_unpack_stencil_span(ctx, srcWidth,
3223
                                      GL_UNSIGNED_BYTE, /* dst type */
3224
                                      stencil, /* dst addr */
3225
                                      srcType, src, srcPacking,
3226
                                      ctx->_ImageTransferState);
3227
            /* merge stencil values into depth values */
3228
            for (i = 0; i < srcWidth; i++)
3229
               dstRow[i] = stencil[i];
3230
 
3231
            src += srcRowStride;
3232
            dstRow += dstRowStride / sizeof(GLubyte);
3233
         }
3234
      }
3235
 
3236
   }
3237
 
3238
   return GL_TRUE;
3239
}
3240
 
3241
 
3242
/**
3243
 * Store an image in any of the formats:
3244
 *   _mesa_texformat_rgba_float32
3245
 *   _mesa_texformat_rgb_float32
3246
 *   _mesa_texformat_alpha_float32
3247
 *   _mesa_texformat_luminance_float32
3248
 *   _mesa_texformat_luminance_alpha_float32
3249
 *   _mesa_texformat_intensity_float32
3250
 */
3251
static GLboolean
3252
_mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
3253
{
3254
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3255
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3256
   const GLint components = _mesa_components_in_format(baseFormat);
3257
 
3258
   ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
3259
          dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
3260
          dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
3261
          dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
3262
          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
3263
          dstFormat == MESA_FORMAT_INTENSITY_FLOAT32);
3264
   ASSERT(baseInternalFormat == GL_RGBA ||
3265
          baseInternalFormat == GL_RGB ||
3266
          baseInternalFormat == GL_ALPHA ||
3267
          baseInternalFormat == GL_LUMINANCE ||
3268
          baseInternalFormat == GL_LUMINANCE_ALPHA ||
3269
          baseInternalFormat == GL_INTENSITY);
3270
   ASSERT(texelBytes == components * sizeof(GLfloat));
3271
 
3272
   if (!ctx->_ImageTransferState &&
3273
       !srcPacking->SwapBytes &&
3274
       baseInternalFormat == srcFormat &&
3275
       srcType == GL_FLOAT) {
3276
      /* simple memcpy path */
3277
      memcpy_texture(ctx, dims,
3278
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3279
                     dstRowStride,
3280
                     dstImageOffsets,
3281
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3282
                     srcAddr, srcPacking);
3283
   }
3284
   else {
3285
      /* general path */
3286
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
3287
                                                 baseInternalFormat,
3288
                                                 baseFormat,
3289
                                                 srcWidth, srcHeight, srcDepth,
3290
                                                 srcFormat, srcType, srcAddr,
3291
                                                 srcPacking,
3292
                                                 ctx->_ImageTransferState);
3293
      const GLfloat *srcRow = tempImage;
3294
      GLint bytesPerRow;
3295
      GLint img, row;
3296
      if (!tempImage)
3297
         return GL_FALSE;
3298
      bytesPerRow = srcWidth * components * sizeof(GLfloat);
3299
      for (img = 0; img < srcDepth; img++) {
3300
         GLubyte *dstRow = (GLubyte *) dstAddr
3301
            + dstImageOffsets[dstZoffset + img] * texelBytes
3302
            + dstYoffset * dstRowStride
3303
            + dstXoffset * texelBytes;
3304
         for (row = 0; row < srcHeight; row++) {
3305
            memcpy(dstRow, srcRow, bytesPerRow);
3306
            dstRow += dstRowStride;
3307
            srcRow += srcWidth * components;
3308
         }
3309
      }
3310
 
3311
      free((void *) tempImage);
3312
   }
3313
   return GL_TRUE;
3314
}
3315
 
3316
 
3317
 
3318
/**
3319
 * As above, but store 16-bit floats.
3320
 */
3321
static GLboolean
3322
_mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
3323
{
3324
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3325
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3326
   const GLint components = _mesa_components_in_format(baseFormat);
3327
 
3328
   ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
3329
          dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
3330
          dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
3331
          dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
3332
          dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
3333
          dstFormat == MESA_FORMAT_INTENSITY_FLOAT16);
3334
   ASSERT(baseInternalFormat == GL_RGBA ||
3335
          baseInternalFormat == GL_RGB ||
3336
          baseInternalFormat == GL_ALPHA ||
3337
          baseInternalFormat == GL_LUMINANCE ||
3338
          baseInternalFormat == GL_LUMINANCE_ALPHA ||
3339
          baseInternalFormat == GL_INTENSITY);
3340
   ASSERT(texelBytes == components * sizeof(GLhalfARB));
3341
 
3342
   if (!ctx->_ImageTransferState &&
3343
       !srcPacking->SwapBytes &&
3344
       baseInternalFormat == srcFormat &&
3345
       srcType == GL_HALF_FLOAT_ARB) {
3346
      /* simple memcpy path */
3347
      memcpy_texture(ctx, dims,
3348
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3349
                     dstRowStride,
3350
                     dstImageOffsets,
3351
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3352
                     srcAddr, srcPacking);
3353
   }
3354
   else {
3355
      /* general path */
3356
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
3357
                                                 baseInternalFormat,
3358
                                                 baseFormat,
3359
                                                 srcWidth, srcHeight, srcDepth,
3360
                                                 srcFormat, srcType, srcAddr,
3361
                                                 srcPacking,
3362
                                                 ctx->_ImageTransferState);
3363
      const GLfloat *src = tempImage;
3364
      GLint img, row;
3365
      if (!tempImage)
3366
         return GL_FALSE;
3367
      for (img = 0; img < srcDepth; img++) {
3368
         GLubyte *dstRow = (GLubyte *) dstAddr
3369
            + dstImageOffsets[dstZoffset + img] * texelBytes
3370
            + dstYoffset * dstRowStride
3371
            + dstXoffset * texelBytes;
3372
         for (row = 0; row < srcHeight; row++) {
3373
            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
3374
            GLint i;
3375
            for (i = 0; i < srcWidth * components; i++) {
3376
               dstTexel[i] = _mesa_float_to_half(src[i]);
3377
            }
3378
            dstRow += dstRowStride;
3379
            src += srcWidth * components;
3380
         }
3381
      }
3382
 
3383
      free((void *) tempImage);
3384
   }
3385
   return GL_TRUE;
3386
}
3387
 
3388
 
3389
/* non-normalized, signed int8 */
3390
static GLboolean
3391
_mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
3392
{
3393
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3394
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3395
   const GLint components = _mesa_components_in_format(baseFormat);
3396
 
3397
   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT8);
3398
   ASSERT(baseInternalFormat == GL_RGBA ||
3399
          baseInternalFormat == GL_RGB ||
3400
          baseInternalFormat == GL_ALPHA ||
3401
          baseInternalFormat == GL_LUMINANCE ||
3402
          baseInternalFormat == GL_LUMINANCE_ALPHA ||
3403
          baseInternalFormat == GL_INTENSITY);
3404
   ASSERT(texelBytes == components * sizeof(GLbyte));
3405
 
3406
   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3407
    * to integer formats.
3408
    */
3409
   if (!srcPacking->SwapBytes &&
3410
       baseInternalFormat == srcFormat &&
3411
       srcType == GL_BYTE) {
3412
      /* simple memcpy path */
3413
      memcpy_texture(ctx, dims,
3414
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3415
                     dstRowStride,
3416
                     dstImageOffsets,
3417
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3418
                     srcAddr, srcPacking);
3419
   }
3420
   else {
3421
      /* general path */
3422
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
3423
                                                 baseInternalFormat,
3424
                                                 baseFormat,
3425
                                                 srcWidth, srcHeight, srcDepth,
3426
                                                 srcFormat, srcType, srcAddr,
3427
                                                 srcPacking, 0x0);
3428
      const GLfloat *src = tempImage;
3429
      GLint img, row;
3430
      if (!tempImage)
3431
         return GL_FALSE;
3432
      for (img = 0; img < srcDepth; img++) {
3433
         GLubyte *dstRow = (GLubyte *) dstAddr
3434
            + dstImageOffsets[dstZoffset + img] * texelBytes
3435
            + dstYoffset * dstRowStride
3436
            + dstXoffset * texelBytes;
3437
         for (row = 0; row < srcHeight; row++) {
3438
            GLbyte *dstTexel = (GLbyte *) dstRow;
3439
            GLint i;
3440
            for (i = 0; i < srcWidth * components; i++) {
3441
               dstTexel[i] = (GLbyte) src[i];
3442
            }
3443
            dstRow += dstRowStride;
3444
            src += srcWidth * components;
3445
         }
3446
      }
3447
 
3448
      free((void *) tempImage);
3449
   }
3450
   return GL_TRUE;
3451
}
3452
 
3453
 
3454
/* non-normalized, signed int16 */
3455
static GLboolean
3456
_mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
3457
{
3458
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3459
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3460
   const GLint components = _mesa_components_in_format(baseFormat);
3461
 
3462
   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT16);
3463
   ASSERT(baseInternalFormat == GL_RGBA ||
3464
          baseInternalFormat == GL_RGB ||
3465
          baseInternalFormat == GL_ALPHA ||
3466
          baseInternalFormat == GL_LUMINANCE ||
3467
          baseInternalFormat == GL_LUMINANCE_ALPHA ||
3468
          baseInternalFormat == GL_INTENSITY);
3469
   ASSERT(texelBytes == components * sizeof(GLshort));
3470
 
3471
   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3472
    * to integer formats.
3473
    */
3474
   if (!srcPacking->SwapBytes &&
3475
       baseInternalFormat == srcFormat &&
3476
       srcType == GL_SHORT) {
3477
      /* simple memcpy path */
3478
      memcpy_texture(ctx, dims,
3479
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3480
                     dstRowStride,
3481
                     dstImageOffsets,
3482
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3483
                     srcAddr, srcPacking);
3484
   }
3485
   else {
3486
      /* general path */
3487
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
3488
                                                 baseInternalFormat,
3489
                                                 baseFormat,
3490
                                                 srcWidth, srcHeight, srcDepth,
3491
                                                 srcFormat, srcType, srcAddr,
3492
                                                 srcPacking, 0x0);
3493
      const GLfloat *src = tempImage;
3494
      GLint img, row;
3495
      if (!tempImage)
3496
         return GL_FALSE;
3497
      for (img = 0; img < srcDepth; img++) {
3498
         GLubyte *dstRow = (GLubyte *) dstAddr
3499
            + dstImageOffsets[dstZoffset + img] * texelBytes
3500
            + dstYoffset * dstRowStride
3501
            + dstXoffset * texelBytes;
3502
         for (row = 0; row < srcHeight; row++) {
3503
            GLshort *dstTexel = (GLshort *) dstRow;
3504
            GLint i;
3505
            for (i = 0; i < srcWidth * components; i++) {
3506
               dstTexel[i] = (GLint) src[i];
3507
            }
3508
            dstRow += dstRowStride;
3509
            src += srcWidth * components;
3510
         }
3511
      }
3512
 
3513
      free((void *) tempImage);
3514
   }
3515
   return GL_TRUE;
3516
}
3517
 
3518
 
3519
/* non-normalized, signed int32 */
3520
static GLboolean
3521
_mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
3522
{
3523
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3524
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3525
   const GLint components = _mesa_components_in_format(baseFormat);
3526
 
3527
   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT32);
3528
   ASSERT(baseInternalFormat == GL_RGBA ||
3529
          baseInternalFormat == GL_RGB ||
3530
          baseInternalFormat == GL_ALPHA ||
3531
          baseInternalFormat == GL_LUMINANCE ||
3532
          baseInternalFormat == GL_LUMINANCE_ALPHA ||
3533
          baseInternalFormat == GL_INTENSITY);
3534
   ASSERT(texelBytes == components * sizeof(GLint));
3535
 
3536
   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3537
    * to integer formats.
3538
    */
3539
   if (!srcPacking->SwapBytes &&
3540
       baseInternalFormat == srcFormat &&
3541
       srcType == GL_INT) {
3542
      /* simple memcpy path */
3543
      memcpy_texture(ctx, dims,
3544
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3545
                     dstRowStride,
3546
                     dstImageOffsets,
3547
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3548
                     srcAddr, srcPacking);
3549
   }
3550
   else {
3551
      /* general path */
3552
      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
3553
                                                 baseInternalFormat,
3554
                                                 baseFormat,
3555
                                                 srcWidth, srcHeight, srcDepth,
3556
                                                 srcFormat, srcType, srcAddr,
3557
                                                 srcPacking, 0x0);
3558
      const GLfloat *src = tempImage;
3559
      GLint img, row;
3560
      if (!tempImage)
3561
         return GL_FALSE;
3562
      for (img = 0; img < srcDepth; img++) {
3563
         GLubyte *dstRow = (GLubyte *) dstAddr
3564
            + dstImageOffsets[dstZoffset + img] * texelBytes
3565
            + dstYoffset * dstRowStride
3566
            + dstXoffset * texelBytes;
3567
         for (row = 0; row < srcHeight; row++) {
3568
            GLint *dstTexel = (GLint *) dstRow;
3569
            GLint i;
3570
            for (i = 0; i < srcWidth * components; i++) {
3571
               dstTexel[i] = (GLint) src[i];
3572
            }
3573
            dstRow += dstRowStride;
3574
            src += srcWidth * components;
3575
         }
3576
      }
3577
 
3578
      free((void *) tempImage);
3579
   }
3580
   return GL_TRUE;
3581
}
3582
 
3583
 
3584
/* non-normalized, unsigned int8 */
3585
static GLboolean
3586
_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
3587
{
3588
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3589
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3590
   const GLint components = _mesa_components_in_format(baseFormat);
3591
 
3592
   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT8);
3593
   ASSERT(baseInternalFormat == GL_RGBA ||
3594
          baseInternalFormat == GL_RGB ||
3595
          baseInternalFormat == GL_ALPHA ||
3596
          baseInternalFormat == GL_LUMINANCE ||
3597
          baseInternalFormat == GL_LUMINANCE_ALPHA ||
3598
          baseInternalFormat == GL_INTENSITY);
3599
   ASSERT(texelBytes == components * sizeof(GLubyte));
3600
 
3601
   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3602
    * to integer formats.
3603
    */
3604
   if (!srcPacking->SwapBytes &&
3605
       baseInternalFormat == srcFormat &&
3606
       srcType == GL_UNSIGNED_BYTE) {
3607
      /* simple memcpy path */
3608
      memcpy_texture(ctx, dims,
3609
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3610
                     dstRowStride,
3611
                     dstImageOffsets,
3612
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3613
                     srcAddr, srcPacking);
3614
   }
3615
   else {
3616
      /* general path */
3617
      const GLuint *tempImage =
3618
         make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3619
                              srcWidth, srcHeight, srcDepth,
3620
                              srcFormat, srcType, srcAddr, srcPacking);
3621
      const GLuint *src = tempImage;
3622
      GLint img, row;
3623
      if (!tempImage)
3624
         return GL_FALSE;
3625
      for (img = 0; img < srcDepth; img++) {
3626
         GLubyte *dstRow = (GLubyte *) dstAddr
3627
            + dstImageOffsets[dstZoffset + img] * texelBytes
3628
            + dstYoffset * dstRowStride
3629
            + dstXoffset * texelBytes;
3630
         for (row = 0; row < srcHeight; row++) {
3631
            GLubyte *dstTexel = (GLubyte *) dstRow;
3632
            GLint i;
3633
            for (i = 0; i < srcWidth * components; i++) {
3634
               dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff);
3635
            }
3636
            dstRow += dstRowStride;
3637
            src += srcWidth * components;
3638
         }
3639
      }
3640
 
3641
      free((void *) tempImage);
3642
   }
3643
   return GL_TRUE;
3644
}
3645
 
3646
 
3647
/* non-normalized, unsigned int16 */
3648
static GLboolean
3649
_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
3650
{
3651
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3652
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3653
   const GLint components = _mesa_components_in_format(baseFormat);
3654
 
3655
   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT16);
3656
   ASSERT(baseInternalFormat == GL_RGBA ||
3657
          baseInternalFormat == GL_RGB ||
3658
          baseInternalFormat == GL_ALPHA ||
3659
          baseInternalFormat == GL_LUMINANCE ||
3660
          baseInternalFormat == GL_LUMINANCE_ALPHA ||
3661
          baseInternalFormat == GL_INTENSITY);
3662
   ASSERT(texelBytes == components * sizeof(GLushort));
3663
 
3664
   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3665
    * to integer formats.
3666
    */
3667
   if (!srcPacking->SwapBytes &&
3668
       baseInternalFormat == srcFormat &&
3669
       srcType == GL_UNSIGNED_SHORT) {
3670
      /* simple memcpy path */
3671
      memcpy_texture(ctx, dims,
3672
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3673
                     dstRowStride,
3674
                     dstImageOffsets,
3675
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3676
                     srcAddr, srcPacking);
3677
   }
3678
   else {
3679
      /* general path */
3680
      const GLuint *tempImage =
3681
         make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3682
                              srcWidth, srcHeight, srcDepth,
3683
                              srcFormat, srcType, srcAddr, srcPacking);
3684
      const GLuint *src = tempImage;
3685
      GLint img, row;
3686
      if (!tempImage)
3687
         return GL_FALSE;
3688
      for (img = 0; img < srcDepth; img++) {
3689
         GLubyte *dstRow = (GLubyte *) dstAddr
3690
            + dstImageOffsets[dstZoffset + img] * texelBytes
3691
            + dstYoffset * dstRowStride
3692
            + dstXoffset * texelBytes;
3693
         for (row = 0; row < srcHeight; row++) {
3694
            GLushort *dstTexel = (GLushort *) dstRow;
3695
            GLint i;
3696
            for (i = 0; i < srcWidth * components; i++) {
3697
               dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff);
3698
            }
3699
            dstRow += dstRowStride;
3700
            src += srcWidth * components;
3701
         }
3702
      }
3703
 
3704
      free((void *) tempImage);
3705
   }
3706
   return GL_TRUE;
3707
}
3708
 
3709
 
3710
/* non-normalized, unsigned int32 */
3711
static GLboolean
3712
_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
3713
{
3714
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3715
   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3716
   const GLint components = _mesa_components_in_format(baseFormat);
3717
 
3718
   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT32);
3719
   ASSERT(baseInternalFormat == GL_RGBA ||
3720
          baseInternalFormat == GL_RGB ||
3721
          baseInternalFormat == GL_ALPHA ||
3722
          baseInternalFormat == GL_LUMINANCE ||
3723
          baseInternalFormat == GL_LUMINANCE_ALPHA ||
3724
          baseInternalFormat == GL_INTENSITY);
3725
   ASSERT(texelBytes == components * sizeof(GLuint));
3726
 
3727
   /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3728
    * to integer formats.
3729
    */
3730
   if (!srcPacking->SwapBytes &&
3731
       baseInternalFormat == srcFormat &&
3732
       srcType == GL_UNSIGNED_INT) {
3733
      /* simple memcpy path */
3734
      memcpy_texture(ctx, dims,
3735
                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3736
                     dstRowStride,
3737
                     dstImageOffsets,
3738
                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3739
                     srcAddr, srcPacking);
3740
   }
3741
   else {
3742
      /* general path */
3743
      const GLuint *tempImage =
3744
         make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3745
                              srcWidth, srcHeight, srcDepth,
3746
                              srcFormat, srcType, srcAddr, srcPacking);
3747
      const GLuint *src = tempImage;
3748
      GLint img, row;
3749
      if (!tempImage)
3750
         return GL_FALSE;
3751
      for (img = 0; img < srcDepth; img++) {
3752
         GLubyte *dstRow = (GLubyte *) dstAddr
3753
            + dstImageOffsets[dstZoffset + img] * texelBytes
3754
            + dstYoffset * dstRowStride
3755
            + dstXoffset * texelBytes;
3756
         for (row = 0; row < srcHeight; row++) {
3757
            GLuint *dstTexel = (GLuint *) dstRow;
3758
            GLint i;
3759
            for (i = 0; i < srcWidth * components; i++) {
3760
               dstTexel[i] = src[i];
3761
            }
3762
            dstRow += dstRowStride;
3763
            src += srcWidth * components;
3764
         }
3765
      }
3766
 
3767
      free((void *) tempImage);
3768
   }
3769
   return GL_TRUE;
3770
}
3771
 
3772
 
3773
 
3774
 
3775
#if FEATURE_EXT_texture_sRGB
3776
static GLboolean
3777
_mesa_texstore_srgb8(TEXSTORE_PARAMS)
3778
{
3779
   gl_format newDstFormat;
3780
   GLboolean k;
3781
 
3782
   ASSERT(dstFormat == MESA_FORMAT_SRGB8);
3783
 
3784
   /* reuse normal rgb texstore code */
3785
   newDstFormat = MESA_FORMAT_RGB888;
3786
 
3787
   k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
3788
                             newDstFormat, dstAddr,
3789
                             dstXoffset, dstYoffset, dstZoffset,
3790
                             dstRowStride, dstImageOffsets,
3791
                             srcWidth, srcHeight, srcDepth,
3792
                             srcFormat, srcType,
3793
                             srcAddr, srcPacking);
3794
   return k;
3795
}
3796
 
3797
 
3798
static GLboolean
3799
_mesa_texstore_srgba8(TEXSTORE_PARAMS)
3800
{
3801
   gl_format newDstFormat;
3802
   GLboolean k;
3803
 
3804
   ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
3805
 
3806
   /* reuse normal rgba texstore code */
3807
   newDstFormat = MESA_FORMAT_RGBA8888;
3808
   k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
3809
                               newDstFormat, dstAddr,
3810
                               dstXoffset, dstYoffset, dstZoffset,
3811
                               dstRowStride, dstImageOffsets,
3812
                               srcWidth, srcHeight, srcDepth,
3813
                               srcFormat, srcType,
3814
                               srcAddr, srcPacking);
3815
   return k;
3816
}
3817
 
3818
 
3819
static GLboolean
3820
_mesa_texstore_sargb8(TEXSTORE_PARAMS)
3821
{
3822
   gl_format newDstFormat;
3823
   GLboolean k;
3824
 
3825
   ASSERT(dstFormat == MESA_FORMAT_SARGB8);
3826
 
3827
   /* reuse normal rgba texstore code */
3828
   newDstFormat = MESA_FORMAT_ARGB8888;
3829
 
3830
   k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
3831
                               newDstFormat, dstAddr,
3832
                               dstXoffset, dstYoffset, dstZoffset,
3833
                               dstRowStride, dstImageOffsets,
3834
                               srcWidth, srcHeight, srcDepth,
3835
                               srcFormat, srcType,
3836
                               srcAddr, srcPacking);
3837
   return k;
3838
}
3839
 
3840
 
3841
static GLboolean
3842
_mesa_texstore_sl8(TEXSTORE_PARAMS)
3843
{
3844
   gl_format newDstFormat;
3845
   GLboolean k;
3846
 
3847
   ASSERT(dstFormat == MESA_FORMAT_SL8);
3848
 
3849
   newDstFormat = MESA_FORMAT_L8;
3850
 
3851
   /* _mesa_textore_a8 handles luminance8 too */
3852
   k = _mesa_texstore_a8(ctx, dims, baseInternalFormat,
3853
                         newDstFormat, dstAddr,
3854
                         dstXoffset, dstYoffset, dstZoffset,
3855
                         dstRowStride, dstImageOffsets,
3856
                         srcWidth, srcHeight, srcDepth,
3857
                         srcFormat, srcType,
3858
                         srcAddr, srcPacking);
3859
   return k;
3860
}
3861
 
3862
 
3863
static GLboolean
3864
_mesa_texstore_sla8(TEXSTORE_PARAMS)
3865
{
3866
   gl_format newDstFormat;
3867
   GLboolean k;
3868
 
3869
   ASSERT(dstFormat == MESA_FORMAT_SLA8);
3870
 
3871
   /* reuse normal luminance/alpha texstore code */
3872
   newDstFormat = MESA_FORMAT_AL88;
3873
 
3874
   k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
3875
			      newDstFormat, dstAddr,
3876
			      dstXoffset, dstYoffset, dstZoffset,
3877
			      dstRowStride, dstImageOffsets,
3878
			      srcWidth, srcHeight, srcDepth,
3879
			      srcFormat, srcType,
3880
			      srcAddr, srcPacking);
3881
   return k;
3882
}
3883
 
3884
#else
3885
 
3886
/* these are used only in texstore_funcs[] below */
3887
#define _mesa_texstore_srgb8 NULL
3888
#define _mesa_texstore_srgba8 NULL
3889
#define _mesa_texstore_sargb8 NULL
3890
#define _mesa_texstore_sl8 NULL
3891
#define _mesa_texstore_sla8 NULL
3892
 
3893
#endif /* FEATURE_EXT_texture_sRGB */
3894
 
3895
 
3896
 
3897
 
3898
/**
3899
 * Table mapping MESA_FORMAT_* to _mesa_texstore_*()
3900
 * XXX this is somewhat temporary.
3901
 */
3902
static const struct {
3903
   gl_format Name;
3904
   StoreTexImageFunc Store;
3905
}
3906
texstore_funcs[MESA_FORMAT_COUNT] =
3907
{
3908
   { MESA_FORMAT_NONE, NULL },
3909
   { MESA_FORMAT_RGBA8888, _mesa_texstore_rgba8888 },
3910
   { MESA_FORMAT_RGBA8888_REV, _mesa_texstore_rgba8888 },
3911
   { MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 },
3912
   { MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 },
3913
   { MESA_FORMAT_XRGB8888, _mesa_texstore_argb8888 },
3914
   { MESA_FORMAT_XRGB8888_REV, _mesa_texstore_argb8888 },
3915
   { MESA_FORMAT_RGB888, _mesa_texstore_rgb888 },
3916
   { MESA_FORMAT_BGR888, _mesa_texstore_bgr888 },
3917
   { MESA_FORMAT_RGB565, _mesa_texstore_rgb565 },
3918
   { MESA_FORMAT_RGB565_REV, _mesa_texstore_rgb565 },
3919
   { MESA_FORMAT_ARGB4444, _mesa_texstore_argb4444 },
3920
   { MESA_FORMAT_ARGB4444_REV, _mesa_texstore_argb4444 },
3921
   { MESA_FORMAT_RGBA5551, _mesa_texstore_rgba5551 },
3922
   { MESA_FORMAT_ARGB1555, _mesa_texstore_argb1555 },
3923
   { MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 },
3924
   { MESA_FORMAT_AL88, _mesa_texstore_unorm88 },
3925
   { MESA_FORMAT_AL88_REV, _mesa_texstore_unorm88 },
3926
   { MESA_FORMAT_AL1616, _mesa_texstore_unorm1616 },
3927
   { MESA_FORMAT_AL1616_REV, _mesa_texstore_unorm1616 },
3928
   { MESA_FORMAT_RGB332, _mesa_texstore_rgb332 },
3929
   { MESA_FORMAT_A8, _mesa_texstore_a8 },
3930
   { MESA_FORMAT_L8, _mesa_texstore_a8 },
3931
   { MESA_FORMAT_I8, _mesa_texstore_a8 },
3932
   { MESA_FORMAT_CI8, _mesa_texstore_ci8 },
3933
   { MESA_FORMAT_YCBCR, _mesa_texstore_ycbcr },
3934
   { MESA_FORMAT_YCBCR_REV, _mesa_texstore_ycbcr },
3935
   { MESA_FORMAT_R8, _mesa_texstore_a8 },
3936
   { MESA_FORMAT_RG88, _mesa_texstore_unorm88 },
3937
   { MESA_FORMAT_RG88_REV, _mesa_texstore_unorm88 },
3938
   { MESA_FORMAT_R16, _mesa_texstore_r16 },
3939
   { MESA_FORMAT_RG1616, _mesa_texstore_unorm1616 },
3940
   { MESA_FORMAT_RG1616_REV, _mesa_texstore_unorm1616 },
3941
   { MESA_FORMAT_Z24_S8, _mesa_texstore_z24_s8 },
3942
   { MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 },
3943
   { MESA_FORMAT_Z16, _mesa_texstore_z16 },
3944
   { MESA_FORMAT_X8_Z24, _mesa_texstore_x8_z24 },
3945
   { MESA_FORMAT_Z24_X8, _mesa_texstore_z24_x8 },
3946
   { MESA_FORMAT_Z32, _mesa_texstore_z32 },
3947
   { MESA_FORMAT_S8, _mesa_texstore_s8 },
3948
   { MESA_FORMAT_SRGB8, _mesa_texstore_srgb8 },
3949
   { MESA_FORMAT_SRGBA8, _mesa_texstore_srgba8 },
3950
   { MESA_FORMAT_SARGB8, _mesa_texstore_sargb8 },
3951
   { MESA_FORMAT_SL8, _mesa_texstore_sl8 },
3952
   { MESA_FORMAT_SLA8, _mesa_texstore_sla8 },
3953
   { MESA_FORMAT_SRGB_DXT1, _mesa_texstore_rgb_dxt1 },
3954
   { MESA_FORMAT_SRGBA_DXT1, _mesa_texstore_rgba_dxt1 },
3955
   { MESA_FORMAT_SRGBA_DXT3, _mesa_texstore_rgba_dxt3 },
3956
   { MESA_FORMAT_SRGBA_DXT5, _mesa_texstore_rgba_dxt5 },
3957
   { MESA_FORMAT_RGB_FXT1, _mesa_texstore_rgb_fxt1 },
3958
   { MESA_FORMAT_RGBA_FXT1, _mesa_texstore_rgba_fxt1 },
3959
   { MESA_FORMAT_RGB_DXT1, _mesa_texstore_rgb_dxt1 },
3960
   { MESA_FORMAT_RGBA_DXT1, _mesa_texstore_rgba_dxt1 },
3961
   { MESA_FORMAT_RGBA_DXT3, _mesa_texstore_rgba_dxt3 },
3962
   { MESA_FORMAT_RGBA_DXT5, _mesa_texstore_rgba_dxt5 },
3963
   { MESA_FORMAT_RGBA_FLOAT32, _mesa_texstore_rgba_float32 },
3964
   { MESA_FORMAT_RGBA_FLOAT16, _mesa_texstore_rgba_float16 },
3965
   { MESA_FORMAT_RGB_FLOAT32, _mesa_texstore_rgba_float32 },
3966
   { MESA_FORMAT_RGB_FLOAT16, _mesa_texstore_rgba_float16 },
3967
   { MESA_FORMAT_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
3968
   { MESA_FORMAT_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
3969
   { MESA_FORMAT_LUMINANCE_FLOAT32, _mesa_texstore_rgba_float32 },
3970
   { MESA_FORMAT_LUMINANCE_FLOAT16, _mesa_texstore_rgba_float16 },
3971
   { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
3972
   { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
3973
   { MESA_FORMAT_INTENSITY_FLOAT32, _mesa_texstore_rgba_float32 },
3974
   { MESA_FORMAT_INTENSITY_FLOAT16, _mesa_texstore_rgba_float16 },
3975
 
3976
   { MESA_FORMAT_RGBA_INT8, _mesa_texstore_rgba_int8 },
3977
   { MESA_FORMAT_RGBA_INT16, _mesa_texstore_rgba_int16 },
3978
   { MESA_FORMAT_RGBA_INT32, _mesa_texstore_rgba_int32 },
3979
   { MESA_FORMAT_RGBA_UINT8, _mesa_texstore_rgba_uint8 },
3980
   { MESA_FORMAT_RGBA_UINT16, _mesa_texstore_rgba_uint16 },
3981
   { MESA_FORMAT_RGBA_UINT32, _mesa_texstore_rgba_uint32 },
3982
 
3983
   { MESA_FORMAT_DUDV8, _mesa_texstore_dudv8 },
3984
 
3985
   { MESA_FORMAT_SIGNED_R8, _mesa_texstore_signed_r8 },
3986
   { MESA_FORMAT_SIGNED_RG88, _mesa_texstore_signed_rg88 },
3987
   { MESA_FORMAT_SIGNED_RGBX8888, _mesa_texstore_signed_rgbx8888 },
3988
 
3989
   { MESA_FORMAT_SIGNED_RGBA8888, _mesa_texstore_signed_rgba8888 },
3990
   { MESA_FORMAT_SIGNED_RGBA8888_REV, _mesa_texstore_signed_rgba8888 },
3991
 
3992
   { MESA_FORMAT_SIGNED_R_16, _mesa_texstore_signed_rgba_16 },
3993
   { MESA_FORMAT_SIGNED_RG_16, _mesa_texstore_signed_rgba_16 },
3994
   { MESA_FORMAT_SIGNED_RGB_16, _mesa_texstore_signed_rgba_16 },
3995
   { MESA_FORMAT_SIGNED_RGBA_16, _mesa_texstore_signed_rgba_16 },
3996
   { MESA_FORMAT_RGBA_16, _mesa_texstore_rgba_16 }
3997
};
3998
 
3999
 
4000
static GLboolean
4001
_mesa_texstore_null(TEXSTORE_PARAMS)
4002
{
4003
   (void) ctx; (void) dims;
4004
   (void) baseInternalFormat;
4005
   (void) dstFormat;
4006
   (void) dstAddr;
4007
   (void) dstXoffset; (void) dstYoffset; (void) dstZoffset;
4008
   (void) dstRowStride; (void) dstImageOffsets;
4009
   (void) srcWidth; (void) srcHeight; (void) srcDepth;
4010
   (void) srcFormat; (void) srcType;
4011
   (void) srcAddr;
4012
   (void) srcPacking;
4013
 
4014
   /* should never happen */
4015
   _mesa_problem(NULL, "_mesa_texstore_null() is called");
4016
   return GL_FALSE;
4017
}
4018
 
4019
 
4020
/**
4021
 * Return the StoreTexImageFunc pointer to store an image in the given format.
4022
 */
4023
static StoreTexImageFunc
4024
_mesa_get_texstore_func(gl_format format)
4025
{
4026
#ifdef DEBUG
4027
   GLuint i;
4028
   for (i = 0; i < MESA_FORMAT_COUNT; i++) {
4029
      ASSERT(texstore_funcs[i].Name == i);
4030
   }
4031
#endif
4032
   ASSERT(texstore_funcs[format].Name == format);
4033
 
4034
   if (texstore_funcs[format].Store)
4035
      return texstore_funcs[format].Store;
4036
   else
4037
      return _mesa_texstore_null;
4038
}
4039
 
4040
 
4041
/**
4042
 * Store user data into texture memory.
4043
 * Called via glTex[Sub]Image1/2/3D()
4044
 */
4045
GLboolean
4046
_mesa_texstore(TEXSTORE_PARAMS)
4047
{
4048
   StoreTexImageFunc storeImage;
4049
   GLboolean success;
4050
 
4051
   storeImage = _mesa_get_texstore_func(dstFormat);
4052
 
4053
   success = storeImage(ctx, dims, baseInternalFormat,
4054
                        dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
4055
                        dstRowStride, dstImageOffsets,
4056
                        srcWidth, srcHeight, srcDepth,
4057
                        srcFormat, srcType, srcAddr, srcPacking);
4058
   return success;
4059
}
4060
 
4061
 
4062
/**
4063
 * Check if an unpack PBO is active prior to fetching a texture image.
4064
 * If so, do bounds checking and map the buffer into main memory.
4065
 * Any errors detected will be recorded.
4066
 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
4067
 */
4068
const GLvoid *
4069
_mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions,
4070
			    GLsizei width, GLsizei height, GLsizei depth,
4071
			    GLenum format, GLenum type, const GLvoid *pixels,
4072
			    const struct gl_pixelstore_attrib *unpack,
4073
			    const char *funcName)
4074
{
4075
   GLubyte *buf;
4076
 
4077
   if (!_mesa_is_bufferobj(unpack->BufferObj)) {
4078
      /* no PBO */
4079
      return pixels;
4080
   }
4081
   if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
4082
                                  format, type, pixels)) {
4083
      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)");
4084
      return NULL;
4085
   }
4086
 
4087
   buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
4088
                                          GL_READ_ONLY_ARB, unpack->BufferObj);
4089
   if (!buf) {
4090
      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped)");
4091
      return NULL;
4092
   }
4093
 
4094
   return ADD_POINTERS(buf, pixels);
4095
}
4096
 
4097
 
4098
/**
4099
 * Check if an unpack PBO is active prior to fetching a compressed texture
4100
 * image.
4101
 * If so, do bounds checking and map the buffer into main memory.
4102
 * Any errors detected will be recorded.
4103
 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
4104
 */
4105
const GLvoid *
4106
_mesa_validate_pbo_compressed_teximage(struct gl_context *ctx,
4107
                                 GLsizei imageSize, const GLvoid *pixels,
4108
                                 const struct gl_pixelstore_attrib *packing,
4109
                                 const char *funcName)
4110
{
4111
   GLubyte *buf;
4112
 
4113
   if (!_mesa_is_bufferobj(packing->BufferObj)) {
4114
      /* not using a PBO - return pointer unchanged */
4115
      return pixels;
4116
   }
4117
   if ((const GLubyte *) pixels + imageSize >
4118
       ((const GLubyte *) 0) + packing->BufferObj->Size) {
4119
      /* out of bounds read! */
4120
      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access)");
4121
      return NULL;
4122
   }
4123
 
4124
   buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
4125
                                         GL_READ_ONLY_ARB, packing->BufferObj);
4126
   if (!buf) {
4127
      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
4128
      return NULL;
4129
   }
4130
 
4131
   return ADD_POINTERS(buf, pixels);
4132
}
4133
 
4134
 
4135
/**
4136
 * This function must be called after either of the validate_pbo_*_teximage()
4137
 * functions.  It unmaps the PBO buffer if it was mapped earlier.
4138
 */
4139
void
4140
_mesa_unmap_teximage_pbo(struct gl_context *ctx,
4141
                         const struct gl_pixelstore_attrib *unpack)
4142
{
4143
   if (_mesa_is_bufferobj(unpack->BufferObj)) {
4144
      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
4145
                              unpack->BufferObj);
4146
   }
4147
}
4148
 
4149
 
4150
/** Return texture size in bytes */
4151
static GLuint
4152
texture_size(const struct gl_texture_image *texImage)
4153
{
4154
   GLuint sz = _mesa_format_image_size(texImage->TexFormat, texImage->Width,
4155
                                       texImage->Height, texImage->Depth);
4156
   return sz;
4157
}
4158
 
4159
 
4160
/** Return row stride in bytes */
4161
static GLuint
4162
texture_row_stride(const struct gl_texture_image *texImage)
4163
{
4164
   GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
4165
                                           texImage->Width);
4166
   return stride;
4167
}
4168
 
4169
 
4170
 
4171
/**
4172
 * This is the software fallback for Driver.TexImage1D()
4173
 * and Driver.CopyTexImage1D().
4174
 * \sa _mesa_store_teximage2d()
4175
 */
4176
void
4177
_mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
4178
                       GLint internalFormat,
4179
                       GLint width, GLint border,
4180
                       GLenum format, GLenum type, const GLvoid *pixels,
4181
                       const struct gl_pixelstore_attrib *packing,
4182
                       struct gl_texture_object *texObj,
4183
                       struct gl_texture_image *texImage)
4184
{
4185
   GLuint sizeInBytes;
4186
   (void) border;
4187
 
4188
   /* allocate memory */
4189
   sizeInBytes = texture_size(texImage);
4190
   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
4191
   if (!texImage->Data) {
4192
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
4193
      return;
4194
   }
4195
 
4196
   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
4197
                                        pixels, packing, "glTexImage1D");
4198
   if (!pixels) {
4199
      /* Note: we check for a NULL image pointer here, _after_ we allocated
4200
       * memory for the texture.  That's what the GL spec calls for.
4201
       */
4202
      return;
4203
   }
4204
   else {
4205
      const GLint dstRowStride = 0;
4206
      GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
4207
                                         texImage->TexFormat,
4208
                                         texImage->Data,
4209
                                         0, 0, 0,  /* dstX/Y/Zoffset */
4210
                                         dstRowStride,
4211
                                         texImage->ImageOffsets,
4212
                                         width, 1, 1,
4213
                                         format, type, pixels, packing);
4214
      if (!success) {
4215
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
4216
      }
4217
   }
4218
 
4219
   _mesa_unmap_teximage_pbo(ctx, packing);
4220
}
4221
 
4222
 
4223
/**
4224
 * This is the software fallback for Driver.TexImage2D()
4225
 * and Driver.CopyTexImage2D().
4226
 *
4227
 * This function is oriented toward storing images in main memory, rather
4228
 * than VRAM.  Device driver's can easily plug in their own replacement.
4229
 */
4230
void
4231
_mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
4232
                       GLint internalFormat,
4233
                       GLint width, GLint height, GLint border,
4234
                       GLenum format, GLenum type, const void *pixels,
4235
                       const struct gl_pixelstore_attrib *packing,
4236
                       struct gl_texture_object *texObj,
4237
                       struct gl_texture_image *texImage)
4238
{
4239
   GLuint sizeInBytes;
4240
   (void) border;
4241
 
4242
   /* allocate memory */
4243
   sizeInBytes = texture_size(texImage);
4244
   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
4245
   if (!texImage->Data) {
4246
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
4247
      return;
4248
   }
4249
 
4250
   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
4251
                                        pixels, packing, "glTexImage2D");
4252
   if (!pixels) {
4253
      /* Note: we check for a NULL image pointer here, _after_ we allocated
4254
       * memory for the texture.  That's what the GL spec calls for.
4255
       */
4256
      return;
4257
   }
4258
   else {
4259
      GLint dstRowStride = texture_row_stride(texImage);
4260
      GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
4261
                                         texImage->TexFormat,
4262
                                         texImage->Data,
4263
                                         0, 0, 0,  /* dstX/Y/Zoffset */
4264
                                         dstRowStride,
4265
                                         texImage->ImageOffsets,
4266
                                         width, height, 1,
4267
                                         format, type, pixels, packing);
4268
      if (!success) {
4269
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
4270
      }
4271
   }
4272
 
4273
   _mesa_unmap_teximage_pbo(ctx, packing);
4274
}
4275
 
4276
 
4277
 
4278
/**
4279
 * This is the software fallback for Driver.TexImage3D()
4280
 * and Driver.CopyTexImage3D().
4281
 * \sa _mesa_store_teximage2d()
4282
 */
4283
void
4284
_mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
4285
                       GLint internalFormat,
4286
                       GLint width, GLint height, GLint depth, GLint border,
4287
                       GLenum format, GLenum type, const void *pixels,
4288
                       const struct gl_pixelstore_attrib *packing,
4289
                       struct gl_texture_object *texObj,
4290
                       struct gl_texture_image *texImage)
4291
{
4292
   GLuint sizeInBytes;
4293
   (void) border;
4294
 
4295
   /* allocate memory */
4296
   sizeInBytes = texture_size(texImage);
4297
   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
4298
   if (!texImage->Data) {
4299
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
4300
      return;
4301
   }
4302
 
4303
   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
4304
                                        type, pixels, packing, "glTexImage3D");
4305
   if (!pixels) {
4306
      /* Note: we check for a NULL image pointer here, _after_ we allocated
4307
       * memory for the texture.  That's what the GL spec calls for.
4308
       */
4309
      return;
4310
   }
4311
   else {
4312
      GLint dstRowStride = texture_row_stride(texImage);
4313
      GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
4314
                                         texImage->TexFormat,
4315
                                         texImage->Data,
4316
                                         0, 0, 0,  /* dstX/Y/Zoffset */
4317
                                         dstRowStride,
4318
                                         texImage->ImageOffsets,
4319
                                         width, height, depth,
4320
                                         format, type, pixels, packing);
4321
      if (!success) {
4322
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
4323
      }
4324
   }
4325
 
4326
   _mesa_unmap_teximage_pbo(ctx, packing);
4327
}
4328
 
4329
 
4330
 
4331
 
4332
/*
4333
 * This is the software fallback for Driver.TexSubImage1D()
4334
 * and Driver.CopyTexSubImage1D().
4335
 */
4336
void
4337
_mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
4338
                          GLint xoffset, GLint width,
4339
                          GLenum format, GLenum type, const void *pixels,
4340
                          const struct gl_pixelstore_attrib *packing,
4341
                          struct gl_texture_object *texObj,
4342
                          struct gl_texture_image *texImage)
4343
{
4344
   /* get pointer to src pixels (may be in a pbo which we'll map here) */
4345
   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
4346
                                        pixels, packing, "glTexSubImage1D");
4347
   if (!pixels)
4348
      return;
4349
 
4350
   {
4351
      const GLint dstRowStride = 0;
4352
      GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
4353
                                         texImage->TexFormat,
4354
                                         texImage->Data,
4355
                                         xoffset, 0, 0,  /* offsets */
4356
                                         dstRowStride,
4357
                                         texImage->ImageOffsets,
4358
                                         width, 1, 1,
4359
                                         format, type, pixels, packing);
4360
      if (!success) {
4361
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
4362
      }
4363
   }
4364
 
4365
   _mesa_unmap_teximage_pbo(ctx, packing);
4366
}
4367
 
4368
 
4369
 
4370
/**
4371
 * This is the software fallback for Driver.TexSubImage2D()
4372
 * and Driver.CopyTexSubImage2D().
4373
 */
4374
void
4375
_mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
4376
                          GLint xoffset, GLint yoffset,
4377
                          GLint width, GLint height,
4378
                          GLenum format, GLenum type, const void *pixels,
4379
                          const struct gl_pixelstore_attrib *packing,
4380
                          struct gl_texture_object *texObj,
4381
                          struct gl_texture_image *texImage)
4382
{
4383
   /* get pointer to src pixels (may be in a pbo which we'll map here) */
4384
   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
4385
                                        pixels, packing, "glTexSubImage2D");
4386
   if (!pixels)
4387
      return;
4388
 
4389
   {
4390
      GLint dstRowStride = texture_row_stride(texImage);
4391
      GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
4392
                                         texImage->TexFormat,
4393
                                         texImage->Data,
4394
                                         xoffset, yoffset, 0,
4395
                                         dstRowStride,
4396
                                         texImage->ImageOffsets,
4397
                                         width, height, 1,
4398
                                         format, type, pixels, packing);
4399
      if (!success) {
4400
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
4401
      }
4402
   }
4403
 
4404
   _mesa_unmap_teximage_pbo(ctx, packing);
4405
}
4406
 
4407
 
4408
/*
4409
 * This is the software fallback for Driver.TexSubImage3D().
4410
 * and Driver.CopyTexSubImage3D().
4411
 */
4412
void
4413
_mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
4414
                          GLint xoffset, GLint yoffset, GLint zoffset,
4415
                          GLint width, GLint height, GLint depth,
4416
                          GLenum format, GLenum type, const void *pixels,
4417
                          const struct gl_pixelstore_attrib *packing,
4418
                          struct gl_texture_object *texObj,
4419
                          struct gl_texture_image *texImage)
4420
{
4421
   /* get pointer to src pixels (may be in a pbo which we'll map here) */
4422
   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
4423
                                        type, pixels, packing,
4424
                                        "glTexSubImage3D");
4425
   if (!pixels)
4426
      return;
4427
 
4428
   {
4429
      GLint dstRowStride = texture_row_stride(texImage);
4430
      GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
4431
                                         texImage->TexFormat,
4432
                                         texImage->Data,
4433
                                         xoffset, yoffset, zoffset,
4434
                                         dstRowStride,
4435
                                         texImage->ImageOffsets,
4436
                                         width, height, depth,
4437
                                         format, type, pixels, packing);
4438
      if (!success) {
4439
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
4440
      }
4441
   }
4442
 
4443
   _mesa_unmap_teximage_pbo(ctx, packing);
4444
}
4445
 
4446
 
4447
/*
4448
 * Fallback for Driver.CompressedTexImage1D()
4449
 */
4450
void
4451
_mesa_store_compressed_teximage1d(struct gl_context *ctx,
4452
                                  GLenum target, GLint level,
4453
                                  GLint internalFormat,
4454
                                  GLint width, GLint border,
4455
                                  GLsizei imageSize, const GLvoid *data,
4456
                                  struct gl_texture_object *texObj,
4457
                                  struct gl_texture_image *texImage)
4458
{
4459
   /* this space intentionally left blank */
4460
   (void) ctx;
4461
   (void) target; (void) level;
4462
   (void) internalFormat;
4463
   (void) width; (void) border;
4464
   (void) imageSize; (void) data;
4465
   (void) texObj;
4466
   (void) texImage;
4467
}
4468
 
4469
 
4470
 
4471
/**
4472
 * Fallback for Driver.CompressedTexImage2D()
4473
 */
4474
void
4475
_mesa_store_compressed_teximage2d(struct gl_context *ctx,
4476
                                  GLenum target, GLint level,
4477
                                  GLint internalFormat,
4478
                                  GLint width, GLint height, GLint border,
4479
                                  GLsizei imageSize, const GLvoid *data,
4480
                                  struct gl_texture_object *texObj,
4481
                                  struct gl_texture_image *texImage)
4482
{
4483
   (void) width; (void) height; (void) border;
4484
 
4485
   /* This is pretty simple, basically just do a memcpy without worrying
4486
    * about the usual image unpacking or image transfer operations.
4487
    */
4488
   ASSERT(texObj);
4489
   ASSERT(texImage);
4490
   ASSERT(texImage->Width > 0);
4491
   ASSERT(texImage->Height > 0);
4492
   ASSERT(texImage->Depth == 1);
4493
   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
4494
 
4495
   /* allocate storage */
4496
   texImage->Data = _mesa_alloc_texmemory(imageSize);
4497
   if (!texImage->Data) {
4498
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
4499
      return;
4500
   }
4501
 
4502
   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
4503
                                                 &ctx->Unpack,
4504
                                                 "glCompressedTexImage2D");
4505
   if (!data)
4506
      return;
4507
 
4508
   /* copy the data */
4509
   memcpy(texImage->Data, data, imageSize);
4510
 
4511
   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
4512
}
4513
 
4514
 
4515
 
4516
/*
4517
 * Fallback for Driver.CompressedTexImage3D()
4518
 */
4519
void
4520
_mesa_store_compressed_teximage3d(struct gl_context *ctx,
4521
                                  GLenum target, GLint level,
4522
                                  GLint internalFormat,
4523
                                  GLint width, GLint height, GLint depth,
4524
                                  GLint border,
4525
                                  GLsizei imageSize, const GLvoid *data,
4526
                                  struct gl_texture_object *texObj,
4527
                                  struct gl_texture_image *texImage)
4528
{
4529
   /* this space intentionally left blank */
4530
   (void) ctx;
4531
   (void) target; (void) level;
4532
   (void) internalFormat;
4533
   (void) width; (void) height; (void) depth;
4534
   (void) border;
4535
   (void) imageSize; (void) data;
4536
   (void) texObj;
4537
   (void) texImage;
4538
}
4539
 
4540
 
4541
 
4542
/**
4543
 * Fallback for Driver.CompressedTexSubImage1D()
4544
 */
4545
void
4546
_mesa_store_compressed_texsubimage1d(struct gl_context *ctx, GLenum target,
4547
                                     GLint level,
4548
                                     GLint xoffset, GLsizei width,
4549
                                     GLenum format,
4550
                                     GLsizei imageSize, const GLvoid *data,
4551
                                     struct gl_texture_object *texObj,
4552
                                     struct gl_texture_image *texImage)
4553
{
4554
   /* there are no compressed 1D texture formats yet */
4555
   (void) ctx;
4556
   (void) target; (void) level;
4557
   (void) xoffset; (void) width;
4558
   (void) format;
4559
   (void) imageSize; (void) data;
4560
   (void) texObj;
4561
   (void) texImage;
4562
}
4563
 
4564
 
4565
/**
4566
 * Fallback for Driver.CompressedTexSubImage2D()
4567
 */
4568
void
4569
_mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
4570
                                     GLint level,
4571
                                     GLint xoffset, GLint yoffset,
4572
                                     GLsizei width, GLsizei height,
4573
                                     GLenum format,
4574
                                     GLsizei imageSize, const GLvoid *data,
4575
                                     struct gl_texture_object *texObj,
4576
                                     struct gl_texture_image *texImage)
4577
{
4578
   GLint bytesPerRow, destRowStride, srcRowStride;
4579
   GLint i, rows;
4580
   GLubyte *dest;
4581
   const GLubyte *src;
4582
   const gl_format texFormat = texImage->TexFormat;
4583
   const GLint destWidth = texImage->Width;
4584
   GLuint bw, bh;
4585
 
4586
   _mesa_get_format_block_size(texFormat, &bw, &bh);
4587
 
4588
   (void) level;
4589
   (void) format;
4590
 
4591
   /* these should have been caught sooner */
4592
   ASSERT((width % bw) == 0 || width == 2 || width == 1);
4593
   ASSERT((height % bh) == 0 || height == 2 || height == 1);
4594
   ASSERT((xoffset % bw) == 0);
4595
   ASSERT((yoffset % bh) == 0);
4596
 
4597
   /* get pointer to src pixels (may be in a pbo which we'll map here) */
4598
   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
4599
                                                 &ctx->Unpack,
4600
                                                 "glCompressedTexSubImage2D");
4601
   if (!data)
4602
      return;
4603
 
4604
   srcRowStride = _mesa_format_row_stride(texFormat, width);
4605
   src = (const GLubyte *) data;
4606
 
4607
   destRowStride = _mesa_format_row_stride(texFormat, destWidth);
4608
   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
4609
                                         texFormat, destWidth,
4610
                                         (GLubyte *) texImage->Data);
4611
 
4612
   bytesPerRow = srcRowStride;  /* bytes per row of blocks */
4613
   rows = height / bh;  /* rows in blocks */
4614
 
4615
   /* copy rows of blocks */
4616
   for (i = 0; i < rows; i++) {
4617
      memcpy(dest, src, bytesPerRow);
4618
      dest += destRowStride;
4619
      src += srcRowStride;
4620
   }
4621
 
4622
   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
4623
}
4624
 
4625
 
4626
/**
4627
 * Fallback for Driver.CompressedTexSubImage3D()
4628
 */
4629
void
4630
_mesa_store_compressed_texsubimage3d(struct gl_context *ctx, GLenum target,
4631
                                GLint level,
4632
                                GLint xoffset, GLint yoffset, GLint zoffset,
4633
                                GLsizei width, GLsizei height, GLsizei depth,
4634
                                GLenum format,
4635
                                GLsizei imageSize, const GLvoid *data,
4636
                                struct gl_texture_object *texObj,
4637
                                struct gl_texture_image *texImage)
4638
{
4639
   /* there are no compressed 3D texture formats yet */
4640
   (void) ctx;
4641
   (void) target; (void) level;
4642
   (void) xoffset; (void) yoffset; (void) zoffset;
4643
   (void) width; (void) height; (void) depth;
4644
   (void) format;
4645
   (void) imageSize; (void) data;
4646
   (void) texObj;
4647
   (void) texImage;
4648
}