intel: Implement DRI image extension
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 11 Feb 2010 23:59:40 +0000 (18:59 -0500)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 24 Feb 2010 19:28:42 +0000 (14:28 -0500)
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/common/dri_util.h
src/mesa/drivers/dri/intel/intel_regions.h
src/mesa/drivers/dri/intel/intel_screen.c

index 9142dd72f5a00d16cdb850a985e2dbbe5fd06202..b80b608f4b98c633aba37680a16cbe15049c9377 100644 (file)
@@ -675,6 +675,8 @@ setupLoaderExtensions(__DRIscreen *psp,
            psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
        if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0)
            psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i];
+       if (strcmp(extensions[i]->name, __DRI_IMAGE_LOOKUP) == 0)
+           psp->dri2.image = (__DRIimageLookupExtension *) extensions[i];
     }
 }
 
index 2eadb9ac8c52296d64b803179e9087f5938f99d0..99c0f1e442233c00d1316f728eab811d5c47980d 100644 (file)
@@ -544,6 +544,7 @@ struct __DRIscreenRec {
         * fields will not be valid or initializaed in that case. */
        int enabled;
        __DRIdri2LoaderExtension *loader;
+       __DRIimageLookupExtension *image;
     } dri2;
 
     /* The lock actually in use, old sarea or DRI2 */
index 6d36f3d88a0dc27413914775bd3c71729672381b..7ee6a988eae3d9c518648c12628bdd801deaf87c 100644 (file)
@@ -148,4 +148,12 @@ void _mesa_copy_rect(GLubyte * dst,
                 const GLubyte * src,
                 GLuint src_pitch, GLuint src_x, GLuint src_y);
 
+struct __DRIimageRec {
+   struct intel_region *region;
+   GLenum internal_format;
+   GLuint format;
+   GLenum data_type;
+   void *data;
+};
+
 #endif
index 5e23aa8a1d6138c48da1a593caee7c0d71fe4419..f19e2ee81d48ce1ad093e8384a3056f867516e80 100644 (file)
@@ -41,6 +41,7 @@
 #include "intel_fbo.h"
 #include "intel_screen.h"
 #include "intel_tex.h"
+#include "intel_regions.h"
 
 #include "i915_drm.h"
 
@@ -137,11 +138,103 @@ static const struct __DRI2flushExtensionRec intelFlushExtension = {
     intelDRI2Invalidate,
 };
 
+static __DRIimage *
+intel_create_image_from_name(__DRIcontext *context,
+                            int width, int height, int format,
+                            int name, int pitch, void *loaderPrivate)
+{
+    __DRIimage *image;
+    struct intel_context *intel = context->driverPrivate;
+    int cpp;
+
+    image = CALLOC(sizeof *image);
+    if (image == NULL)
+       return NULL;
+
+    switch (format) {
+    case __DRI_IMAGE_FORMAT_RGB565:
+       image->format = MESA_FORMAT_RGB565;
+       image->internal_format = GL_RGB;
+       image->data_type = GL_UNSIGNED_BYTE;
+       break;
+    case __DRI_IMAGE_FORMAT_XRGB8888:
+       image->format = MESA_FORMAT_XRGB8888;
+       image->internal_format = GL_RGB;
+       image->data_type = GL_UNSIGNED_BYTE;
+       break;
+    case __DRI_IMAGE_FORMAT_ARGB8888:
+       image->format = MESA_FORMAT_ARGB8888;
+       image->internal_format = GL_RGBA;
+       image->data_type = GL_UNSIGNED_BYTE;
+       break;
+    default:
+       free(image);
+       return NULL;
+    }
+
+    image->data = loaderPrivate;
+    cpp = _mesa_get_format_bytes(image->format);
+
+    image->region = intel_region_alloc_for_handle(intel, cpp, width, height,
+                                                 pitch, name, "image");
+    if (image->region == NULL) {
+       FREE(image);
+       return NULL;
+    }
+
+    return image;      
+}
+
+static __DRIimage *
+intel_create_image_from_renderbuffer(__DRIcontext *context,
+                                    int renderbuffer, void *loaderPrivate)
+{
+   __DRIimage *image;
+   struct intel_context *intel = context->driverPrivate;
+   struct gl_renderbuffer *rb;
+   struct intel_renderbuffer *irb;
+
+   rb = intel->ctx.CurrentRenderbuffer;
+   if (!rb) {
+      _mesa_error(&intel->ctx,
+                 GL_INVALID_OPERATION, "glRenderbufferExternalMESA");
+      return NULL;
+   }
+
+   irb = intel_renderbuffer(rb);
+   image = CALLOC(sizeof *image);
+   if (image == NULL)
+      return NULL;
+
+   image->internal_format = rb->InternalFormat;
+   image->format = rb->Format;
+   image->data_type = rb->DataType;
+   image->data = loaderPrivate;
+   intel_region_reference(&image->region, irb->region);
+
+   return image;
+}
+
+static void
+intel_destroy_image(__DRIimage *image)
+{
+    intel_region_release(&image->region);
+    FREE(image);
+}
+
+static struct __DRIimageExtensionRec intelImageExtension = {
+    { __DRI_IMAGE, __DRI_IMAGE_VERSION },
+    intel_create_image_from_name,
+    intel_create_image_from_renderbuffer,
+    intel_destroy_image,
+};
+
 static const __DRIextension *intelScreenExtensions[] = {
     &driReadDrawableExtension,
     &intelTexOffsetExtension.base,
     &intelTexBufferExtension.base,
     &intelFlushExtension.base,
+    &intelImageExtension.base,
     NULL
 };