intel: Implement GL_OES_EGL_image entrypoints
[mesa.git] / src / mesa / drivers / dri / intel / intel_tex_image.c
index f5d0dabebb64cacf81265c9112a258558786c911..f586aee99294a24acd392d9af966e4bf1a8aa0cb 100644 (file)
@@ -177,6 +177,7 @@ check_pbo_format(GLint internalFormat,
    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) &&
@@ -186,6 +187,11 @@ check_pbo_format(GLint internalFormat,
       return (format == GL_RGB &&
               type == GL_UNSIGNED_SHORT_5_6_5 &&
               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:
@@ -234,13 +240,15 @@ try_pbo_upload(struct intel_context *intel,
 
    if (drm_intel_bo_references(intel->batch->buf, dst_buffer))
       intelFlush(&intel->ctx);
+   intel_prepare_render(intel);
    {
       dri_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, 0, GL_FALSE,
+                            dst_stride, dst_buffer, 0,
+                            intelImage->mt->region->tiling,
                             0, 0, dst_x, dst_y, width, height,
                             GL_COPY)) {
         return GL_FALSE;
@@ -465,6 +473,8 @@ intelTexImage(GLcontext * ctx,
                                           pixels, unpack, "glTexImage");
    }
 
+   intel_prepare_render(intel);
+
    if (intelImage->mt) {
       if (pixels != NULL) {
         /* Flush any queued rendering with the texture before mapping. */
@@ -721,7 +731,7 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
 
 void
 intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
-                  GLint glx_texture_format,
+                  GLint texture_format,
                   __DRIdrawable *dPriv)
 {
    struct gl_framebuffer *fb = dPriv->driverPrivate;
@@ -741,7 +751,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
    if (!intelObj)
       return;
 
-   if (!dPriv->validBuffers)
+   if (dPriv->lastStamp != dPriv->dri2.stamp)
       intel_update_renderbuffers(pDRICtx, dPriv);
 
    rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT);
@@ -751,7 +761,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
    if (rb->region == NULL)
       return;
 
-   if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT)
+   if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
       internalFormat = GL_RGB;
    else
       internalFormat = GL_RGBA;
@@ -781,7 +791,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
 
    intelImage->face = target_to_face(target);
    intelImage->level = level;
-   if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT)
+   if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
       texImage->TexFormat = MESA_FORMAT_XRGB8888;
    else
       texImage->TexFormat = MESA_FORMAT_ARGB8888;
@@ -801,9 +811,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(GLcontext *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(intel->driContext, image_handle,
+                                             intel->driContext->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)
@@ -815,4 +873,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
 }