~ubuntu-branches/ubuntu/quantal/mesa/quantal

« back to all changes in this revision

Viewing changes to src/mesa/drivers/dri/i915tex/intel_tex_image.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-02-21 12:44:07 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 22.
  • Revision ID: james.westby@ubuntu.com-20070221124407-rgcacs32mycrtadl
ImportĀ upstreamĀ versionĀ 6.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include <stdlib.h>
 
3
#include <stdio.h>
 
4
 
 
5
#include "glheader.h"
 
6
#include "macros.h"
 
7
#include "mtypes.h"
 
8
#include "enums.h"
 
9
#include "colortab.h"
 
10
#include "convolve.h"
 
11
#include "context.h"
 
12
#include "simple_list.h"
 
13
#include "texcompress.h"
 
14
#include "texformat.h"
 
15
#include "texobj.h"
 
16
#include "texstore.h"
 
17
 
 
18
#include "intel_context.h"
 
19
#include "intel_mipmap_tree.h"
 
20
#include "intel_buffer_objects.h"
 
21
#include "intel_batchbuffer.h"
 
22
#include "intel_tex.h"
 
23
#include "intel_ioctl.h"
 
24
#include "intel_blit.h"
 
25
 
 
26
#define FILE_DEBUG_FLAG DEBUG_TEXTURE
 
27
 
 
28
/* Functions to store texture images.  Where possible, mipmap_tree's
 
29
 * will be created or further instantiated with image data, otherwise
 
30
 * images will be stored in malloc'd memory.  A validation step is
 
31
 * required to pull those images into a mipmap tree, or otherwise
 
32
 * decide a fallback is required.
 
33
 */
 
34
 
 
35
 
 
36
static int
 
37
logbase2(int n)
 
38
{
 
39
   GLint i = 1;
 
40
   GLint log2 = 0;
 
41
 
 
42
   while (n > i) {
 
43
      i *= 2;
 
44
      log2++;
 
45
   }
 
46
 
 
47
   return log2;
 
48
}
 
49
 
 
50
 
 
51
/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
 
52
 * 1).
 
53
 *    
 
54
 * Otherwise, if max_level >= level >= min_level, create tree with
 
55
 * space for textures from min_level down to max_level.
 
56
 *
 
57
 * Otherwise, create tree with space for textures from (level
 
58
 * 0)..(1x1).  Consider pruning this tree at a validation if the
 
59
 * saving is worth it.
 
60
 */
 
61
static void
 
62
guess_and_alloc_mipmap_tree(struct intel_context *intel,
 
63
                            struct intel_texture_object *intelObj,
 
64
                            struct intel_texture_image *intelImage)
 
65
{
 
66
   GLuint firstLevel;
 
67
   GLuint lastLevel;
 
68
   GLuint width = intelImage->base.Width;
 
69
   GLuint height = intelImage->base.Height;
 
70
   GLuint depth = intelImage->base.Depth;
 
71
   GLuint l2width, l2height, l2depth;
 
72
   GLuint i, comp_byte = 0;
 
73
 
 
74
   DBG("%s\n", __FUNCTION__);
 
75
 
 
76
   if (intelImage->base.Border)
 
77
      return;
 
78
 
 
79
   if (intelImage->level > intelObj->base.BaseLevel &&
 
80
       (intelImage->base.Width == 1 ||
 
81
        (intelObj->base.Target != GL_TEXTURE_1D &&
 
82
         intelImage->base.Height == 1) ||
 
83
        (intelObj->base.Target == GL_TEXTURE_3D &&
 
84
         intelImage->base.Depth == 1)))
 
85
      return;
 
86
 
 
87
   /* If this image disrespects BaseLevel, allocate from level zero.
 
88
    * Usually BaseLevel == 0, so it's unlikely to happen.
 
89
    */
 
90
   if (intelImage->level < intelObj->base.BaseLevel)
 
91
      firstLevel = 0;
 
92
   else
 
93
      firstLevel = intelObj->base.BaseLevel;
 
94
 
 
95
 
 
96
   /* Figure out image dimensions at start level. 
 
97
    */
 
98
   for (i = intelImage->level; i > firstLevel; i--) {
 
99
      width <<= 1;
 
100
      if (height != 1)
 
101
         height <<= 1;
 
102
      if (depth != 1)
 
103
         depth <<= 1;
 
104
   }
 
105
 
 
106
   /* Guess a reasonable value for lastLevel.  This is probably going
 
107
    * to be wrong fairly often and might mean that we have to look at
 
108
    * resizable buffers, or require that buffers implement lazy
 
109
    * pagetable arrangements.
 
110
    */
 
111
   if ((intelObj->base.MinFilter == GL_NEAREST ||
 
112
        intelObj->base.MinFilter == GL_LINEAR) &&
 
113
       intelImage->level == firstLevel) {
 
114
      lastLevel = firstLevel;
 
115
   }
 
116
   else {
 
117
      l2width = logbase2(width);
 
118
      l2height = logbase2(height);
 
119
      l2depth = logbase2(depth);
 
120
      lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
 
121
   }
 
122
 
 
123
   assert(!intelObj->mt);
 
124
   if (intelImage->base.IsCompressed)
 
125
      comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
 
126
   intelObj->mt = intel_miptree_create(intel,
 
127
                                       intelObj->base.Target,
 
128
                                       intelImage->base.InternalFormat,
 
129
                                       firstLevel,
 
130
                                       lastLevel,
 
131
                                       width,
 
132
                                       height,
 
133
                                       depth,
 
134
                                       intelImage->base.TexFormat->TexelBytes,
 
135
                                       comp_byte);
 
136
 
 
137
   DBG("%s - success\n", __FUNCTION__);
 
138
}
 
139
 
 
140
 
 
141
 
 
142
 
 
143
static GLuint
 
144
target_to_face(GLenum target)
 
145
{
 
146
   switch (target) {
 
147
   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
 
148
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
 
149
   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
 
150
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
 
151
   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
 
152
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
 
153
      return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
 
154
   default:
 
155
      return 0;
 
156
   }
 
157
}
 
158
 
 
159
/* There are actually quite a few combinations this will work for,
 
160
 * more than what I've listed here.
 
161
 */
 
162
static GLboolean
 
163
check_pbo_format(GLint internalFormat,
 
164
                 GLenum format, GLenum type,
 
165
                 const struct gl_texture_format *mesa_format)
 
166
{
 
167
   switch (internalFormat) {
 
168
   case 4:
 
169
   case GL_RGBA:
 
170
      return (format == GL_BGRA &&
 
171
              (type == GL_UNSIGNED_BYTE ||
 
172
               type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
 
173
              mesa_format == &_mesa_texformat_argb8888);
 
174
   case 3:
 
175
   case GL_RGB:
 
176
      return (format == GL_RGB &&
 
177
              type == GL_UNSIGNED_SHORT_5_6_5 &&
 
178
              mesa_format == &_mesa_texformat_rgb565);
 
179
   case GL_YCBCR_MESA:
 
180
      return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
 
181
   default:
 
182
      return GL_FALSE;
 
183
   }
 
184
}
 
185
 
 
186
 
 
187
/* XXX: Do this for TexSubImage also:
 
188
 */
 
189
static GLboolean
 
190
try_pbo_upload(struct intel_context *intel,
 
191
               struct intel_texture_image *intelImage,
 
192
               const struct gl_pixelstore_attrib *unpack,
 
193
               GLint internalFormat,
 
194
               GLint width, GLint height,
 
195
               GLenum format, GLenum type, const void *pixels)
 
196
{
 
197
   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
 
198
   GLuint src_offset, src_stride;
 
199
   GLuint dst_offset, dst_stride;
 
200
 
 
201
   if (!pbo ||
 
202
       intel->ctx._ImageTransferState ||
 
203
       unpack->SkipPixels || unpack->SkipRows) {
 
204
      _mesa_printf("%s: failure 1\n", __FUNCTION__);
 
205
      return GL_FALSE;
 
206
   }
 
207
 
 
208
   src_offset = (GLuint) pixels;
 
209
 
 
210
   if (unpack->RowLength > 0)
 
211
      src_stride = unpack->RowLength;
 
212
   else
 
213
      src_stride = width;
 
214
 
 
215
   dst_offset = intel_miptree_image_offset(intelImage->mt,
 
216
                                           intelImage->face,
 
217
                                           intelImage->level);
 
218
 
 
219
   dst_stride = intelImage->mt->pitch;
 
220
 
 
221
   intelFlush(&intel->ctx);
 
222
   LOCK_HARDWARE(intel);
 
223
   {
 
224
      struct _DriBufferObject *src_buffer =
 
225
         intel_bufferobj_buffer(intel, pbo, INTEL_READ);
 
226
      struct _DriBufferObject *dst_buffer =
 
227
         intel_region_buffer(intel->intelScreen, intelImage->mt->region,
 
228
                             INTEL_WRITE_FULL);
 
229
 
 
230
 
 
231
      intelEmitCopyBlit(intel,
 
232
                        intelImage->mt->cpp,
 
233
                        src_stride, src_buffer, src_offset,
 
234
                        dst_stride, dst_buffer, dst_offset,
 
235
                        0, 0, 0, 0, width, height,
 
236
                        GL_COPY);
 
237
 
 
238
      intel_batchbuffer_flush(intel->batch);
 
239
   }
 
240
   UNLOCK_HARDWARE(intel);
 
241
 
 
242
   return GL_TRUE;
 
243
}
 
244
 
 
245
 
 
246
 
 
247
static GLboolean
 
248
try_pbo_zcopy(struct intel_context *intel,
 
249
              struct intel_texture_image *intelImage,
 
250
              const struct gl_pixelstore_attrib *unpack,
 
251
              GLint internalFormat,
 
252
              GLint width, GLint height,
 
253
              GLenum format, GLenum type, const void *pixels)
 
254
{
 
255
   struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
 
256
   GLuint src_offset, src_stride;
 
257
   GLuint dst_offset, dst_stride;
 
258
 
 
259
   if (!pbo ||
 
260
       intel->ctx._ImageTransferState ||
 
261
       unpack->SkipPixels || unpack->SkipRows) {
 
262
      _mesa_printf("%s: failure 1\n", __FUNCTION__);
 
263
      return GL_FALSE;
 
264
   }
 
265
 
 
266
   src_offset = (GLuint) pixels;
 
267
 
 
268
   if (unpack->RowLength > 0)
 
269
      src_stride = unpack->RowLength;
 
270
   else
 
271
      src_stride = width;
 
272
 
 
273
   dst_offset = intel_miptree_image_offset(intelImage->mt,
 
274
                                           intelImage->face,
 
275
                                           intelImage->level);
 
276
 
 
277
   dst_stride = intelImage->mt->pitch;
 
278
 
 
279
   if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) {
 
280
      _mesa_printf("%s: failure 2\n", __FUNCTION__);
 
281
      return GL_FALSE;
 
282
   }
 
283
 
 
284
   intel_region_attach_pbo(intel->intelScreen, intelImage->mt->region, pbo);
 
285
 
 
286
   return GL_TRUE;
 
287
}
 
288
 
 
289
 
 
290
 
 
291
 
 
292
 
 
293
 
 
294
static void
 
295
intelTexImage(GLcontext * ctx,
 
296
              GLint dims,
 
297
              GLenum target, GLint level,
 
298
              GLint internalFormat,
 
299
              GLint width, GLint height, GLint depth,
 
300
              GLint border,
 
301
              GLenum format, GLenum type, const void *pixels,
 
302
              const struct gl_pixelstore_attrib *unpack,
 
303
              struct gl_texture_object *texObj,
 
304
              struct gl_texture_image *texImage, GLsizei imageSize, int compressed)
 
305
{
 
306
   struct intel_context *intel = intel_context(ctx);
 
307
   struct intel_texture_object *intelObj = intel_texture_object(texObj);
 
308
   struct intel_texture_image *intelImage = intel_texture_image(texImage);
 
309
   GLint postConvWidth = width;
 
310
   GLint postConvHeight = height;
 
311
   GLint texelBytes, sizeInBytes;
 
312
   GLuint dstRowStride;
 
313
 
 
314
 
 
315
   DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
 
316
       _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
 
317
 
 
318
   intelFlush(ctx);
 
319
 
 
320
   intelImage->face = target_to_face(target);
 
321
   intelImage->level = level;
 
322
 
 
323
   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
 
324
      _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
 
325
                                         &postConvHeight);
 
326
   }
 
327
 
 
328
   /* choose the texture format */
 
329
   texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat,
 
330
                                                  format, type);
 
331
 
 
332
   assert(texImage->TexFormat);
 
333
 
 
334
   switch (dims) {
 
335
   case 1:
 
336
      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
 
337
      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
 
338
      break;
 
339
   case 2:
 
340
      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
 
341
      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
 
342
      break;
 
343
   case 3:
 
344
      texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
 
345
      texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
 
346
      break;
 
347
   default:
 
348
      assert(0);
 
349
      break;
 
350
   }
 
351
 
 
352
   if (texImage->TexFormat->TexelBytes == 0) {
 
353
      /* must be a compressed format */
 
354
      texelBytes = 0;
 
355
      texImage->IsCompressed = GL_TRUE;
 
356
      texImage->CompressedSize =
 
357
         ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
 
358
                                           texImage->Height, texImage->Depth,
 
359
                                           texImage->TexFormat->MesaFormat);
 
360
   } else {
 
361
      texelBytes = texImage->TexFormat->TexelBytes;
 
362
      
 
363
      /* Minimum pitch of 32 bytes */
 
364
      if (postConvWidth * texelBytes < 32) {
 
365
         postConvWidth = 32 / texelBytes;
 
366
         texImage->RowStride = postConvWidth;
 
367
      }
 
368
      
 
369
      assert(texImage->RowStride == postConvWidth);
 
370
   }
 
371
 
 
372
   /* Release the reference to a potentially orphaned buffer.   
 
373
    * Release any old malloced memory.
 
374
    */
 
375
   if (intelImage->mt) {
 
376
      intel_miptree_release(intel, &intelImage->mt);
 
377
      assert(!texImage->Data);
 
378
   }
 
379
   else if (texImage->Data) {
 
380
      _mesa_align_free(texImage->Data);
 
381
   }
 
382
 
 
383
   /* If this is the only texture image in the tree, could call
 
384
    * bmBufferData with NULL data to free the old block and avoid
 
385
    * waiting on any outstanding fences.
 
386
    */
 
387
   if (intelObj->mt &&
 
388
       intelObj->mt->first_level == level &&
 
389
       intelObj->mt->last_level == level &&
 
390
       intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
 
391
       !intel_miptree_match_image(intelObj->mt, &intelImage->base,
 
392
                                  intelImage->face, intelImage->level)) {
 
393
 
 
394
      DBG("release it\n");
 
395
      intel_miptree_release(intel, &intelObj->mt);
 
396
      assert(!intelObj->mt);
 
397
   }
 
398
 
 
399
   if (!intelObj->mt) {
 
400
      guess_and_alloc_mipmap_tree(intel, intelObj, intelImage);
 
401
      if (!intelObj->mt) {
 
402
         DBG("guess_and_alloc_mipmap_tree: failed\n");
 
403
      }
 
404
   }
 
405
 
 
406
 
 
407
   assert(!intelImage->mt);
 
408
 
 
409
   if (intelObj->mt &&
 
410
       intel_miptree_match_image(intelObj->mt, &intelImage->base,
 
411
                                 intelImage->face, intelImage->level)) {
 
412
 
 
413
      intel_miptree_reference(&intelImage->mt, intelObj->mt);
 
414
      assert(intelImage->mt);
 
415
   }
 
416
 
 
417
   if (!intelImage->mt)
 
418
      DBG("XXX: Image did not fit into tree - storing in local memory!\n");
 
419
 
 
420
   /* PBO fastpaths:
 
421
    */
 
422
   if (dims <= 2 &&
 
423
       intelImage->mt &&
 
424
       intel_buffer_object(unpack->BufferObj) &&
 
425
       check_pbo_format(internalFormat, format,
 
426
                        type, intelImage->base.TexFormat)) {
 
427
 
 
428
      DBG("trying pbo upload\n");
 
429
 
 
430
      /* Attempt to texture directly from PBO data (zero copy upload).
 
431
       *
 
432
       * Currently disable as it can lead to worse as well as better
 
433
       * performance (in particular when intel_region_cow() is
 
434
       * required).
 
435
       */
 
436
      if (intelObj->mt == intelImage->mt &&
 
437
          intelObj->mt->first_level == level &&
 
438
          intelObj->mt->last_level == level) {
 
439
 
 
440
         if (try_pbo_zcopy(intel, intelImage, unpack,
 
441
                           internalFormat,
 
442
                           width, height, format, type, pixels)) {
 
443
 
 
444
            DBG("pbo zcopy upload succeeded\n");
 
445
            return;
 
446
         }
 
447
      }
 
448
 
 
449
 
 
450
      /* Otherwise, attempt to use the blitter for PBO image uploads.
 
451
       */
 
452
      if (try_pbo_upload(intel, intelImage, unpack,
 
453
                         internalFormat,
 
454
                         width, height, format, type, pixels)) {
 
455
         DBG("pbo upload succeeded\n");
 
456
         return;
 
457
      }
 
458
 
 
459
      DBG("pbo upload failed\n");
 
460
   }
 
461
 
 
462
 
 
463
 
 
464
   /* intelCopyTexImage calls this function with pixels == NULL, with
 
465
    * the expectation that the mipmap tree will be set up but nothing
 
466
    * more will be done.  This is where those calls return:
 
467
    */
 
468
   if (compressed) {
 
469
      pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
 
470
                                                      unpack,
 
471
                                                      "glCompressedTexImage");
 
472
   } else {
 
473
      pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
 
474
                                           format, type,
 
475
                                           pixels, unpack, "glTexImage");
 
476
   }
 
477
   if (!pixels)
 
478
      return;
 
479
 
 
480
 
 
481
   if (intelImage->mt)
 
482
      intel_region_idle(intel->intelScreen, intelImage->mt->region);
 
483
 
 
484
   LOCK_HARDWARE(intel);
 
485
 
 
486
   if (intelImage->mt) {
 
487
      texImage->Data = intel_miptree_image_map(intel,
 
488
                                               intelImage->mt,
 
489
                                               intelImage->face,
 
490
                                               intelImage->level,
 
491
                                               &dstRowStride,
 
492
                                               intelImage->base.ImageOffsets);
 
493
   }
 
494
   else {
 
495
      /* Allocate regular memory and store the image there temporarily.   */
 
496
      if (texImage->IsCompressed) {
 
497
         sizeInBytes = texImage->CompressedSize;
 
498
         dstRowStride =
 
499
            _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
 
500
         assert(dims != 3);
 
501
      }
 
502
      else {
 
503
         dstRowStride = postConvWidth * texelBytes;
 
504
         sizeInBytes = depth * dstRowStride * postConvHeight;
 
505
      }
 
506
 
 
507
      texImage->Data = malloc(sizeInBytes);
 
508
   }
 
509
 
 
510
   DBG("Upload image %dx%dx%d row_len %x "
 
511
       "pitch %x\n",
 
512
       width, height, depth, width * texelBytes, dstRowStride);
 
513
 
 
514
   /* Copy data.  Would like to know when it's ok for us to eg. use
 
515
    * the blitter to copy.  Or, use the hardware to do the format
 
516
    * conversion and copy:
 
517
    */
 
518
   if (compressed) {
 
519
     memcpy(texImage->Data, pixels, imageSize);
 
520
   } else if (!texImage->TexFormat->StoreImage(ctx, dims, 
 
521
                                               texImage->_BaseFormat, 
 
522
                                               texImage->TexFormat, 
 
523
                                               texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
 
524
                                               dstRowStride,
 
525
                                               texImage->ImageOffsets,
 
526
                                               width, height, depth,
 
527
                                               format, type, pixels, unpack)) {
 
528
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
 
529
   }
 
530
 
 
531
   _mesa_unmap_teximage_pbo(ctx, unpack);
 
532
 
 
533
   if (intelImage->mt) {
 
534
      intel_miptree_image_unmap(intel, intelImage->mt);
 
535
      texImage->Data = NULL;
 
536
   }
 
537
 
 
538
   UNLOCK_HARDWARE(intel);
 
539
 
 
540
#if 0
 
541
   /* GL_SGIS_generate_mipmap -- this can be accelerated now.
 
542
    */
 
543
   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
 
544
      intel_generate_mipmap(ctx, target,
 
545
                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
 
546
                            texObj);
 
547
   }
 
548
#endif
 
549
}
 
550
 
 
551
void
 
552
intelTexImage3D(GLcontext * ctx,
 
553
                GLenum target, GLint level,
 
554
                GLint internalFormat,
 
555
                GLint width, GLint height, GLint depth,
 
556
                GLint border,
 
557
                GLenum format, GLenum type, const void *pixels,
 
558
                const struct gl_pixelstore_attrib *unpack,
 
559
                struct gl_texture_object *texObj,
 
560
                struct gl_texture_image *texImage)
 
561
{
 
562
   intelTexImage(ctx, 3, target, level,
 
563
                 internalFormat, width, height, depth, border,
 
564
                 format, type, pixels, unpack, texObj, texImage, 0, 0);
 
565
}
 
566
 
 
567
 
 
568
void
 
569
intelTexImage2D(GLcontext * ctx,
 
570
                GLenum target, GLint level,
 
571
                GLint internalFormat,
 
572
                GLint width, GLint height, GLint border,
 
573
                GLenum format, GLenum type, const void *pixels,
 
574
                const struct gl_pixelstore_attrib *unpack,
 
575
                struct gl_texture_object *texObj,
 
576
                struct gl_texture_image *texImage)
 
577
{
 
578
   intelTexImage(ctx, 2, target, level,
 
579
                 internalFormat, width, height, 1, border,
 
580
                 format, type, pixels, unpack, texObj, texImage, 0, 0);
 
581
}
 
582
 
 
583
void
 
584
intelTexImage1D(GLcontext * ctx,
 
585
                GLenum target, GLint level,
 
586
                GLint internalFormat,
 
587
                GLint width, GLint border,
 
588
                GLenum format, GLenum type, const void *pixels,
 
589
                const struct gl_pixelstore_attrib *unpack,
 
590
                struct gl_texture_object *texObj,
 
591
                struct gl_texture_image *texImage)
 
592
{
 
593
   intelTexImage(ctx, 1, target, level,
 
594
                 internalFormat, width, 1, 1, border,
 
595
                 format, type, pixels, unpack, texObj, texImage, 0, 0);
 
596
}
 
597
 
 
598
void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
 
599
                                GLint internalFormat,
 
600
                                GLint width, GLint height, GLint border,
 
601
                                GLsizei imageSize, const GLvoid *data,
 
602
                                struct gl_texture_object *texObj,
 
603
                                struct gl_texture_image *texImage )
 
604
{
 
605
   intelTexImage(ctx, 2, target, level,
 
606
                 internalFormat, width, height, 1, border,
 
607
                 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1);
 
608
}
 
609
 
 
610
/**
 
611
 * Need to map texture image into memory before copying image data,
 
612
 * then unmap it.
 
613
 */
 
614
static void
 
615
intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
 
616
                    GLenum format, GLenum type, GLvoid * pixels,
 
617
                    struct gl_texture_object *texObj,
 
618
                    struct gl_texture_image *texImage, int compressed)
 
619
{
 
620
   struct intel_context *intel = intel_context(ctx);
 
621
   struct intel_texture_image *intelImage = intel_texture_image(texImage);
 
622
 
 
623
   /* Map */
 
624
   if (intelImage->mt) {
 
625
      /* Image is stored in hardware format in a buffer managed by the
 
626
       * kernel.  Need to explicitly map and unmap it.
 
627
       */
 
628
      intelImage->base.Data =
 
629
         intel_miptree_image_map(intel,
 
630
                                 intelImage->mt,
 
631
                                 intelImage->face,
 
632
                                 intelImage->level,
 
633
                                 &intelImage->base.RowStride,
 
634
                                 intelImage->base.ImageOffsets);
 
635
   }
 
636
   else {
 
637
      /* Otherwise, the image should actually be stored in
 
638
       * intelImage->base.Data.  This is pretty confusing for
 
639
       * everybody, I'd much prefer to separate the two functions of
 
640
       * texImage->Data - storage for texture images in main memory
 
641
       * and access (ie mappings) of images.  In other words, we'd
 
642
       * create a new texImage->Map field and leave Data simply for
 
643
       * storage.
 
644
       */
 
645
      assert(intelImage->base.Data);
 
646
   }
 
647
 
 
648
 
 
649
   if (compressed) {
 
650
      _mesa_get_compressed_teximage(ctx, target, level, pixels,
 
651
                                    texObj, texImage);
 
652
   } else {
 
653
      _mesa_get_teximage(ctx, target, level, format, type, pixels,
 
654
                         texObj, texImage);
 
655
   }
 
656
     
 
657
 
 
658
   /* Unmap */
 
659
   if (intelImage->mt) {
 
660
      intel_miptree_image_unmap(intel, intelImage->mt);
 
661
      intelImage->base.Data = NULL;
 
662
   }
 
663
}
 
664
 
 
665
void
 
666
intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
 
667
                 GLenum format, GLenum type, GLvoid * pixels,
 
668
                 struct gl_texture_object *texObj,
 
669
                 struct gl_texture_image *texImage)
 
670
{
 
671
   intel_get_tex_image(ctx, target, level, format, type, pixels,
 
672
                       texObj, texImage, 0);
 
673
 
 
674
 
 
675
}
 
676
 
 
677
void
 
678
intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
 
679
                           GLvoid *pixels,
 
680
                           const struct gl_texture_object *texObj,
 
681
                           const struct gl_texture_image *texImage)
 
682
{
 
683
   intel_get_tex_image(ctx, target, level, 0, 0, pixels,
 
684
                       texObj, texImage, 1);
 
685
 
 
686
}