Merge branch 'llvm-cliptest-viewport'
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_image.c
index c5f52208376e98a8ad2d5bc04ef1a4cb9bc86631..35f3d7d38290c03677f6a2f411da76a6a2c892af 100644 (file)
@@ -1,20 +1,15 @@
 
-#include <stdlib.h>
-#include <stdio.h>
-
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/mtypes.h"
 #include "main/enums.h"
-#include "main/colortab.h"
-#include "main/convolve.h"
+#include "main/bufferobj.h"
 #include "main/context.h"
-#include "main/simple_list.h"
+#include "main/formats.h"
 #include "main/texcompress.h"
-#include "main/texformat.h"
+#include "main/texstore.h"
 #include "main/texgetimage.h"
 #include "main/texobj.h"
-#include "main/texstore.h"
 #include "main/teximage.h"
 
 #include "intel_context.h"
@@ -73,13 +68,11 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
    GLuint depth = intelImage->base.Depth;
    GLuint l2width, l2height, l2depth;
    GLuint i, comp_byte = 0;
+   GLuint texelBytes;
 
    DBG("%s\n", __FUNCTION__);
 
-   if (intelImage->base.Border ||
-       ((intelImage->base._BaseFormat == GL_DEPTH_COMPONENT) && 
-        ((intelObj->base.WrapS == GL_CLAMP_TO_BORDER) ||
-         (intelObj->base.WrapT == GL_CLAMP_TO_BORDER))))
+   if (intelImage->base.Border)
       return;
 
    if (intelImage->level > intelObj->base.BaseLevel &&
@@ -116,7 +109,8 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
     */
    if ((intelObj->base.MinFilter == GL_NEAREST ||
         intelObj->base.MinFilter == GL_LINEAR) &&
-       intelImage->level == firstLevel) {
+       intelImage->level == firstLevel &&
+       (intel->gen < 4 || firstLevel == 0)) {
       lastLevel = firstLevel;
    }
    else {
@@ -127,8 +121,11 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
    }
 
    assert(!intelObj->mt);
-   if (intelImage->base.IsCompressed)
-      comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
+   if (_mesa_is_format_compressed(intelImage->base.TexFormat))
+      comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat);
+
+   texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat);
+
    intelObj->mt = intel_miptree_create(intel,
                                        intelObj->base.Target,
                                        intelImage->base._BaseFormat,
@@ -138,7 +135,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel,
                                        width,
                                        height,
                                        depth,
-                                       intelImage->base.TexFormat->TexelBytes,
+                                       texelBytes,
                                        comp_byte,
                                       expect_accelerated_upload);
 
@@ -170,20 +167,26 @@ target_to_face(GLenum target)
 static GLboolean
 check_pbo_format(GLint internalFormat,
                  GLenum format, GLenum type,
-                 const struct gl_texture_format *mesa_format)
+                 gl_format mesa_format)
 {
    switch (internalFormat) {
    case 4:
    case GL_RGBA:
+   case GL_RGBA8:
       return (format == GL_BGRA &&
               (type == GL_UNSIGNED_BYTE ||
                type == GL_UNSIGNED_INT_8_8_8_8_REV) &&
-              mesa_format == &_mesa_texformat_argb8888);
+              mesa_format == MESA_FORMAT_ARGB8888);
    case 3:
    case GL_RGB:
       return (format == GL_RGB &&
               type == GL_UNSIGNED_SHORT_5_6_5 &&
-              mesa_format == &_mesa_texformat_rgb565);
+              mesa_format == MESA_FORMAT_RGB565);
+   case 1:
+   case GL_LUMINANCE:
+      return (format == GL_LUMINANCE &&
+             type == GL_UNSIGNED_BYTE &&
+             mesa_format == MESA_FORMAT_L8);
    case GL_YCBCR_MESA:
       return (type == GL_UNSIGNED_SHORT_8_8_MESA || type == GL_UNSIGNED_BYTE);
    default:
@@ -204,9 +207,12 @@ try_pbo_upload(struct intel_context *intel,
 {
    struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
    GLuint src_offset, src_stride;
-   GLuint dst_offset, dst_stride;
+   GLuint dst_x, dst_y, dst_stride;
+   drm_intel_bo *dst_buffer = intel_region_buffer(intel,
+                                                 intelImage->mt->region,
+                                                 INTEL_WRITE_FULL);
 
-   if (unpack->BufferObj->Name == 0 ||
+   if (!_mesa_is_bufferobj(unpack->BufferObj) ||
        intel->ctx._ImageTransferState ||
        unpack->SkipPixels || unpack->SkipRows) {
       DBG("%s: failure 1\n", __FUNCTION__);
@@ -221,32 +227,28 @@ try_pbo_upload(struct intel_context *intel,
    else
       src_stride = width;
 
-   dst_offset = intel_miptree_image_offset(intelImage->mt,
-                                           intelImage->face,
-                                           intelImage->level);
+   intel_miptree_get_image_offset(intelImage->mt, intelImage->level,
+                                 intelImage->face, 0,
+                                 &dst_x, &dst_y);
 
-   dst_stride = intelImage->mt->pitch;
+   dst_stride = intelImage->mt->region->pitch;
 
-   intelFlush(&intel->ctx);
-   LOCK_HARDWARE(intel);
-   {
-      dri_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ);
-      dri_bo *dst_buffer = intel_region_buffer(intel,
-                                              intelImage->mt->region,
-                                              INTEL_WRITE_FULL);
+   if (drm_intel_bo_references(intel->batch->buf, dst_buffer))
+      intel_flush(&intel->ctx);
 
+   {
+      drm_intel_bo *src_buffer = intel_bufferobj_buffer(intel, pbo, INTEL_READ);
 
       if (!intelEmitCopyBlit(intel,
                             intelImage->mt->cpp,
                             src_stride, src_buffer, src_offset, GL_FALSE,
-                            dst_stride, dst_buffer, dst_offset, GL_FALSE,
-                            0, 0, 0, 0, width, height,
+                            dst_stride, dst_buffer, 0,
+                            intelImage->mt->region->tiling,
+                            0, 0, dst_x, dst_y, width, height,
                             GL_COPY)) {
-        UNLOCK_HARDWARE(intel);
         return GL_FALSE;
       }
    }
-   UNLOCK_HARDWARE(intel);
 
    return GL_TRUE;
 }
@@ -262,9 +264,9 @@ try_pbo_zcopy(struct intel_context *intel,
 {
    struct intel_buffer_object *pbo = intel_buffer_object(unpack->BufferObj);
    GLuint src_offset, src_stride;
-   GLuint dst_offset, dst_stride;
+   GLuint dst_x, dst_y, dst_stride;
 
-   if (unpack->BufferObj->Name == 0 ||
+   if (!_mesa_is_bufferobj(unpack->BufferObj) ||
        intel->ctx._ImageTransferState ||
        unpack->SkipPixels || unpack->SkipRows) {
       DBG("%s: failure 1\n", __FUNCTION__);
@@ -279,13 +281,14 @@ try_pbo_zcopy(struct intel_context *intel,
    else
       src_stride = width;
 
-   dst_offset = intel_miptree_image_offset(intelImage->mt,
-                                           intelImage->face,
-                                           intelImage->level);
+   intel_miptree_get_image_offset(intelImage->mt, intelImage->level,
+                                 intelImage->face, 0,
+                                 &dst_x, &dst_y);
 
-   dst_stride = intelImage->mt->pitch;
+   dst_stride = intelImage->mt->region->pitch;
 
-   if (src_stride != dst_stride || dst_offset != 0 || src_offset != 0) {
+   if (src_stride != dst_stride || dst_x != 0 || dst_y != 0 ||
+       src_offset != 0) {
       DBG("%s: failure 2\n", __FUNCTION__);
       return GL_FALSE;
    }
@@ -297,7 +300,7 @@ try_pbo_zcopy(struct intel_context *intel,
 
 
 static void
-intelTexImage(GLcontext * ctx,
+intelTexImage(struct gl_context * ctx,
               GLint dims,
               GLenum target, GLint level,
               GLint internalFormat,
@@ -312,49 +315,23 @@ intelTexImage(GLcontext * ctx,
    struct intel_context *intel = intel_context(ctx);
    struct intel_texture_object *intelObj = intel_texture_object(texObj);
    struct intel_texture_image *intelImage = intel_texture_image(texImage);
-   GLint postConvWidth = width;
-   GLint postConvHeight = height;
    GLint texelBytes, sizeInBytes;
    GLuint dstRowStride = 0, srcRowStride = texImage->RowStride;
 
    DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
        _mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
 
-   intelFlush(ctx);
-
    intelImage->face = target_to_face(target);
    intelImage->level = level;
 
-   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
-      _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
-                                         &postConvHeight);
-   }
-
-   /* choose the texture format */
-   texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat,
-                                                  format, type);
-
-   _mesa_set_fetch_functions(texImage, dims);
-
-   if (texImage->TexFormat->TexelBytes == 0) {
-      /* must be a compressed format */
+   if (_mesa_is_format_compressed(texImage->TexFormat)) {
       texelBytes = 0;
-      texImage->IsCompressed = GL_TRUE;
-      texImage->CompressedSize =
-        ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
-                                          texImage->Height, texImage->Depth,
-                                          texImage->TexFormat->MesaFormat);
-   } else {
-      texelBytes = texImage->TexFormat->TexelBytes;
-      
-      /* Minimum pitch of 32 bytes */
-      if (postConvWidth * texelBytes < 32) {
-        postConvWidth = 32 / texelBytes;
-        texImage->RowStride = postConvWidth;
-      }
+   }
+   else {
+      texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
 
       if (!intelImage->mt) {      
-         assert(texImage->RowStride == postConvWidth);
+         assert(texImage->RowStride == width);
       }
    }
 
@@ -378,8 +355,7 @@ intelTexImage(GLcontext * ctx,
        intelObj->mt->first_level == level &&
        intelObj->mt->last_level == level &&
        intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
-       !intel_miptree_match_image(intelObj->mt, &intelImage->base,
-                                  intelImage->face, intelImage->level)) {
+       !intel_miptree_match_image(intelObj->mt, &intelImage->base)) {
 
       DBG("release it\n");
       intel_miptree_release(intel, &intelObj->mt);
@@ -396,17 +372,17 @@ intelTexImage(GLcontext * ctx,
    assert(!intelImage->mt);
 
    if (intelObj->mt &&
-       intel_miptree_match_image(intelObj->mt, &intelImage->base,
-                                 intelImage->face, intelImage->level)) {
+       intel_miptree_match_image(intelObj->mt, &intelImage->base)) {
 
       intel_miptree_reference(&intelImage->mt, intelObj->mt);
       assert(intelImage->mt);
    } else if (intelImage->base.Border == 0) {
       int comp_byte = 0;
-
-      if (intelImage->base.IsCompressed) {
+      GLuint texelBytes = _mesa_get_format_bytes(intelImage->base.TexFormat);
+      GLenum baseFormat = _mesa_get_format_base_format(intelImage->base.TexFormat);
+      if (_mesa_is_format_compressed(intelImage->base.TexFormat)) {
         comp_byte =
-           intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat);
+           intel_compressed_num_bytes(intelImage->base.TexFormat);
       }
 
       /* Didn't fit in the object miptree, but it's suitable for inclusion in
@@ -414,11 +390,11 @@ intelTexImage(GLcontext * ctx,
        * It'll get moved into the object miptree at validate time.
        */
       intelImage->mt = intel_miptree_create(intel, target,
-                                           intelImage->base.TexFormat->BaseFormat,
+                                           baseFormat,
                                            internalFormat,
                                            level, level,
                                            width, height, depth,
-                                           intelImage->base.TexFormat->TexelBytes,
+                                           texelBytes,
                                            comp_byte, pixels == NULL);
 
    }
@@ -427,7 +403,7 @@ intelTexImage(GLcontext * ctx,
     */
    if (dims <= 2 &&
        intelImage->mt &&
-       unpack->BufferObj->Name != 0 &&
+       _mesa_is_bufferobj(unpack->BufferObj) &&
        check_pbo_format(internalFormat, format,
                         type, intelImage->base.TexFormat)) {
 
@@ -479,29 +455,37 @@ intelTexImage(GLcontext * ctx,
                                           pixels, unpack, "glTexImage");
    }
 
-   LOCK_HARDWARE(intel);
-
    if (intelImage->mt) {
-      if (pixels != NULL)
+      if (pixels != NULL) {
+        /* Flush any queued rendering with the texture before mapping. */
+        if (drm_intel_bo_references(intel->batch->buf,
+                                    intelImage->mt->region->buffer)) {
+           intel_flush(ctx);
+        }
          texImage->Data = intel_miptree_image_map(intel,
                                                   intelImage->mt,
                                                   intelImage->face,
                                                   intelImage->level,
                                                   &dstRowStride,
                                                   intelImage->base.ImageOffsets);
+      }
+
       texImage->RowStride = dstRowStride / intelImage->mt->cpp;
    }
    else {
       /* Allocate regular memory and store the image there temporarily.   */
-      if (texImage->IsCompressed) {
-         sizeInBytes = texImage->CompressedSize;
+      if (_mesa_is_format_compressed(texImage->TexFormat)) {
+         sizeInBytes = _mesa_format_image_size(texImage->TexFormat,
+                                               texImage->Width,
+                                               texImage->Height,
+                                               texImage->Depth);
          dstRowStride =
-            _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+            _mesa_format_row_stride(texImage->TexFormat, width);
          assert(dims != 3);
       }
       else {
-         dstRowStride = postConvWidth * texelBytes;
-         sizeInBytes = depth * dstRowStride * postConvHeight;
+         dstRowStride = width * texelBytes;
+         sizeInBytes = depth * dstRowStride * height;
       }
 
       texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
@@ -527,17 +511,20 @@ intelTexImage(GLcontext * ctx,
                               pixels,
                               srcRowStride,
                               0, 0);
-          } else
+          }
+           else {
               memcpy(texImage->Data, pixels, imageSize);
-       } else if (!texImage->TexFormat->StoreImage(ctx, dims, 
-                                                  texImage->_BaseFormat, 
-                                                  texImage->TexFormat, 
-                                                  texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
-                                                  dstRowStride,
-                                                  texImage->ImageOffsets,
-                                                  width, height, depth,
-                                                  format, type, pixels, unpack)) {
-          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+           }
+       }
+       else if (!_mesa_texstore(ctx, dims, 
+                                texImage->_BaseFormat, 
+                                texImage->TexFormat, 
+                                texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */
+                                dstRowStride,
+                                texImage->ImageOffsets,
+                                width, height, depth,
+                                format, type, pixels, unpack)) {
+          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
        }
    }
 
@@ -548,18 +535,11 @@ intelTexImage(GLcontext * ctx,
          intel_miptree_image_unmap(intel, intelImage->mt);
       texImage->Data = NULL;
    }
-
-   UNLOCK_HARDWARE(intel);
-
-   /* GL_SGIS_generate_mipmap */
-   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
-      intel_generate_mipmap(ctx, target, texObj);
-   }
 }
 
 
 static void
-intelTexImage3D(GLcontext * ctx,
+intelTexImage3D(struct gl_context * ctx,
                 GLenum target, GLint level,
                 GLint internalFormat,
                 GLint width, GLint height, GLint depth,
@@ -576,7 +556,7 @@ intelTexImage3D(GLcontext * ctx,
 
 
 static void
-intelTexImage2D(GLcontext * ctx,
+intelTexImage2D(struct gl_context * ctx,
                 GLenum target, GLint level,
                 GLint internalFormat,
                 GLint width, GLint height, GLint border,
@@ -592,7 +572,7 @@ intelTexImage2D(GLcontext * ctx,
 
 
 static void
-intelTexImage1D(GLcontext * ctx,
+intelTexImage1D(struct gl_context * ctx,
                 GLenum target, GLint level,
                 GLint internalFormat,
                 GLint width, GLint border,
@@ -608,7 +588,7 @@ intelTexImage1D(GLcontext * ctx,
 
 
 static void
-intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
+intelCompressedTexImage2D( struct gl_context *ctx, GLenum target, GLint level,
                            GLint internalFormat,
                            GLint width, GLint height, GLint border,
                            GLsizei imageSize, const GLvoid *data,
@@ -626,7 +606,7 @@ intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
  * then unmap it.
  */
 static void
-intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
+intel_get_tex_image(struct gl_context * ctx, GLenum target, GLint level,
                    GLenum format, GLenum type, GLvoid * pixels,
                    struct gl_texture_object *texObj,
                    struct gl_texture_image *texImage, GLboolean compressed)
@@ -638,7 +618,7 @@ intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
     * make sure rendering is complete.
     * We could probably predicate this on texObj->_RenderToTexture
     */
-   intelFlush(ctx);
+   intel_flush(ctx);
 
    /* Map */
    if (intelImage->mt) {
@@ -670,9 +650,10 @@ intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
    if (compressed) {
       _mesa_get_compressed_teximage(ctx, target, level, pixels,
                                    texObj, texImage);
-   } else {
+   }
+   else {
       _mesa_get_teximage(ctx, target, level, format, type, pixels,
-                        texObj, texImage);
+                         texObj, texImage);
    }
      
 
@@ -685,7 +666,7 @@ intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
 
 
 static void
-intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
+intelGetTexImage(struct gl_context * ctx, GLenum target, GLint level,
                  GLenum format, GLenum type, GLvoid * pixels,
                  struct gl_texture_object *texObj,
                  struct gl_texture_image *texImage)
@@ -696,7 +677,7 @@ intelGetTexImage(GLcontext * ctx, GLenum target, GLint level,
 
 
 static void
-intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
+intelGetCompressedTexImage(struct gl_context *ctx, GLenum target, GLint level,
                           GLvoid *pixels,
                           struct gl_texture_object *texObj,
                           struct gl_texture_image *texImage)
@@ -705,64 +686,40 @@ intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level,
                       texObj, texImage, GL_TRUE);
 }
 
-
-void
-intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
-                 unsigned long long offset, GLint depth, GLuint pitch)
-{
-   struct intel_context *intel = pDRICtx->driverPrivate;
-   struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname);
-   struct intel_texture_object *intelObj = intel_texture_object(tObj);
-
-   if (!intelObj)
-      return;
-
-   if (intelObj->mt)
-      intel_miptree_release(intel, &intelObj->mt);
-
-   intelObj->imageOverride = GL_TRUE;
-   intelObj->depthOverride = depth;
-   intelObj->pitchOverride = pitch;
-
-   if (offset)
-      intelObj->textureOffset = offset;
-}
-
 void
 intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
-                  GLint glx_texture_format,
+                  GLint texture_format,
                   __DRIdrawable *dPriv)
 {
-   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   struct gl_framebuffer *fb = dPriv->driverPrivate;
    struct intel_context *intel = pDRICtx->driverPrivate;
+   struct gl_context *ctx = &intel->ctx;
    struct intel_texture_object *intelObj;
    struct intel_texture_image *intelImage;
    struct intel_mipmap_tree *mt;
    struct intel_renderbuffer *rb;
-   struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   int level = 0, type, format, internalFormat;
+   int level = 0, internalFormat;
 
-   texUnit = &intel->ctx.Texture.Unit[intel->ctx.Texture.CurrentUnit];
-   texObj = _mesa_select_tex_object(&intel->ctx, texUnit, target);
+   texObj = _mesa_get_current_tex_object(ctx, target);
    intelObj = intel_texture_object(texObj);
 
    if (!intelObj)
       return;
 
-   intel_update_renderbuffers(pDRICtx, dPriv);
+   if (dPriv->lastStamp != dPriv->dri2.stamp ||
+       !pDRICtx->driScreenPriv->dri2.useInvalidate)
+      intel_update_renderbuffers(pDRICtx, dPriv);
 
-   rb = intel_fb->color_rb[0];
+   rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
    /* If the region isn't set, then intel_update_renderbuffers was unable
     * to get the buffers for the drawable.
     */
    if (rb->region == NULL)
       return;
 
-   type = GL_BGRA;
-   format = GL_UNSIGNED_BYTE;
-   if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT)
+   if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
       internalFormat = GL_RGB;
    else
       internalFormat = GL_RGBA;
@@ -792,14 +749,14 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
 
    intelImage->face = target_to_face(target);
    intelImage->level = level;
-   texImage->TexFormat = intelChooseTextureFormat(&intel->ctx, internalFormat,
-                                                  type, format);
-   _mesa_set_fetch_functions(texImage, 2);
+   if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
+      texImage->TexFormat = MESA_FORMAT_XRGB8888;
+   else
+      texImage->TexFormat = MESA_FORMAT_ARGB8888;
    texImage->RowStride = rb->region->pitch;
    intel_miptree_reference(&intelImage->mt, intelObj->mt);
 
-   if (!intel_miptree_match_image(intelObj->mt, &intelImage->base,
-                                 intelImage->face, intelImage->level)) {
+   if (!intel_miptree_match_image(intelObj->mt, &intelImage->base)) {
           fprintf(stderr, "miptree doesn't match image\n");
    }
 
@@ -812,9 +769,57 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
    /* The old interface didn't have the format argument, so copy our
     * implementation's behavior at the time.
     */
-   intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
+   intelSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
 }
 
+#if FEATURE_OES_EGL_image
+static void
+intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
+                             struct gl_texture_object *texObj,
+                             struct gl_texture_image *texImage,
+                             GLeglImageOES image_handle)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_texture_object *intelObj = intel_texture_object(texObj);
+   struct intel_texture_image *intelImage = intel_texture_image(texImage);
+   struct intel_mipmap_tree *mt;
+   __DRIscreen *screen;
+   __DRIimage *image;
+
+   screen = intel->intelScreen->driScrnPriv;
+   image = screen->dri2.image->lookupEGLImage(screen, image_handle,
+                                             screen->loaderPrivate);
+   if (image == NULL)
+      return;
+
+   mt = intel_miptree_create_for_region(intel, target,
+                                       image->internal_format,
+                                       0, 0, image->region, 1, 0);
+   if (mt == NULL)
+       return;
+
+   if (intelImage->mt) {
+      intel_miptree_release(intel, &intelImage->mt);
+      assert(!texImage->Data);
+   }
+   if (intelObj->mt)
+      intel_miptree_release(intel, &intelObj->mt);
+
+   intelObj->mt = mt;
+   _mesa_init_teximage_fields(&intel->ctx, target, texImage,
+                             image->region->width, image->region->height, 1,
+                             0, image->internal_format);
+
+   intelImage->face = target_to_face(target);
+   intelImage->level = 0;
+   texImage->TexFormat = image->format;
+   texImage->RowStride = image->region->pitch;
+   intel_miptree_reference(&intelImage->mt, intelObj->mt);
+
+   if (!intel_miptree_match_image(intelObj->mt, &intelImage->base))
+      fprintf(stderr, "miptree doesn't match image\n");
+}
+#endif
 
 void
 intelInitTextureImageFuncs(struct dd_function_table *functions)
@@ -826,4 +831,8 @@ intelInitTextureImageFuncs(struct dd_function_table *functions)
 
    functions->CompressedTexImage2D = intelCompressedTexImage2D;
    functions->GetCompressedTexImage = intelGetCompressedTexImage;
+
+#if FEATURE_OES_EGL_image
+   functions->EGLImageTargetTexture2D = intel_image_target_texture_2d;
+#endif
 }