Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5
 * Copyright (c) 2008-2009  VMware, Inc.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 * copy of this software and associated documentation files (the "Software"),
9
 * to deal in the Software without restriction, including without limitation
10
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
 * and/or sell copies of the Software, and to permit persons to whom the
12
 * Software is furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included
15
 * in all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * 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.TexImage = _mesa_store_teximage;
41
 *   ctx->Driver.TexSubImage = _mesa_store_texsubimage;
42
 *   etc...
43
 *
44
 * Texture image processing is actually kind of complicated.  We have to do:
45
 *    Format/type conversions
46
 *    pixel unpacking
47
 *    pixel transfer (scale, bais, lookup, etc)
48
 *
49
 * These functions can handle most everything, including processing full
50
 * images and sub-images.
51
 */
52
 
53
 
54
#include "glheader.h"
55
#include "bufferobj.h"
56
#include "format_pack.h"
57
#include "format_utils.h"
58
#include "image.h"
59
#include "macros.h"
60
#include "mipmap.h"
61
#include "mtypes.h"
62
#include "pack.h"
63
#include "pbo.h"
64
#include "imports.h"
65
#include "texcompress.h"
66
#include "texcompress_fxt1.h"
67
#include "texcompress_rgtc.h"
68
#include "texcompress_s3tc.h"
69
#include "texcompress_etc.h"
70
#include "texcompress_bptc.h"
71
#include "teximage.h"
72
#include "texstore.h"
73
#include "enums.h"
74
#include "glformats.h"
75
#include "pixeltransfer.h"
76
#include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
77
#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
78
 
79
 
80
enum {
81
   ZERO = 4,
82
   ONE = 5
83
};
84
 
85
 
86
/**
87
 * Texture image storage function.
88
 */
89
typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
90
static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
91
static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
92
static const GLubyte map_1032[6] = { 1, 0, 3, 2, ZERO, ONE };
93
 
94
 
95
/**
96
 * Teximage storage routine for when a simple memcpy will do.
97
 * No pixel transfer operations or special texel encodings allowed.
98
 * 1D, 2D and 3D images supported.
99
 */
100
static void
101
memcpy_texture(struct gl_context *ctx,
102
	       GLuint dimensions,
103
               mesa_format dstFormat,
104
               GLint dstRowStride,
105
               GLubyte **dstSlices,
106
               GLint srcWidth, GLint srcHeight, GLint srcDepth,
107
               GLenum srcFormat, GLenum srcType,
108
               const GLvoid *srcAddr,
109
               const struct gl_pixelstore_attrib *srcPacking)
110
{
111
   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
112
                                                     srcFormat, srcType);
113
   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
114
                                      srcWidth, srcHeight, srcFormat, srcType);
115
   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
116
        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
117
   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
118
   const GLint bytesPerRow = srcWidth * texelBytes;
119
 
120
   if (dstRowStride == srcRowStride &&
121
       dstRowStride == bytesPerRow) {
122
      /* memcpy image by image */
123
      GLint img;
124
      for (img = 0; img < srcDepth; img++) {
125
         GLubyte *dstImage = dstSlices[img];
126
         memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
127
         srcImage += srcImageStride;
128
      }
129
   }
130
   else {
131
      /* memcpy row by row */
132
      GLint img, row;
133
      for (img = 0; img < srcDepth; img++) {
134
         const GLubyte *srcRow = srcImage;
135
         GLubyte *dstRow = dstSlices[img];
136
         for (row = 0; row < srcHeight; row++) {
137
            memcpy(dstRow, srcRow, bytesPerRow);
138
            dstRow += dstRowStride;
139
            srcRow += srcRowStride;
140
         }
141
         srcImage += srcImageStride;
142
      }
143
   }
144
}
145
 
146
 
147
/**
148
 * Store a 32-bit integer or float depth component texture image.
149
 */
150
static GLboolean
151
_mesa_texstore_z32(TEXSTORE_PARAMS)
152
{
153
   const GLuint depthScale = 0xffffffff;
154
   GLenum dstType;
155
   (void) dims;
156
   assert(dstFormat == MESA_FORMAT_Z_UNORM32 ||
157
          dstFormat == MESA_FORMAT_Z_FLOAT32);
158
   assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
159
 
160
   if (dstFormat == MESA_FORMAT_Z_UNORM32)
161
      dstType = GL_UNSIGNED_INT;
162
   else
163
      dstType = GL_FLOAT;
164
 
165
   {
166
      /* general path */
167
      GLint img, row;
168
      for (img = 0; img < srcDepth; img++) {
169
         GLubyte *dstRow = dstSlices[img];
170
         for (row = 0; row < srcHeight; row++) {
171
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
172
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
173
            _mesa_unpack_depth_span(ctx, srcWidth,
174
                                    dstType, dstRow,
175
                                    depthScale, srcType, src, srcPacking);
176
            dstRow += dstRowStride;
177
         }
178
      }
179
   }
180
   return GL_TRUE;
181
}
182
 
183
 
184
/**
185
 * Store a 24-bit integer depth component texture image.
186
 */
187
static GLboolean
188
_mesa_texstore_x8_z24(TEXSTORE_PARAMS)
189
{
190
   const GLuint depthScale = 0xffffff;
191
 
192
   (void) dims;
193
   assert(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
194
 
195
   {
196
      /* general path */
197
      GLint img, row;
198
      for (img = 0; img < srcDepth; img++) {
199
         GLubyte *dstRow = dstSlices[img];
200
         for (row = 0; row < srcHeight; row++) {
201
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
202
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
203
            _mesa_unpack_depth_span(ctx, srcWidth,
204
                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
205
                                    depthScale, srcType, src, srcPacking);
206
            dstRow += dstRowStride;
207
         }
208
      }
209
   }
210
   return GL_TRUE;
211
}
212
 
213
 
214
/**
215
 * Store a 24-bit integer depth component texture image.
216
 */
217
static GLboolean
218
_mesa_texstore_z24_x8(TEXSTORE_PARAMS)
219
{
220
   const GLuint depthScale = 0xffffff;
221
 
222
   (void) dims;
223
   assert(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
224
 
225
   {
226
      /* general path */
227
      GLint img, row;
228
      for (img = 0; img < srcDepth; img++) {
229
         GLubyte *dstRow = dstSlices[img];
230
         for (row = 0; row < srcHeight; row++) {
231
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
232
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
233
            GLuint *dst = (GLuint *) dstRow;
234
            GLint i;
235
            _mesa_unpack_depth_span(ctx, srcWidth,
236
                                    GL_UNSIGNED_INT, dst,
237
                                    depthScale, srcType, src, srcPacking);
238
            for (i = 0; i < srcWidth; i++)
239
               dst[i] <<= 8;
240
            dstRow += dstRowStride;
241
         }
242
      }
243
   }
244
   return GL_TRUE;
245
}
246
 
247
 
248
/**
249
 * Store a 16-bit integer depth component texture image.
250
 */
251
static GLboolean
252
_mesa_texstore_z16(TEXSTORE_PARAMS)
253
{
254
   const GLuint depthScale = 0xffff;
255
   (void) dims;
256
   assert(dstFormat == MESA_FORMAT_Z_UNORM16);
257
   assert(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
258
 
259
   {
260
      /* general path */
261
      GLint img, row;
262
      for (img = 0; img < srcDepth; img++) {
263
         GLubyte *dstRow = dstSlices[img];
264
         for (row = 0; row < srcHeight; row++) {
265
            const GLvoid *src = _mesa_image_address(dims, srcPacking,
266
                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
267
            GLushort *dst16 = (GLushort *) dstRow;
268
            _mesa_unpack_depth_span(ctx, srcWidth,
269
                                    GL_UNSIGNED_SHORT, dst16, depthScale,
270
                                    srcType, src, srcPacking);
271
            dstRow += dstRowStride;
272
         }
273
      }
274
   }
275
   return GL_TRUE;
276
}
277
 
278
 
279
/**
280
 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
281
 */
282
static GLboolean
283
_mesa_texstore_ycbcr(TEXSTORE_PARAMS)
284
{
285
   const GLboolean littleEndian = _mesa_little_endian();
286
 
287
   (void) ctx; (void) dims; (void) baseInternalFormat;
288
 
289
   assert((dstFormat == MESA_FORMAT_YCBCR) ||
290
          (dstFormat == MESA_FORMAT_YCBCR_REV));
291
   assert(_mesa_get_format_bytes(dstFormat) == 2);
292
   assert(ctx->Extensions.MESA_ycbcr_texture);
293
   assert(srcFormat == GL_YCBCR_MESA);
294
   assert((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
295
          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
296
   assert(baseInternalFormat == GL_YCBCR_MESA);
297
 
298
   /* always just memcpy since no pixel transfer ops apply */
299
   memcpy_texture(ctx, dims,
300
                  dstFormat,
301
                  dstRowStride, dstSlices,
302
                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
303
                  srcAddr, srcPacking);
304
 
305
   /* Check if we need byte swapping */
306
   /* XXX the logic here _might_ be wrong */
307
   if (srcPacking->SwapBytes ^
308
       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
309
       (dstFormat == MESA_FORMAT_YCBCR_REV) ^
310
       !littleEndian) {
311
      GLint img, row;
312
      for (img = 0; img < srcDepth; img++) {
313
         GLubyte *dstRow = dstSlices[img];
314
         for (row = 0; row < srcHeight; row++) {
315
            _mesa_swap2((GLushort *) dstRow, srcWidth);
316
            dstRow += dstRowStride;
317
         }
318
      }
319
   }
320
   return GL_TRUE;
321
}
322
 
323
 
324
/**
325
 * Store a combined depth/stencil texture image.
326
 */
327
static GLboolean
328
_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
329
{
330
   const GLuint depthScale = 0xffffff;
331
   const GLint srcRowStride
332
      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
333
   GLint img, row;
334
   GLuint *depth = malloc(srcWidth * sizeof(GLuint));
335
   GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
336
 
337
   assert(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
338
   assert(srcFormat == GL_DEPTH_STENCIL_EXT ||
339
          srcFormat == GL_DEPTH_COMPONENT ||
340
          srcFormat == GL_STENCIL_INDEX);
341
   assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
342
          srcType == GL_UNSIGNED_INT_24_8_EXT ||
343
          srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
344
 
345
   if (!depth || !stencil) {
346
      free(depth);
347
      free(stencil);
348
      return GL_FALSE;
349
   }
350
 
351
   /* In case we only upload depth we need to preserve the stencil */
352
   for (img = 0; img < srcDepth; img++) {
353
      GLuint *dstRow = (GLuint *) dstSlices[img];
354
      const GLubyte *src
355
         = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
356
               srcWidth, srcHeight,
357
               srcFormat, srcType,
358
               img, 0, 0);
359
      for (row = 0; row < srcHeight; row++) {
360
         GLint i;
361
         GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
362
 
363
         if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
364
            keepstencil = GL_TRUE;
365
         }
366
         else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
367
            keepdepth = GL_TRUE;
368
         }
369
 
370
         if (keepdepth == GL_FALSE)
371
            /* the 24 depth bits will be in the low position: */
372
            _mesa_unpack_depth_span(ctx, srcWidth,
373
                                    GL_UNSIGNED_INT, /* dst type */
374
                                    keepstencil ? depth : dstRow, /* dst addr */
375
                                    depthScale,
376
                                    srcType, src, srcPacking);
377
 
378
         if (keepstencil == GL_FALSE)
379
            /* get the 8-bit stencil values */
380
            _mesa_unpack_stencil_span(ctx, srcWidth,
381
                                      GL_UNSIGNED_BYTE, /* dst type */
382
                                      stencil, /* dst addr */
383
                                      srcType, src, srcPacking,
384
                                      ctx->_ImageTransferState);
385
 
386
         for (i = 0; i < srcWidth; i++) {
387
            if (keepstencil)
388
               dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
389
            else
390
               dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
391
         }
392
         src += srcRowStride;
393
         dstRow += dstRowStride / sizeof(GLuint);
394
      }
395
   }
396
 
397
   free(depth);
398
   free(stencil);
399
   return GL_TRUE;
400
}
401
 
402
 
403
/**
404
 * Store a combined depth/stencil texture image.
405
 */
406
static GLboolean
407
_mesa_texstore_s8_z24(TEXSTORE_PARAMS)
408
{
409
   const GLuint depthScale = 0xffffff;
410
   const GLint srcRowStride
411
      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
412
   GLint img, row;
413
   GLuint *depth;
414
   GLubyte *stencil;
415
 
416
   assert(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
417
   assert(srcFormat == GL_DEPTH_STENCIL_EXT ||
418
          srcFormat == GL_DEPTH_COMPONENT ||
419
          srcFormat == GL_STENCIL_INDEX);
420
   assert(srcFormat != GL_DEPTH_STENCIL_EXT ||
421
          srcType == GL_UNSIGNED_INT_24_8_EXT ||
422
          srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
423
 
424
   depth = malloc(srcWidth * sizeof(GLuint));
425
   stencil = malloc(srcWidth * sizeof(GLubyte));
426
 
427
   if (!depth || !stencil) {
428
      free(depth);
429
      free(stencil);
430
      return GL_FALSE;
431
   }
432
 
433
   for (img = 0; img < srcDepth; img++) {
434
      GLuint *dstRow = (GLuint *) dstSlices[img];
435
      const GLubyte *src
436
	 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
437
						srcWidth, srcHeight,
438
						srcFormat, srcType,
439
						img, 0, 0);
440
      for (row = 0; row < srcHeight; row++) {
441
	 GLint i;
442
	 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
443
 
444
	 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
445
	    keepstencil = GL_TRUE;
446
	 }
447
         else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
448
	    keepdepth = GL_TRUE;
449
	 }
450
 
451
	 if (keepdepth == GL_FALSE)
452
	    /* the 24 depth bits will be in the low position: */
453
	    _mesa_unpack_depth_span(ctx, srcWidth,
454
				    GL_UNSIGNED_INT, /* dst type */
455
				    keepstencil ? depth : dstRow, /* dst addr */
456
				    depthScale,
457
				    srcType, src, srcPacking);
458
 
459
	 if (keepstencil == GL_FALSE)
460
	    /* get the 8-bit stencil values */
461
	    _mesa_unpack_stencil_span(ctx, srcWidth,
462
				      GL_UNSIGNED_BYTE, /* dst type */
463
				      stencil, /* dst addr */
464
				      srcType, src, srcPacking,
465
				      ctx->_ImageTransferState);
466
 
467
	 /* merge stencil values into depth values */
468
	 for (i = 0; i < srcWidth; i++) {
469
	    if (keepstencil)
470
	       dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
471
	    else
472
	       dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
473
 
474
	 }
475
	 src += srcRowStride;
476
	 dstRow += dstRowStride / sizeof(GLuint);
477
      }
478
   }
479
 
480
   free(depth);
481
   free(stencil);
482
 
483
   return GL_TRUE;
484
}
485
 
486
 
487
/**
488
 * Store simple 8-bit/value stencil texture data.
489
 */
490
static GLboolean
491
_mesa_texstore_s8(TEXSTORE_PARAMS)
492
{
493
   assert(dstFormat == MESA_FORMAT_S_UINT8);
494
   assert(srcFormat == GL_STENCIL_INDEX);
495
 
496
   {
497
      const GLint srcRowStride
498
	 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
499
      GLint img, row;
500
      GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
501
 
502
      if (!stencil)
503
         return GL_FALSE;
504
 
505
      for (img = 0; img < srcDepth; img++) {
506
         GLubyte *dstRow = dstSlices[img];
507
         const GLubyte *src
508
            = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
509
                                                   srcWidth, srcHeight,
510
                                                   srcFormat, srcType,
511
                                                   img, 0, 0);
512
         for (row = 0; row < srcHeight; row++) {
513
            GLint i;
514
 
515
            /* get the 8-bit stencil values */
516
            _mesa_unpack_stencil_span(ctx, srcWidth,
517
                                      GL_UNSIGNED_BYTE, /* dst type */
518
                                      stencil, /* dst addr */
519
                                      srcType, src, srcPacking,
520
                                      ctx->_ImageTransferState);
521
            /* merge stencil values into depth values */
522
            for (i = 0; i < srcWidth; i++)
523
               dstRow[i] = stencil[i];
524
 
525
            src += srcRowStride;
526
            dstRow += dstRowStride / sizeof(GLubyte);
527
         }
528
      }
529
 
530
      free(stencil);
531
   }
532
 
533
   return GL_TRUE;
534
}
535
 
536
 
537
static GLboolean
538
_mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
539
{
540
   GLint img, row;
541
   const GLint srcRowStride
542
      = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
543
      / sizeof(uint64_t);
544
 
545
   assert(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
546
   assert(srcFormat == GL_DEPTH_STENCIL ||
547
          srcFormat == GL_DEPTH_COMPONENT ||
548
          srcFormat == GL_STENCIL_INDEX);
549
   assert(srcFormat != GL_DEPTH_STENCIL ||
550
          srcType == GL_UNSIGNED_INT_24_8 ||
551
          srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
552
 
553
   /* In case we only upload depth we need to preserve the stencil */
554
   for (img = 0; img < srcDepth; img++) {
555
      uint64_t *dstRow = (uint64_t *) dstSlices[img];
556
      const uint64_t *src
557
         = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
558
               srcWidth, srcHeight,
559
               srcFormat, srcType,
560
               img, 0, 0);
561
      for (row = 0; row < srcHeight; row++) {
562
         /* The unpack functions with:
563
          *    dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
564
          * only write their own dword, so the other dword (stencil
565
          * or depth) is preserved. */
566
         if (srcFormat != GL_STENCIL_INDEX)
567
            _mesa_unpack_depth_span(ctx, srcWidth,
568
                                    GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
569
                                    dstRow, /* dst addr */
570
                                    ~0U, srcType, src, srcPacking);
571
 
572
         if (srcFormat != GL_DEPTH_COMPONENT)
573
            _mesa_unpack_stencil_span(ctx, srcWidth,
574
                                      GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
575
                                      dstRow, /* dst addr */
576
                                      srcType, src, srcPacking,
577
                                      ctx->_ImageTransferState);
578
 
579
         src += srcRowStride;
580
         dstRow += dstRowStride / sizeof(uint64_t);
581
      }
582
   }
583
   return GL_TRUE;
584
}
585
 
586
static GLboolean
587
texstore_depth_stencil(TEXSTORE_PARAMS)
588
{
589
   static StoreTexImageFunc table[MESA_FORMAT_COUNT];
590
   static GLboolean initialized = GL_FALSE;
591
 
592
   if (!initialized) {
593
      memset(table, 0, sizeof table);
594
 
595
      table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8;
596
      table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24;
597
      table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16;
598
      table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24;
599
      table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8;
600
      table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32;
601
      table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8;
602
      table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32;
603
      table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8;
604
 
605
      initialized = GL_TRUE;
606
   }
607
 
608
   assert(table[dstFormat]);
609
   return table[dstFormat](ctx, dims, baseInternalFormat,
610
                           dstFormat, dstRowStride, dstSlices,
611
                           srcWidth, srcHeight, srcDepth,
612
                           srcFormat, srcType, srcAddr, srcPacking);
613
}
614
 
615
static GLboolean
616
texstore_compressed(TEXSTORE_PARAMS)
617
{
618
   static StoreTexImageFunc table[MESA_FORMAT_COUNT];
619
   static GLboolean initialized = GL_FALSE;
620
 
621
   if (!initialized) {
622
      memset(table, 0, sizeof table);
623
 
624
      table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
625
      table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
626
      table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
627
      table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
628
      table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
629
      table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
630
      table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
631
      table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
632
      table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
633
      table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
634
      table[MESA_FORMAT_R_RGTC1_UNORM] = _mesa_texstore_red_rgtc1;
635
      table[MESA_FORMAT_R_RGTC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
636
      table[MESA_FORMAT_RG_RGTC2_UNORM] = _mesa_texstore_rg_rgtc2;
637
      table[MESA_FORMAT_RG_RGTC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
638
      table[MESA_FORMAT_L_LATC1_UNORM] = _mesa_texstore_red_rgtc1;
639
      table[MESA_FORMAT_L_LATC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
640
      table[MESA_FORMAT_LA_LATC2_UNORM] = _mesa_texstore_rg_rgtc2;
641
      table[MESA_FORMAT_LA_LATC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
642
      table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
643
      table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8;
644
      table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8;
645
      table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac;
646
      table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac;
647
      table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac;
648
      table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac;
649
      table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac;
650
      table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac;
651
      table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
652
         _mesa_texstore_etc2_rgb8_punchthrough_alpha1;
653
      table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
654
         _mesa_texstore_etc2_srgb8_punchthrough_alpha1;
655
 
656
      table[MESA_FORMAT_BPTC_RGBA_UNORM] =
657
         _mesa_texstore_bptc_rgba_unorm;
658
      table[MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM] =
659
         _mesa_texstore_bptc_rgba_unorm;
660
      table[MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT] =
661
         _mesa_texstore_bptc_rgb_signed_float;
662
      table[MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT] =
663
         _mesa_texstore_bptc_rgb_unsigned_float;
664
 
665
      initialized = GL_TRUE;
666
   }
667
 
668
   assert(table[dstFormat]);
669
   return table[dstFormat](ctx, dims, baseInternalFormat,
670
                           dstFormat, dstRowStride, dstSlices,
671
                           srcWidth, srcHeight, srcDepth,
672
                           srcFormat, srcType, srcAddr, srcPacking);
673
}
674
 
675
static GLboolean
676
texstore_rgba(TEXSTORE_PARAMS)
677
{
678
   void *tempImage = NULL, *tempRGBA = NULL;
679
   int srcRowStride, img;
680
   GLubyte *src, *dst;
681
   uint32_t srcMesaFormat;
682
   uint8_t rebaseSwizzle[4];
683
   bool needRebase;
684
   bool transferOpsDone = false;
685
 
686
   /* We have to handle MESA_FORMAT_YCBCR manually because it is a special case
687
    * and _mesa_format_convert does not support it. In this case the we only
688
    * allow conversions between YCBCR formats and it is mostly a memcpy.
689
    */
690
   if (dstFormat == MESA_FORMAT_YCBCR || dstFormat == MESA_FORMAT_YCBCR_REV) {
691
      return _mesa_texstore_ycbcr(ctx, dims, baseInternalFormat,
692
                                  dstFormat, dstRowStride, dstSlices,
693
                                  srcWidth, srcHeight, srcDepth,
694
                                  srcFormat, srcType, srcAddr,
695
                                  srcPacking);
696
   }
697
 
698
   /* We have to deal with GL_COLOR_INDEX manually because
699
    * _mesa_format_convert does not handle this format. So what we do here is
700
    * convert it to RGBA ubyte first and then convert from that to dst as usual.
701
    */
702
   if (srcFormat == GL_COLOR_INDEX) {
703
      /* Notice that this will already handle byte swapping if necessary */
704
      tempImage =
705
         _mesa_unpack_color_index_to_rgba_ubyte(ctx, dims,
706
                                                srcAddr, srcFormat, srcType,
707
                                                srcWidth, srcHeight, srcDepth,
708
                                                srcPacking,
709
                                                ctx->_ImageTransferState);
710
      if (!tempImage)
711
         return GL_FALSE;
712
 
713
      /* _mesa_unpack_color_index_to_rgba_ubyte has handled transferops
714
       * if needed.
715
       */
716
      transferOpsDone = true;
717
 
718
      /* Now we only have to adjust our src info for a conversion from
719
       * the RGBA ubyte and then we continue as usual.
720
       */
721
      srcAddr = tempImage;
722
      srcFormat = GL_RGBA;
723
      srcType = GL_UNSIGNED_BYTE;
724
   } else if (srcPacking->SwapBytes) {
725
      /* We have to handle byte-swapping scenarios before calling
726
       * _mesa_format_convert
727
       */
728
      GLint swapSize = _mesa_sizeof_packed_type(srcType);
729
      if (swapSize == 2 || swapSize == 4) {
730
         int bytesPerPixel = _mesa_bytes_per_pixel(srcFormat, srcType);
731
         int swapsPerPixel = bytesPerPixel / swapSize;
732
         int elementCount = srcWidth * srcHeight * srcDepth;
733
         assert(bytesPerPixel % swapSize == 0);
734
         tempImage = malloc(elementCount * bytesPerPixel);
735
         if (!tempImage)
736
            return GL_FALSE;
737
         if (swapSize == 2)
738
            _mesa_swap2_copy(tempImage, (GLushort *) srcAddr,
739
                             elementCount * swapsPerPixel);
740
         else
741
            _mesa_swap4_copy(tempImage, (GLuint *) srcAddr,
742
                             elementCount * swapsPerPixel);
743
         srcAddr = tempImage;
744
      }
745
   }
746
 
747
   srcRowStride =
748
      _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
749
 
750
   srcMesaFormat = _mesa_format_from_format_and_type(srcFormat, srcType);
751
   dstFormat = _mesa_get_srgb_format_linear(dstFormat);
752
 
753
   /* If we have transferOps then we need to convert to RGBA float first,
754
      then apply transferOps, then do the conversion to dst
755
    */
756
   if (!transferOpsDone &&
757
       _mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
758
      /* Allocate RGBA float image */
759
      int elementCount = srcWidth * srcHeight * srcDepth;
760
      tempRGBA = malloc(4 * elementCount * sizeof(float));
761
      if (!tempRGBA) {
762
         free(tempImage);
763
         free(tempRGBA);
764
         return GL_FALSE;
765
      }
766
 
767
      /* Convert from src to RGBA float */
768
      src = (GLubyte *) srcAddr;
769
      dst = (GLubyte *) tempRGBA;
770
      for (img = 0; img < srcDepth; img++) {
771
         _mesa_format_convert(dst, RGBA32_FLOAT, 4 * srcWidth * sizeof(float),
772
                              src, srcMesaFormat, srcRowStride,
773
                              srcWidth, srcHeight, NULL);
774
         src += srcHeight * srcRowStride;
775
         dst += srcHeight * 4 * srcWidth * sizeof(float);
776
      }
777
 
778
      /* Apply transferOps */
779
      _mesa_apply_rgba_transfer_ops(ctx, ctx->_ImageTransferState, elementCount,
780
                                    (float(*)[4]) tempRGBA);
781
 
782
      /* Now we have to adjust our src info for a conversion from
783
       * the RGBA float image and then we continue as usual.
784
       */
785
      srcAddr = tempRGBA;
786
      srcFormat = GL_RGBA;
787
      srcType = GL_FLOAT;
788
      srcRowStride = srcWidth * 4 * sizeof(float);
789
      srcMesaFormat = RGBA32_FLOAT;
790
   }
791
 
792
   src = (GLubyte *)
793
      _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
794
                          srcFormat, srcType, 0, 0, 0);
795
 
796
   if (_mesa_get_format_base_format(dstFormat) != baseInternalFormat) {
797
      needRebase =
798
         _mesa_compute_rgba2base2rgba_component_mapping(baseInternalFormat,
799
                                                        rebaseSwizzle);
800
   } else {
801
      needRebase = false;
802
   }
803
 
804
   for (img = 0; img < srcDepth; img++) {
805
      _mesa_format_convert(dstSlices[img], dstFormat, dstRowStride,
806
                           src, srcMesaFormat, srcRowStride,
807
                           srcWidth, srcHeight,
808
                           needRebase ? rebaseSwizzle : NULL);
809
      src += srcHeight * srcRowStride;
810
   }
811
 
812
   free(tempImage);
813
   free(tempRGBA);
814
 
815
   return GL_TRUE;
816
}
817
 
818
GLboolean
819
_mesa_texstore_needs_transfer_ops(struct gl_context *ctx,
820
                                  GLenum baseInternalFormat,
821
                                  mesa_format dstFormat)
822
{
823
   GLenum dstType;
824
 
825
   /* There are different rules depending on the base format. */
826
   switch (baseInternalFormat) {
827
   case GL_DEPTH_COMPONENT:
828
   case GL_DEPTH_STENCIL:
829
      return ctx->Pixel.DepthScale != 1.0f ||
830
             ctx->Pixel.DepthBias != 0.0f;
831
 
832
   case GL_STENCIL_INDEX:
833
      return GL_FALSE;
834
 
835
   default:
836
      /* Color formats.
837
       * Pixel transfer ops (scale, bias, table lookup) do not apply
838
       * to integer formats.
839
       */
840
      dstType = _mesa_get_format_datatype(dstFormat);
841
 
842
      return dstType != GL_INT && dstType != GL_UNSIGNED_INT &&
843
             ctx->_ImageTransferState;
844
   }
845
}
846
 
847
 
848
GLboolean
849
_mesa_texstore_can_use_memcpy(struct gl_context *ctx,
850
                              GLenum baseInternalFormat, mesa_format dstFormat,
851
                              GLenum srcFormat, GLenum srcType,
852
                              const struct gl_pixelstore_attrib *srcPacking)
853
{
854
   if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
855
      return GL_FALSE;
856
   }
857
 
858
   /* The base internal format and the base Mesa format must match. */
859
   if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {
860
      return GL_FALSE;
861
   }
862
 
863
   /* The Mesa format must match the input format and type. */
864
   if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
865
                                             srcPacking->SwapBytes)) {
866
      return GL_FALSE;
867
   }
868
 
869
   /* Depth texture data needs clamping in following cases:
870
    * - Floating point dstFormat with signed srcType: clamp to [0.0, 1.0].
871
    * - Fixed point dstFormat with signed srcType: clamp to [0, 2^n -1].
872
    *
873
    * All the cases except one (float dstFormat with float srcType) are ruled
874
    * out by _mesa_format_matches_format_and_type() check above. Handle the
875
    * remaining case here.
876
    */
877
   if ((baseInternalFormat == GL_DEPTH_COMPONENT ||
878
        baseInternalFormat == GL_DEPTH_STENCIL) &&
879
       (srcType == GL_FLOAT ||
880
        srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)) {
881
      return GL_FALSE;
882
   }
883
 
884
   return GL_TRUE;
885
}
886
 
887
static GLboolean
888
_mesa_texstore_memcpy(TEXSTORE_PARAMS)
889
{
890
   if (!_mesa_texstore_can_use_memcpy(ctx, baseInternalFormat, dstFormat,
891
                                      srcFormat, srcType, srcPacking)) {
892
      return GL_FALSE;
893
   }
894
 
895
   memcpy_texture(ctx, dims,
896
                  dstFormat,
897
                  dstRowStride, dstSlices,
898
                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
899
                  srcAddr, srcPacking);
900
   return GL_TRUE;
901
}
902
/**
903
 * Store user data into texture memory.
904
 * Called via glTex[Sub]Image1/2/3D()
905
 * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
906
 */
907
GLboolean
908
_mesa_texstore(TEXSTORE_PARAMS)
909
{
910
   if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat,
911
                             dstFormat,
912
                             dstRowStride, dstSlices,
913
                             srcWidth, srcHeight, srcDepth,
914
                             srcFormat, srcType, srcAddr, srcPacking)) {
915
      return GL_TRUE;
916
   }
917
 
918
   if (_mesa_is_depth_or_stencil_format(baseInternalFormat)) {
919
      return texstore_depth_stencil(ctx, dims, baseInternalFormat,
920
                                    dstFormat, dstRowStride, dstSlices,
921
                                    srcWidth, srcHeight, srcDepth,
922
                                    srcFormat, srcType, srcAddr, srcPacking);
923
   } else if (_mesa_is_format_compressed(dstFormat)) {
924
      return texstore_compressed(ctx, dims, baseInternalFormat,
925
                                 dstFormat, dstRowStride, dstSlices,
926
                                 srcWidth, srcHeight, srcDepth,
927
                                 srcFormat, srcType, srcAddr, srcPacking);
928
   } else {
929
      return texstore_rgba(ctx, dims, baseInternalFormat,
930
                           dstFormat, dstRowStride, dstSlices,
931
                           srcWidth, srcHeight, srcDepth,
932
                           srcFormat, srcType, srcAddr, srcPacking);
933
   }
934
}
935
 
936
 
937
/**
938
 * Normally, we'll only _write_ texel data to a texture when we map it.
939
 * But if the user is providing depth or stencil values and the texture
940
 * image is a combined depth/stencil format, we'll actually read from
941
 * the texture buffer too (in order to insert the depth or stencil values.
942
 * \param userFormat  the user-provided image format
943
 * \param texFormat  the destination texture format
944
 */
945
static GLbitfield
946
get_read_write_mode(GLenum userFormat, mesa_format texFormat)
947
{
948
   if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
949
       && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
950
      return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
951
   else
952
      return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
953
}
954
 
955
 
956
/**
957
 * Helper function for storing 1D, 2D, 3D whole and subimages into texture
958
 * memory.
959
 * The source of the image data may be user memory or a PBO.  In the later
960
 * case, we'll map the PBO, copy from it, then unmap it.
961
 */
962
static void
963
store_texsubimage(struct gl_context *ctx,
964
                  struct gl_texture_image *texImage,
965
                  GLint xoffset, GLint yoffset, GLint zoffset,
966
                  GLint width, GLint height, GLint depth,
967
                  GLenum format, GLenum type, const GLvoid *pixels,
968
                  const struct gl_pixelstore_attrib *packing,
969
                  const char *caller)
970
 
971
{
972
   const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
973
   const GLenum target = texImage->TexObject->Target;
974
   GLboolean success = GL_FALSE;
975
   GLuint dims, slice, numSlices = 1, sliceOffset = 0;
976
   GLint srcImageStride = 0;
977
   const GLubyte *src;
978
 
979
   assert(xoffset + width <= texImage->Width);
980
   assert(yoffset + height <= texImage->Height);
981
   assert(zoffset + depth <= texImage->Depth);
982
 
983
   switch (target) {
984
   case GL_TEXTURE_1D:
985
      dims = 1;
986
      break;
987
   case GL_TEXTURE_2D_ARRAY:
988
   case GL_TEXTURE_CUBE_MAP_ARRAY:
989
   case GL_TEXTURE_3D:
990
      dims = 3;
991
      break;
992
   default:
993
      dims = 2;
994
   }
995
 
996
   /* get pointer to src pixels (may be in a pbo which we'll map here) */
997
   src = (const GLubyte *)
998
      _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
999
                                  format, type, pixels, packing, caller);
1000
   if (!src)
1001
      return;
1002
 
1003
   /* compute slice info (and do some sanity checks) */
1004
   switch (target) {
1005
   case GL_TEXTURE_2D:
1006
   case GL_TEXTURE_RECTANGLE:
1007
   case GL_TEXTURE_CUBE_MAP:
1008
   case GL_TEXTURE_EXTERNAL_OES:
1009
      /* one image slice, nothing special needs to be done */
1010
      break;
1011
   case GL_TEXTURE_1D:
1012
      assert(height == 1);
1013
      assert(depth == 1);
1014
      assert(yoffset == 0);
1015
      assert(zoffset == 0);
1016
      break;
1017
   case GL_TEXTURE_1D_ARRAY:
1018
      assert(depth == 1);
1019
      assert(zoffset == 0);
1020
      numSlices = height;
1021
      sliceOffset = yoffset;
1022
      height = 1;
1023
      yoffset = 0;
1024
      srcImageStride = _mesa_image_row_stride(packing, width, format, type);
1025
      break;
1026
   case GL_TEXTURE_2D_ARRAY:
1027
      numSlices = depth;
1028
      sliceOffset = zoffset;
1029
      depth = 1;
1030
      zoffset = 0;
1031
      srcImageStride = _mesa_image_image_stride(packing, width, height,
1032
                                                format, type);
1033
      break;
1034
   case GL_TEXTURE_3D:
1035
      /* we'll store 3D images as a series of slices */
1036
      numSlices = depth;
1037
      sliceOffset = zoffset;
1038
      srcImageStride = _mesa_image_image_stride(packing, width, height,
1039
                                                format, type);
1040
      break;
1041
   case GL_TEXTURE_CUBE_MAP_ARRAY:
1042
      numSlices = depth;
1043
      sliceOffset = zoffset;
1044
      srcImageStride = _mesa_image_image_stride(packing, width, height,
1045
                                                format, type);
1046
      break;
1047
   default:
1048
      _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
1049
      return;
1050
   }
1051
 
1052
   assert(numSlices == 1 || srcImageStride != 0);
1053
 
1054
   for (slice = 0; slice < numSlices; slice++) {
1055
      GLubyte *dstMap;
1056
      GLint dstRowStride;
1057
 
1058
      ctx->Driver.MapTextureImage(ctx, texImage,
1059
                                  slice + sliceOffset,
1060
                                  xoffset, yoffset, width, height,
1061
                                  mapMode, &dstMap, &dstRowStride);
1062
      if (dstMap) {
1063
         /* Note: we're only storing a 2D (or 1D) slice at a time but we need
1064
          * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
1065
          * used for 3D images.
1066
          */
1067
         success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
1068
                                  texImage->TexFormat,
1069
                                  dstRowStride,
1070
                                  &dstMap,
1071
                                  width, height, 1,  /* w, h, d */
1072
                                  format, type, src, packing);
1073
 
1074
         ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
1075
      }
1076
 
1077
      src += srcImageStride;
1078
 
1079
      if (!success)
1080
         break;
1081
   }
1082
 
1083
   if (!success)
1084
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
1085
 
1086
   _mesa_unmap_teximage_pbo(ctx, packing);
1087
}
1088
 
1089
 
1090
 
1091
/**
1092
 * Fallback code for ctx->Driver.TexImage().
1093
 * Basically, allocate storage for the texture image, then copy the
1094
 * user's image into it.
1095
 */
1096
void
1097
_mesa_store_teximage(struct gl_context *ctx,
1098
                     GLuint dims,
1099
                     struct gl_texture_image *texImage,
1100
                     GLenum format, GLenum type, const GLvoid *pixels,
1101
                     const struct gl_pixelstore_attrib *packing)
1102
{
1103
   assert(dims == 1 || dims == 2 || dims == 3);
1104
 
1105
   if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
1106
      return;
1107
 
1108
   /* allocate storage for texture data */
1109
   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
1110
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
1111
      return;
1112
   }
1113
 
1114
   store_texsubimage(ctx, texImage,
1115
                     0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
1116
                     format, type, pixels, packing, "glTexImage");
1117
}
1118
 
1119
 
1120
/*
1121
 * Fallback for Driver.TexSubImage().
1122
 */
1123
void
1124
_mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
1125
                        struct gl_texture_image *texImage,
1126
                        GLint xoffset, GLint yoffset, GLint zoffset,
1127
                        GLint width, GLint height, GLint depth,
1128
                        GLenum format, GLenum type, const void *pixels,
1129
                        const struct gl_pixelstore_attrib *packing)
1130
{
1131
   store_texsubimage(ctx, texImage,
1132
                     xoffset, yoffset, zoffset, width, height, depth,
1133
                     format, type, pixels, packing, "glTexSubImage");
1134
}
1135
 
1136
static void
1137
clear_image_to_zero(GLubyte *dstMap, GLint dstRowStride,
1138
                    GLsizei width, GLsizei height,
1139
                    GLsizei clearValueSize)
1140
{
1141
   GLsizei y;
1142
 
1143
   for (y = 0; y < height; y++) {
1144
      memset(dstMap, 0, clearValueSize * width);
1145
      dstMap += dstRowStride;
1146
   }
1147
}
1148
 
1149
static void
1150
clear_image_to_value(GLubyte *dstMap, GLint dstRowStride,
1151
                     GLsizei width, GLsizei height,
1152
                     const GLvoid *clearValue,
1153
                     GLsizei clearValueSize)
1154
{
1155
   GLsizei y, x;
1156
 
1157
   for (y = 0; y < height; y++) {
1158
      for (x = 0; x < width; x++) {
1159
         memcpy(dstMap, clearValue, clearValueSize);
1160
         dstMap += clearValueSize;
1161
      }
1162
      dstMap += dstRowStride - clearValueSize * width;
1163
   }
1164
}
1165
 
1166
/*
1167
 * Fallback for Driver.ClearTexSubImage().
1168
 */
1169
void
1170
_mesa_store_cleartexsubimage(struct gl_context *ctx,
1171
                             struct gl_texture_image *texImage,
1172
                             GLint xoffset, GLint yoffset, GLint zoffset,
1173
                             GLsizei width, GLsizei height, GLsizei depth,
1174
                             const GLvoid *clearValue)
1175
{
1176
   GLubyte *dstMap;
1177
   GLint dstRowStride;
1178
   GLsizeiptr clearValueSize;
1179
   GLsizei z;
1180
 
1181
   clearValueSize = _mesa_get_format_bytes(texImage->TexFormat);
1182
 
1183
   for (z = 0; z < depth; z++) {
1184
      ctx->Driver.MapTextureImage(ctx, texImage,
1185
                                  z + zoffset, xoffset, yoffset,
1186
                                  width, height,
1187
                                  GL_MAP_WRITE_BIT,
1188
                                  &dstMap, &dstRowStride);
1189
      if (dstMap == NULL) {
1190
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearTex*Image");
1191
         return;
1192
      }
1193
 
1194
      if (clearValue) {
1195
         clear_image_to_value(dstMap, dstRowStride,
1196
                              width, height,
1197
                              clearValue,
1198
                              clearValueSize);
1199
      } else {
1200
         clear_image_to_zero(dstMap, dstRowStride,
1201
                             width, height,
1202
                             clearValueSize);
1203
      }
1204
 
1205
      ctx->Driver.UnmapTextureImage(ctx, texImage, z + zoffset);
1206
   }
1207
}
1208
 
1209
/**
1210
 * Fallback for Driver.CompressedTexImage()
1211
 */
1212
void
1213
_mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
1214
                                struct gl_texture_image *texImage,
1215
                                GLsizei imageSize, const GLvoid *data)
1216
{
1217
   /* only 2D and 3D compressed images are supported at this time */
1218
   if (dims == 1) {
1219
      _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call");
1220
      return;
1221
   }
1222
 
1223
   /* This is pretty simple, because unlike the general texstore path we don't
1224
    * have to worry about the usual image unpacking or image transfer
1225
    * operations.
1226
    */
1227
   assert(texImage);
1228
   assert(texImage->Width > 0);
1229
   assert(texImage->Height > 0);
1230
   assert(texImage->Depth > 0);
1231
 
1232
   /* allocate storage for texture data */
1233
   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
1234
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims);
1235
      return;
1236
   }
1237
 
1238
   _mesa_store_compressed_texsubimage(ctx, dims, texImage,
1239
                                      0, 0, 0,
1240
                                      texImage->Width, texImage->Height, texImage->Depth,
1241
                                      texImage->TexFormat,
1242
                                      imageSize, data);
1243
}
1244
 
1245
 
1246
/**
1247
 * Compute compressed_pixelstore parameters for copying compressed
1248
 * texture data.
1249
 * \param dims  number of texture image dimensions: 1, 2 or 3
1250
 * \param texFormat  the compressed texture format
1251
 * \param width, height, depth  size of image to copy
1252
 * \param packing  pixelstore parameters describing user-space image packing
1253
 * \param store  returns the compressed_pixelstore parameters
1254
 */
1255
void
1256
_mesa_compute_compressed_pixelstore(GLuint dims, mesa_format texFormat,
1257
                                    GLsizei width, GLsizei height,
1258
                                    GLsizei depth,
1259
                                    const struct gl_pixelstore_attrib *packing,
1260
                                    struct compressed_pixelstore *store)
1261
{
1262
   GLuint bw, bh;
1263
 
1264
   _mesa_get_format_block_size(texFormat, &bw, &bh);
1265
 
1266
   store->SkipBytes = 0;
1267
   store->TotalBytesPerRow = store->CopyBytesPerRow =
1268
         _mesa_format_row_stride(texFormat, width);
1269
   store->TotalRowsPerSlice = store->CopyRowsPerSlice =
1270
         (height + bh - 1) / bh;
1271
   store->CopySlices = depth;
1272
 
1273
   if (packing->CompressedBlockWidth &&
1274
       packing->CompressedBlockSize) {
1275
 
1276
      bw = packing->CompressedBlockWidth;
1277
 
1278
      if (packing->RowLength) {
1279
         store->TotalBytesPerRow = packing->CompressedBlockSize *
1280
            ((packing->RowLength + bw - 1) / bw);
1281
      }
1282
 
1283
      store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw;
1284
   }
1285
 
1286
   if (dims > 1 && packing->CompressedBlockHeight &&
1287
       packing->CompressedBlockSize) {
1288
 
1289
      bh = packing->CompressedBlockHeight;
1290
 
1291
      store->SkipBytes += packing->SkipRows * store->TotalBytesPerRow / bh;
1292
      store->CopyRowsPerSlice = (height + bh - 1) / bh;  /* rows in blocks */
1293
 
1294
      if (packing->ImageHeight) {
1295
         store->TotalRowsPerSlice = (packing->ImageHeight + bh - 1) / bh;
1296
      }
1297
   }
1298
 
1299
   if (dims > 2 && packing->CompressedBlockDepth &&
1300
       packing->CompressedBlockSize) {
1301
 
1302
      int bd = packing->CompressedBlockDepth;
1303
 
1304
      store->SkipBytes += packing->SkipImages * store->TotalBytesPerRow *
1305
            store->TotalRowsPerSlice / bd;
1306
   }
1307
}
1308
 
1309
 
1310
/**
1311
 * Fallback for Driver.CompressedTexSubImage()
1312
 */
1313
void
1314
_mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
1315
                                   struct gl_texture_image *texImage,
1316
                                   GLint xoffset, GLint yoffset, GLint zoffset,
1317
                                   GLsizei width, GLsizei height, GLsizei depth,
1318
                                   GLenum format,
1319
                                   GLsizei imageSize, const GLvoid *data)
1320
{
1321
   struct compressed_pixelstore store;
1322
   GLint dstRowStride;
1323
   GLint i, slice;
1324
   GLubyte *dstMap;
1325
   const GLubyte *src;
1326
 
1327
   if (dims == 1) {
1328
      _mesa_problem(ctx, "Unexpected 1D compressed texsubimage call");
1329
      return;
1330
   }
1331
 
1332
   _mesa_compute_compressed_pixelstore(dims, texImage->TexFormat,
1333
                                       width, height, depth,
1334
                                       &ctx->Unpack, &store);
1335
 
1336
   /* get pointer to src pixels (may be in a pbo which we'll map here) */
1337
   data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data,
1338
                                                 &ctx->Unpack,
1339
                                                 "glCompressedTexSubImage");
1340
   if (!data)
1341
      return;
1342
 
1343
   src = (const GLubyte *) data + store.SkipBytes;
1344
 
1345
   for (slice = 0; slice < store.CopySlices; slice++) {
1346
      /* Map dest texture buffer */
1347
      ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset,
1348
                                  xoffset, yoffset, width, height,
1349
                                  GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
1350
                                  &dstMap, &dstRowStride);
1351
 
1352
      if (dstMap) {
1353
 
1354
         /* copy rows of blocks */
1355
         for (i = 0; i < store.CopyRowsPerSlice; i++) {
1356
            memcpy(dstMap, src, store.CopyBytesPerRow);
1357
            dstMap += dstRowStride;
1358
            src += store.TotalBytesPerRow;
1359
         }
1360
 
1361
         ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset);
1362
 
1363
         /* advance to next slice */
1364
         src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice);
1365
      }
1366
      else {
1367
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",
1368
                     dims);
1369
      }
1370
   }
1371
 
1372
   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
1373
}