commit 7755e7b36df990f5db443c613b2d6b69e18c75b7
Author: Kristian Høgsberg <krh@redhat.com>
Date:   Sat Sep 12 09:55:17 2009 -0400

    Native FBO hooks

diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 804c034..6a822e2 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -94,23 +94,13 @@ intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb,
    return NULL;
 }
 
-
-/**
- * Called via glRenderbufferStorageEXT() to set the format and allocate
- * storage for a user-created renderbuffer.
- */
-static GLboolean
-intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
-                                 GLenum internalFormat,
-                                 GLuint width, GLuint height)
+static int
+intel_get_format_data(GLcontext *ctx,
+		      GLenum internalFormat, struct intel_renderbuffer *irb)
 {
-   struct intel_context *intel = intel_context(ctx);
-   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
-   GLboolean softwareBuffer = GL_FALSE;
+   struct gl_renderbuffer *rb = &irb->Base;
    int cpp;
 
-   ASSERT(rb->Name != 0);
-
    switch (internalFormat) {
    case GL_R3_G3_B2:
    case GL_RGB4:
@@ -194,9 +184,64 @@ intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    default:
       _mesa_problem(ctx,
                     "Unexpected format in intel_alloc_renderbuffer_storage");
-      return GL_FALSE;
+      cpp = 0;
+      break;
    }
 
+   return cpp;
+}
+
+void
+_mesa_RenderbufferExternalMESA(GLint target,
+			       GLint internalFormat,
+			       GLuint width, GLuint height,
+			       GLuint pitch, GLuint handle)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct intel_context *intel = intel_context(ctx);
+   struct gl_renderbuffer *rb;
+   struct intel_renderbuffer *irb;
+   int cpp;
+
+   rb = ctx->CurrentRenderbuffer;
+   if (!rb) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
+      return;
+   }
+
+   irb = intel_renderbuffer(rb);
+   cpp = intel_get_format_data(ctx, internalFormat, irb);
+
+   irb->region = intel_region_alloc_for_handle(intel, cpp,
+					       width, height, pitch,
+					       handle, "foregin rb storage");
+   if (!irb->region)
+      return;
+
+   ASSERT(irb->region->buffer);
+
+   rb->Width = width;
+   rb->Height = height;
+}
+
+/**
+ * Called via glRenderbufferStorageEXT() to set the format and allocate
+ * storage for a user-created renderbuffer.
+ */
+static GLboolean
+intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
+                                 GLenum internalFormat,
+                                 GLuint width, GLuint height)
+{
+   struct intel_context *intel = intel_context(ctx);
+   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+   GLboolean softwareBuffer = GL_FALSE;
+   int cpp;
+
+   ASSERT(rb->Name != 0);
+
+   cpp = intel_get_format_data(ctx, internalFormat, irb);
+
    intelFlush(ctx);
 
    /* free old region */
diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h
index 471aa2a..ecb707f 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.h
+++ b/src/mesa/drivers/dri/intel/intel_tex.h
@@ -52,6 +52,11 @@ void intelSetTexBuffer(__DRIcontext *pDRICtx,
 		       GLint target, __DRIdrawable *pDraw);
 void intelSetTexBuffer2(__DRIcontext *pDRICtx,
 			GLint target, GLint format, __DRIdrawable *pDraw);
+void intelSetTexBuffer3(__DRIcontext *pDRICtx, GLint target,
+			GLint glx_texture_format,
+			GLuint cpp,
+			GLuint width, GLuint height,
+			GLuint pitch, GLuint handle);
 
 GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit);
 
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index a206fe6..dddf317 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -724,17 +724,15 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
       intelObj->textureOffset = offset;
 }
 
-void
-intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
-		   GLint glx_texture_format,
-		   __DRIdrawable *dPriv)
+static void
+intelSetTexBufferRegion(GLcontext *ctx, GLint target,
+			GLint glx_texture_format,
+			struct intel_region *region)
 {
-   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
-   struct intel_context *intel = pDRICtx->driverPrivate;
+   struct intel_context *intel = intel_context(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;
@@ -747,15 +745,6 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
    if (!intelObj)
       return;
 
-   intel_update_renderbuffers(pDRICtx, dPriv);
-
-   rb = intel_fb->color_rb[0];
-   /* 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)
@@ -765,7 +754,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
 
    mt = intel_miptree_create_for_region(intel, target,
 					internalFormat,
-					0, 0, rb->region, 1, 0);
+					0, 0, region, 1, 0);
    if (mt == NULL)
        return;
 
@@ -783,7 +772,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
 
    intelObj->mt = mt;
    _mesa_init_teximage_fields(&intel->ctx, target, texImage,
-			      rb->region->width, rb->region->height, 1,
+			      region->width, region->height, 1,
 			      0, internalFormat);
 
    intelImage->face = target_to_face(target);
@@ -791,7 +780,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
    texImage->TexFormat = intelChooseTextureFormat(&intel->ctx, internalFormat,
                                                   type, format);
    _mesa_set_fetch_functions(texImage, 2);
-   texImage->RowStride = rb->region->pitch;
+   texImage->RowStride = region->pitch;
    intel_miptree_reference(&intelImage->mt, intelObj->mt);
 
    if (!intel_miptree_match_image(intelObj->mt, &intelImage->base,
@@ -803,6 +792,49 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
 }
 
 void
+_mesa_TextureExternalMESA(GLint target,
+			  GLint glx_texture_format,
+			  GLuint cpp,
+			  GLuint width, GLuint height,
+			  GLuint pitch, GLuint handle)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct intel_region *region;
+   struct intel_context *intel = intel_context(ctx);
+
+   region = intel_region_alloc_for_handle(intel,
+					  cpp,
+					  width, height, pitch,
+					  handle, "foreign region");
+
+   intelSetTexBufferRegion(ctx, target, glx_texture_format, region);
+
+   intel_region_release(&region);
+}
+
+void
+intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
+		   GLint glx_texture_format,
+		   __DRIdrawable *dPriv)
+{
+   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
+   struct intel_renderbuffer *rb;
+   GLcontext *ctx = pDRICtx->driverPrivate;
+
+   intel_update_renderbuffers(pDRICtx, dPriv);
+
+   rb = intel_fb->color_rb[0];
+   /* If the region isn't set, then intel_update_renderbuffers was unable
+    * to get the buffers for the drawable.
+    */
+   if (rb->region == NULL)
+      return;
+
+   return intelSetTexBufferRegion(ctx, target,
+				  glx_texture_format, rb->region);
+}
+
+void
 intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
 {
    /* The old interface didn't have the format argument, so copy our
