OSDN Git Service

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