Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / intel / intel_tex_image.c
1
2 #include "main/glheader.h"
3 #include "main/macros.h"
4 #include "main/mfeatures.h"
5 #include "main/mtypes.h"
6 #include "main/enums.h"
7 #include "main/bufferobj.h"
8 #include "main/context.h"
9 #include "main/formats.h"
10 #include "main/pbo.h"
11 #include "main/renderbuffer.h"
12 #include "main/texcompress.h"
13 #include "main/texstore.h"
14 #include "main/texgetimage.h"
15 #include "main/texobj.h"
16 #include "main/teximage.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_blit.h"
24 #include "intel_fbo.h"
25 #include "intel_span.h"
26
27 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
28
29 /* Functions to store texture images.  Where possible, mipmap_tree's
30  * will be created or further instantiated with image data, otherwise
31  * images will be stored in malloc'd memory.  A validation step is
32  * required to pull those images into a mipmap tree, or otherwise
33  * decide a fallback is required.
34  */
35
36
37
38 /* Otherwise, store it in memory if (Border != 0) or (any dimension ==
39  * 1).
40  *    
41  * Otherwise, if max_level >= level >= min_level, create tree with
42  * space for textures from min_level down to max_level.
43  *
44  * Otherwise, create tree with space for textures from (level
45  * 0)..(1x1).  Consider pruning this tree at a validation if the
46  * saving is worth it.
47  */
48 static struct intel_mipmap_tree *
49 intel_miptree_create_for_teximage(struct intel_context *intel,
50                                   struct intel_texture_object *intelObj,
51                                   struct intel_texture_image *intelImage,
52                                   GLboolean expect_accelerated_upload)
53 {
54    GLuint firstLevel;
55    GLuint lastLevel;
56    GLuint width = intelImage->base.Width;
57    GLuint height = intelImage->base.Height;
58    GLuint depth = intelImage->base.Depth;
59    GLuint i;
60
61    DBG("%s\n", __FUNCTION__);
62
63    if (intelImage->base.Border)
64       return NULL;
65
66    if (intelImage->level > intelObj->base.BaseLevel &&
67        (intelImage->base.Width == 1 ||
68         (intelObj->base.Target != GL_TEXTURE_1D &&
69          intelImage->base.Height == 1) ||
70         (intelObj->base.Target == GL_TEXTURE_3D &&
71          intelImage->base.Depth == 1))) {
72       /* For this combination, we're at some lower mipmap level and
73        * some important dimension is 1.  We can't extrapolate up to a
74        * likely base level width/height/depth for a full mipmap stack
75        * from this info, so just allocate this one level.
76        */
77       firstLevel = intelImage->level;
78       lastLevel = intelImage->level;
79    } else {
80       /* If this image disrespects BaseLevel, allocate from level zero.
81        * Usually BaseLevel == 0, so it's unlikely to happen.
82        */
83       if (intelImage->level < intelObj->base.BaseLevel)
84          firstLevel = 0;
85       else
86          firstLevel = intelObj->base.BaseLevel;
87
88       /* Figure out image dimensions at start level. */
89       for (i = intelImage->level; i > firstLevel; i--) {
90          width <<= 1;
91          if (height != 1)
92             height <<= 1;
93          if (depth != 1)
94             depth <<= 1;
95       }
96
97       /* Guess a reasonable value for lastLevel.  This is probably going
98        * to be wrong fairly often and might mean that we have to look at
99        * resizable buffers, or require that buffers implement lazy
100        * pagetable arrangements.
101        */
102       if ((intelObj->base.Sampler.MinFilter == GL_NEAREST ||
103            intelObj->base.Sampler.MinFilter == GL_LINEAR) &&
104           intelImage->level == firstLevel &&
105           (intel->gen < 4 || firstLevel == 0)) {
106          lastLevel = firstLevel;
107       } else {
108          lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth));
109       }
110    }
111
112    return intel_miptree_create(intel,
113                                intelObj->base.Target,
114                                intelImage->base.TexFormat,
115                                firstLevel,
116                                lastLevel,
117                                width,
118                                height,
119                                depth,
120                                expect_accelerated_upload);
121 }
122
123
124
125
126 static GLuint
127 target_to_face(GLenum target)
128 {
129    switch (target) {
130    case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
131    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
132    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
133    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
134    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
135    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
136       return ((GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
137    default:
138       return 0;
139    }
140 }
141
142 /* There are actually quite a few combinations this will work for,
143  * more than what I've listed here.
144  */
145 static GLboolean
146 check_pbo_format(GLint internalFormat,
147                  GLenum format, GLenum type,
148                  gl_format mesa_format)
149 {
150    switch (internalFormat) {
151    case 4:
152    case GL_RGBA:
153    case GL_RGBA8:
154       return (format == GL_BGRA &&
155               (type == GL_UNSIGNED_BYTE ||
156                type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
157               mesa_format == MESA_FORMAT_ARGB8888);
158    case 3:
159    case GL_RGB:
160       return (format == GL_RGB &&
161               type == GL_UNSIGNED_SHORT_5_6_5 &&
162               mesa_format == MESA_FORMAT_RGB565);
163    case 1:
164    case GL_LUMINANCE:
165       return (format == GL_LUMINANCE &&
166               type == GL_UNSIGNED_BYTE &&
167               mesa_format == MESA_FORMAT_L8);
168    case GL_YCBCR_MESA:
169       return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
170    default:
171       return GL_FALSE;
172    }
173 }
174
175
176 /* XXX: Do this for TexSubImage also:
177  */
178 static GLboolean
179 try_pbo_upload(struct intel_context *intel,
180                struct intel_texture_image *intelImage,
181                const struct gl_pixelstore_attrib *unpack,
182                GLint internalFormat,
183                GLint width, GLint height,
184                GLenum format, GLenum type, const void *pixels)
185 {
186    struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
187    GLuint src_offset, src_stride;
188    GLuint dst_x, dst_y, dst_stride;
189    drm_intel_bo *dst_buffer = intel_region_buffer(intel,
190                                                   intelImage->mt->region,
191                                                   INTEL_WRITE_FULL);
192
193    if (!_mesa_is_bufferobj(unpack->BufferObj) ||
194        intel->ctx._ImageTransferState ||
195        unpack->SkipPixels || unpack->SkipRows) {
196       DBG("%s: failure 1\n", __FUNCTION__);
197       return GL_FALSE;
198    }
199
200    /* note: potential 64-bit ptr to 32-bit int cast */
201    src_offset = (GLuint) (unsigned long) pixels;
202
203    if (unpack->RowLength > 0)
204       src_stride = unpack->RowLength;
205    else
206       src_stride = width;
207
208    intel_miptree_get_image_offset(intelImage->mt, intelImage->level,
209                                   intelImage->face, 0,
210                                   &dst_x, &dst_y);
211
212    dst_stride = intelImage->mt->region->pitch;
213
214    if (drm_intel_bo_references(intel->batch.bo, dst_buffer))
215       intel_flush(&intel->ctx);
216
217    {
218       GLuint offset;
219       drm_intel_bo *src_buffer =
220               intel_bufferobj_source(intel, pbo, 64, &offset);
221
222       if (!intelEmitCopyBlit(intel,
223                              intelImage->mt->cpp,
224                              src_stride, src_buffer,
225                              src_offset + offset, GL_FALSE,
226                              dst_stride, dst_buffer, 0,
227                              intelImage->mt->region->tiling,
228                              0, 0, dst_x, dst_y, width, height,
229                              GL_COPY)) {
230          return GL_FALSE;
231       }
232    }
233
234    return GL_TRUE;
235 }
236
237
238 static GLboolean
239 try_pbo_zcopy(struct intel_context *intel,
240               struct intel_texture_image *intelImage,
241               const struct gl_pixelstore_attrib *unpack,
242               GLint internalFormat,
243               GLint width, GLint height,
244               GLenum format, GLenum type, const void *pixels)
245 {
246    struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
247    GLuint src_offset, src_stride;
248    GLuint dst_x, dst_y, dst_stride;
249
250    if (!_mesa_is_bufferobj(unpack->BufferObj) ||
251        intel->ctx._ImageTransferState ||
252        unpack->SkipPixels || unpack->SkipRows) {
253       DBG("%s: failure 1\n", __FUNCTION__);
254       return GL_FALSE;
255    }
256
257    /* note: potential 64-bit ptr to 32-bit int cast */
258    src_offset = (GLuint) (unsigned long) pixels;
259
260    if (unpack->RowLength > 0)
261       src_stride = unpack->RowLength;
262    else
263       src_stride = width;
264
265    intel_miptree_get_image_offset(intelImage->mt, intelImage->level,
266                                   intelImage->face, 0,
267                                   &dst_x, &dst_y);
268
269    dst_stride = intelImage->mt->region->pitch;
270
271    if (src_stride != dst_stride || dst_x != 0 || dst_y != 0 ||
272        src_offset != 0) {
273       DBG("%s: failure 2\n", __FUNCTION__);
274       return GL_FALSE;
275    }
276
277    intel_region_attach_pbo(intel, intelImage->mt->region, pbo);
278
279    return GL_TRUE;
280 }
281
282 /**
283  * \param scatter Scatter if true. Gather if false.
284  *
285  * \see intel_tex_image_x8z24_scatter
286  * \see intel_tex_image_x8z24_gather
287  */
288 static void
289 intel_tex_image_s8z24_scattergather(struct intel_context *intel,
290                                     struct intel_texture_image *intel_image,
291                                     bool scatter)
292 {
293    struct gl_context *ctx = &intel->ctx;
294    struct gl_renderbuffer *depth_rb = intel_image->depth_rb;
295    struct gl_renderbuffer *stencil_rb = intel_image->stencil_rb;
296
297    int w = intel_image->base.Width;
298    int h = intel_image->base.Height;
299
300    uint32_t depth_row[w];
301    uint8_t stencil_row[w];
302
303    intel_renderbuffer_map(intel, depth_rb);
304    intel_renderbuffer_map(intel, stencil_rb);
305
306    if (scatter) {
307       for (int y = 0; y < h; ++y) {
308          depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row);
309          for (int x = 0; x < w; ++x) {
310             stencil_row[x] = depth_row[x] >> 24;
311          }
312          stencil_rb->PutRow(ctx, stencil_rb, w, 0, y, stencil_row, NULL);
313       }
314    } else { /* gather */
315       for (int y = 0; y < h; ++y) {
316          depth_rb->GetRow(ctx, depth_rb, w, 0, y, depth_row);
317          stencil_rb->GetRow(ctx, stencil_rb, w, 0, y, stencil_row);
318          for (int x = 0; x < w; ++x) {
319             uint32_t s8_x24 = stencil_row[x] << 24;
320             uint32_t x8_z24 = depth_row[x] & 0x00ffffff;
321             depth_row[x] = s8_x24 | x8_z24;
322          }
323          depth_rb->PutRow(ctx, depth_rb, w, 0, y, depth_row, NULL);
324       }
325    }
326
327    intel_renderbuffer_unmap(intel, depth_rb);
328    intel_renderbuffer_unmap(intel, stencil_rb);
329 }
330
331 /**
332  * Copy the x8 bits from intel_image->depth_rb to intel_image->stencil_rb.
333  */
334 static void
335 intel_tex_image_s8z24_scatter(struct intel_context *intel,
336                               struct intel_texture_image *intel_image)
337 {
338    intel_tex_image_s8z24_scattergather(intel, intel_image, true);
339 }
340
341 /**
342  * Copy the data in intel_image->stencil_rb to the x8 bits in
343  * intel_image->depth_rb.
344  */
345 static void
346 intel_tex_image_s8z24_gather(struct intel_context *intel,
347                              struct intel_texture_image *intel_image)
348 {
349    intel_tex_image_s8z24_scattergather(intel, intel_image, false);
350 }
351
352 static bool
353 intel_tex_image_s8z24_create_renderbuffers(struct intel_context *intel,
354                                            struct intel_texture_image *image)
355 {
356    struct gl_context *ctx = &intel->ctx;
357
358    bool ok = true;
359    int width = image->base.Width;
360    int height = image->base.Height;
361    struct gl_renderbuffer *drb;
362    struct gl_renderbuffer *srb;
363    struct intel_renderbuffer *idrb;
364    struct intel_renderbuffer *isrb;
365
366    assert(intel->has_separate_stencil);
367    assert(image->base.TexFormat == MESA_FORMAT_S8_Z24);
368    assert(image->mt != NULL);
369
370    drb = intel_create_wrapped_renderbuffer(ctx, width, height,
371                                            MESA_FORMAT_X8_Z24);
372    srb = intel_create_wrapped_renderbuffer(ctx, width, height,
373                                            MESA_FORMAT_S8);
374
375    if (!drb || !srb) {
376       if (drb) {
377          drb->Delete(drb);
378       }
379       if (srb) {
380          srb->Delete(srb);
381       }
382       return false;
383    }
384
385    idrb = intel_renderbuffer(drb);
386    isrb = intel_renderbuffer(srb);
387
388    intel_region_reference(&idrb->region, image->mt->region);
389    ok = intel_alloc_renderbuffer_storage(ctx, srb, GL_STENCIL_INDEX8,
390                                          width, height);
391
392    if (!ok) {
393       drb->Delete(drb);
394       srb->Delete(srb);
395       return false;
396    }
397
398    intel_renderbuffer_set_draw_offset(idrb, image, 0);
399    intel_renderbuffer_set_draw_offset(isrb, image, 0);
400
401    _mesa_reference_renderbuffer(&image->depth_rb, drb);
402    _mesa_reference_renderbuffer(&image->stencil_rb, srb);
403
404    return true;
405 }
406
407 static void
408 intelTexImage(struct gl_context * ctx,
409               GLint dims,
410               GLenum target, GLint level,
411               GLint internalFormat,
412               GLint width, GLint height, GLint depth,
413               GLint border,
414               GLenum format, GLenum type, const void *pixels,
415               const struct gl_pixelstore_attrib *unpack,
416               struct gl_texture_object *texObj,
417               struct gl_texture_image *texImage, GLsizei imageSize,
418               GLboolean compressed)
419 {
420    struct intel_context *intel = intel_context(ctx);
421    struct intel_texture_object *intelObj = intel_texture_object(texObj);
422    struct intel_texture_image *intelImage = intel_texture_image(texImage);
423    GLint texelBytes, sizeInBytes;
424    GLuint dstRowStride = 0, srcRowStride = texImage->RowStride;
425
426    DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
427        _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
428
429    intelImage->face = target_to_face(target);
430    intelImage->level = level;
431
432    if (_mesa_is_format_compressed(texImage->TexFormat)) {
433       texelBytes = 0;
434    }
435    else {
436       texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
437
438       if (!intelImage->mt) {      
439           assert(texImage->RowStride == width);
440       }
441    }
442
443    ctx->Driver.FreeTexImageData(ctx, texImage);
444    assert(!intelImage->mt);
445
446    if (intelObj->mt &&
447        intel_miptree_match_image(intelObj->mt, &intelImage->base)) {
448       /* Use an existing miptree when possible */
449       intel_miptree_reference(&intelImage->mt, intelObj->mt);
450       assert(intelImage->mt);
451    } else if (intelImage->base.Border == 0) {
452       /* Didn't fit in the object miptree, but it's suitable for inclusion in
453        * a miptree, so create one just for our level and store it in the image.
454        * It'll get moved into the object miptree at validate time.
455        */
456       intelImage->mt = intel_miptree_create_for_teximage(intel, intelObj,
457                                                          intelImage,
458                                                          pixels == NULL);
459
460       /* Even if the object currently has a mipmap tree associated
461        * with it, this one is a more likely candidate to represent the
462        * whole object since our level didn't fit what was there
463        * before, and any lower levels would fit into our miptree.
464        */
465       if (intelImage->mt) {
466          intel_miptree_release(intel, &intelObj->mt);
467          intel_miptree_reference(&intelObj->mt, intelImage->mt);
468       }
469    }
470
471    /* PBO fastpaths:
472     */
473    if (dims <= 2 &&
474        intelImage->mt &&
475        _mesa_is_bufferobj(unpack->BufferObj) &&
476        check_pbo_format(internalFormat, format,
477                         type, intelImage->base.TexFormat)) {
478
479       DBG("trying pbo upload\n");
480
481       /* Attempt to texture directly from PBO data (zero copy upload).
482        *
483        * Currently disable as it can lead to worse as well as better
484        * performance (in particular when intel_region_cow() is
485        * required).
486        */
487       if (intelObj->mt == intelImage->mt &&
488           intelObj->mt->first_level == level &&
489           intelObj->mt->last_level == level) {
490
491          if (try_pbo_zcopy(intel, intelImage, unpack,
492                            internalFormat,
493                            width, height, format, type, pixels)) {
494
495             DBG("pbo zcopy upload succeeded\n");
496             return;
497          }
498       }
499
500
501       /* Otherwise, attempt to use the blitter for PBO image uploads.
502        */
503       if (try_pbo_upload(intel, intelImage, unpack,
504                          internalFormat,
505                          width, height, format, type, pixels)) {
506          DBG("pbo upload succeeded\n");
507          return;
508       }
509
510       DBG("pbo upload failed\n");
511    }
512
513    /* intelCopyTexImage calls this function with pixels == NULL, with
514     * the expectation that the mipmap tree will be set up but nothing
515     * more will be done.  This is where those calls return:
516     */
517    if (compressed) {
518       pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels,
519                                                       unpack,
520                                                       "glCompressedTexImage");
521    } else {
522       pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
523                                            format, type,
524                                            pixels, unpack, "glTexImage");
525    }
526
527    if (intelImage->mt) {
528       if (pixels != NULL) {
529          /* Flush any queued rendering with the texture before mapping. */
530          if (drm_intel_bo_references(intel->batch.bo,
531                                      intelImage->mt->region->buffer)) {
532             intel_flush(ctx);
533          }
534          texImage->Data = intel_miptree_image_map(intel,
535                                                   intelImage->mt,
536                                                   intelImage->face,
537                                                   intelImage->level,
538                                                   &dstRowStride,
539                                                   intelImage->base.ImageOffsets);
540       }
541
542       texImage->RowStride = dstRowStride / intelImage->mt->cpp;
543    }
544    else {
545       /* Allocate regular memory and store the image there temporarily.   */
546       if (_mesa_is_format_compressed(texImage->TexFormat)) {
547          sizeInBytes = _mesa_format_image_size(texImage->TexFormat,
548                                                texImage->Width,
549                                                texImage->Height,
550                                                texImage->Depth);
551          dstRowStride =
552             _mesa_format_row_stride(texImage->TexFormat, width);
553          assert(dims != 3);
554       }
555       else {
556          dstRowStride = width * texelBytes;
557          sizeInBytes = depth * dstRowStride * height;
558       }
559
560       texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
561    }
562
563    DBG("Upload image %dx%dx%d row_len %d "
564        "pitch %d pixels %d compressed %d\n",
565        width, height, depth, width * texelBytes, dstRowStride,
566        pixels ? 1 : 0, compressed);
567
568    /* Copy data.  Would like to know when it's ok for us to eg. use
569     * the blitter to copy.  Or, use the hardware to do the format
570     * conversion and copy:
571     */
572    if (pixels) {
573        if (compressed) {
574            if (intelImage->mt) {
575                struct intel_region *dst = intelImage->mt->region;
576                _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch,
577                                0, 0,
578                                intelImage->mt->level[level].width,
579                                (intelImage->mt->level[level].height+3)/4,
580                                pixels,
581                                srcRowStride,
582                                0, 0);
583            }
584            else {
585                memcpy(texImage->Data, pixels, imageSize);
586            }
587        }
588        else if (!_mesa_texstore(ctx, dims, 
589                                 texImage->_BaseFormat, 
590                                 texImage->TexFormat, 
591                                 texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
592                                 dstRowStride,
593                                 texImage->ImageOffsets,
594                                 width, height, depth,
595                                 format, type, pixels, unpack)) {
596           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
597        }
598
599        _mesa_unmap_teximage_pbo(ctx, unpack);
600    }
601
602    if (intel->must_use_separate_stencil
603        && texImage->TexFormat == MESA_FORMAT_S8_Z24) {
604       intel_tex_image_s8z24_create_renderbuffers(intel, intelImage);
605       intel_tex_image_s8z24_scatter(intel, intelImage);
606    }
607
608    if (intelImage->mt) {
609       if (pixels != NULL)
610          intel_miptree_image_unmap(intel, intelImage->mt);
611       texImage->Data = NULL;
612    }
613 }
614
615
616 static void
617 intelTexImage3D(struct gl_context * ctx,
618                 GLenum target, GLint level,
619                 GLint internalFormat,
620                 GLint width, GLint height, GLint depth,
621                 GLint border,
622                 GLenum format, GLenum type, const void *pixels,
623                 const struct gl_pixelstore_attrib *unpack,
624                 struct gl_texture_object *texObj,
625                 struct gl_texture_image *texImage)
626 {
627    intelTexImage(ctx, 3, target, level,
628                  internalFormat, width, height, depth, border,
629                  format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
630 }
631
632
633 static void
634 intelTexImage2D(struct gl_context * ctx,
635                 GLenum target, GLint level,
636                 GLint internalFormat,
637                 GLint width, GLint height, GLint border,
638                 GLenum format, GLenum type, const void *pixels,
639                 const struct gl_pixelstore_attrib *unpack,
640                 struct gl_texture_object *texObj,
641                 struct gl_texture_image *texImage)
642 {
643    intelTexImage(ctx, 2, target, level,
644                  internalFormat, width, height, 1, border,
645                  format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
646 }
647
648
649 static void
650 intelTexImage1D(struct gl_context * ctx,
651                 GLenum target, GLint level,
652                 GLint internalFormat,
653                 GLint width, GLint border,
654                 GLenum format, GLenum type, const void *pixels,
655                 const struct gl_pixelstore_attrib *unpack,
656                 struct gl_texture_object *texObj,
657                 struct gl_texture_image *texImage)
658 {
659    intelTexImage(ctx, 1, target, level,
660                  internalFormat, width, 1, 1, border,
661                  format, type, pixels, unpack, texObj, texImage, 0, GL_FALSE);
662 }
663
664
665 static void
666 intelCompressedTexImage2D( struct gl_context *ctx, GLenum target, GLint level,
667                            GLint internalFormat,
668                            GLint width, GLint height, GLint border,
669                            GLsizei imageSize, const GLvoid *data,
670                            struct gl_texture_object *texObj,
671                            struct gl_texture_image *texImage )
672 {
673    intelTexImage(ctx, 2, target, level,
674                  internalFormat, width, height, 1, border,
675                  0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, GL_TRUE);
676 }
677
678
679 /**
680  * Need to map texture image into memory before copying image data,
681  * then unmap it.
682  */
683 static void
684 intel_get_tex_image(struct gl_context * ctx, GLenum target, GLint level,
685                     GLenum format, GLenum type, GLvoid * pixels,
686                     struct gl_texture_object *texObj,
687                     struct gl_texture_image *texImage, GLboolean compressed)
688 {
689    struct intel_context *intel = intel_context(ctx);
690    struct intel_texture_image *intelImage = intel_texture_image(texImage);
691
692    /* If we're reading from a texture that has been rendered to, need to
693     * make sure rendering is complete.
694     * We could probably predicate this on texObj->_RenderToTexture
695     */
696    intel_flush(ctx);
697
698    /* Map */
699    if (intelImage->mt) {
700       /* Image is stored in hardware format in a buffer managed by the
701        * kernel.  Need to explicitly map and unmap it.
702        */
703       intelImage->base.Data =
704          intel_miptree_image_map(intel,
705                                  intelImage->mt,
706                                  intelImage->face,
707                                  intelImage->level,
708                                  &intelImage->base.RowStride,
709                                  intelImage->base.ImageOffsets);
710       intelImage->base.RowStride /= intelImage->mt->cpp;
711    }
712    else {
713       /* Otherwise, the image should actually be stored in
714        * intelImage->base.Data.  This is pretty confusing for
715        * everybody, I'd much prefer to separate the two functions of
716        * texImage->Data - storage for texture images in main memory
717        * and access (ie mappings) of images.  In other words, we'd
718        * create a new texImage->Map field and leave Data simply for
719        * storage.
720        */
721       assert(intelImage->base.Data);
722    }
723
724    if (intelImage->stencil_rb) {
725       /*
726        * The texture has packed depth/stencil format, but uses separate
727        * stencil. The texture's embedded stencil buffer contains the real
728        * stencil data, so copy that into the miptree.
729        */
730       intel_tex_image_s8z24_gather(intel, intelImage);
731    }
732
733    if (compressed) {
734       _mesa_get_compressed_teximage(ctx, target, level, pixels,
735                                     texObj, texImage);
736    }
737    else {
738       _mesa_get_teximage(ctx, target, level, format, type, pixels,
739                          texObj, texImage);
740    }
741      
742
743    /* Unmap */
744    if (intelImage->mt) {
745       intel_miptree_image_unmap(intel, intelImage->mt);
746       intelImage->base.Data = NULL;
747    }
748 }
749
750
751 static void
752 intelGetTexImage(struct gl_context * ctx, GLenum target, GLint level,
753                  GLenum format, GLenum type, GLvoid * pixels,
754                  struct gl_texture_object *texObj,
755                  struct gl_texture_image *texImage)
756 {
757    intel_get_tex_image(ctx, target, level, format, type, pixels,
758                        texObj, texImage, GL_FALSE);
759 }
760
761
762 static void
763 intelGetCompressedTexImage(struct gl_context *ctx, GLenum target, GLint level,
764                            GLvoid *pixels,
765                            struct gl_texture_object *texObj,
766                            struct gl_texture_image *texImage)
767 {
768    intel_get_tex_image(ctx, target, level, 0, 0, pixels,
769                        texObj, texImage, GL_TRUE);
770 }
771
772 void
773 intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
774                    GLint texture_format,
775                    __DRIdrawable *dPriv)
776 {
777    struct gl_framebuffer *fb = dPriv->driverPrivate;
778    struct intel_context *intel = pDRICtx->driverPrivate;
779    struct gl_context *ctx = &intel->ctx;
780    struct intel_texture_object *intelObj;
781    struct intel_texture_image *intelImage;
782    struct intel_mipmap_tree *mt;
783    struct intel_renderbuffer *rb;
784    struct gl_texture_object *texObj;
785    struct gl_texture_image *texImage;
786    int level = 0, internalFormat;
787    gl_format texFormat;
788
789    texObj = _mesa_get_current_tex_object(ctx, target);
790    intelObj = intel_texture_object(texObj);
791
792    if (!intelObj)
793       return;
794
795    if (dPriv->lastStamp != dPriv->dri2.stamp ||
796        !pDRICtx->driScreenPriv->dri2.useInvalidate)
797       intel_update_renderbuffers(pDRICtx, dPriv);
798
799    rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
800    /* If the region isn't set, then intel_update_renderbuffers was unable
801     * to get the buffers for the drawable.
802     */
803    if (rb->region == NULL)
804       return;
805
806    if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
807       internalFormat = GL_RGB;
808       texFormat = MESA_FORMAT_XRGB8888;
809    }
810    else {
811       internalFormat = GL_RGBA;
812       texFormat = MESA_FORMAT_ARGB8888;
813    }
814
815    mt = intel_miptree_create_for_region(intel, target, texFormat,
816                                         rb->region, 1);
817    if (mt == NULL)
818        return;
819
820    _mesa_lock_texture(&intel->ctx, texObj);
821
822    texImage = _mesa_get_tex_image(&intel->ctx, texObj, target, level);
823    intelImage = intel_texture_image(texImage);
824
825    if (intelImage->mt) {
826       intel_miptree_release(intel, &intelImage->mt);
827       assert(!texImage->Data);
828    }
829    if (intelObj->mt)
830       intel_miptree_release(intel, &intelObj->mt);
831
832    intelObj->mt = mt;
833
834    _mesa_init_teximage_fields(&intel->ctx, target, texImage,
835                               rb->region->width, rb->region->height, 1,
836                               0, internalFormat, texFormat);
837
838    intelImage->face = target_to_face(target);
839    intelImage->level = level;
840    texImage->RowStride = rb->region->pitch;
841    intel_miptree_reference(&intelImage->mt, intelObj->mt);
842
843    if (!intel_miptree_match_image(intelObj->mt, &intelImage->base)) {
844            fprintf(stderr, "miptree doesn't match image\n");
845    }
846
847    _mesa_unlock_texture(&intel->ctx, texObj);
848 }
849
850 void
851 intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
852 {
853    /* The old interface didn't have the format argument, so copy our
854     * implementation's behavior at the time.
855     */
856    intelSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
857 }
858
859 #if FEATURE_OES_EGL_image
860 static void
861 intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
862                               struct gl_texture_object *texObj,
863                               struct gl_texture_image *texImage,
864                               GLeglImageOES image_handle)
865 {
866    struct intel_context *intel = intel_context(ctx);
867    struct intel_texture_object *intelObj = intel_texture_object(texObj);
868    struct intel_texture_image *intelImage = intel_texture_image(texImage);
869    struct intel_mipmap_tree *mt;
870    __DRIscreen *screen;
871    __DRIimage *image;
872
873    screen = intel->intelScreen->driScrnPriv;
874    image = screen->dri2.image->lookupEGLImage(screen, image_handle,
875                                               screen->loaderPrivate);
876    if (image == NULL)
877       return;
878
879    mt = intel_miptree_create_for_region(intel, target, image->format,
880                                         image->region, 1);
881    if (mt == NULL)
882        return;
883
884    if (intelImage->mt) {
885       intel_miptree_release(intel, &intelImage->mt);
886       assert(!texImage->Data);
887    }
888    if (intelObj->mt)
889       intel_miptree_release(intel, &intelObj->mt);
890
891    intelObj->mt = mt;
892    _mesa_init_teximage_fields(&intel->ctx, target, texImage,
893                               image->region->width, image->region->height, 1,
894                               0, image->internal_format, image->format);
895
896    intelImage->face = target_to_face(target);
897    intelImage->level = 0;
898    texImage->RowStride = image->region->pitch;
899    intel_miptree_reference(&intelImage->mt, intelObj->mt);
900
901    if (!intel_miptree_match_image(intelObj->mt, &intelImage->base))
902       fprintf(stderr, "miptree doesn't match image\n");
903 }
904 #endif
905
906 void
907 intelInitTextureImageFuncs(struct dd_function_table *functions)
908 {
909    functions->TexImage1D = intelTexImage1D;
910    functions->TexImage2D = intelTexImage2D;
911    functions->TexImage3D = intelTexImage3D;
912    functions->GetTexImage = intelGetTexImage;
913
914    functions->CompressedTexImage2D = intelCompressedTexImage2D;
915    functions->GetCompressedTexImage = intelGetCompressedTexImage;
916
917 #if FEATURE_OES_EGL_image
918    functions->EGLImageTargetTexture2D = intel_image_target_texture_2d;
919 #endif
920 }