intel: Implement __DRIimage::createSubImage and bump supported version to 5
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 5 Jul 2012 17:02:02 +0000 (13:02 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Wed, 11 Jul 2012 19:28:35 +0000 (15:28 -0400)
We use the new miptree offset to pick out the sub-image when we bind
the EGLImage to a texture.

Signed-off-by: Kristian Høgsberg <krh@bitplanet.net>
src/mesa/drivers/dri/intel/intel_regions.h
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/intel/intel_tex_image.c

index 18f8093d13c887a23e89eeffd559109c02217ccb..782d6696dcf1b649a2a9ec3f90cc066b8d101e00 100644 (file)
@@ -147,6 +147,7 @@ struct __DRIimageRec {
    uint32_t usage;
    uint32_t dri_format;
    GLuint format;
+   uint32_t offset;
    void *data;
 };
 
index 9f31e87b16ddb548bd71b092453470b2bea49748..3638d0d13cba904a88d56fed29bd99fc6e5957ea 100644 (file)
@@ -185,6 +185,7 @@ intel_allocate_image(int dri_format, void *loaderPrivate)
        return NULL;
 
     image->dri_format = dri_format;
+    image->offset = 0;
 
     switch (dri_format) {
     case __DRI_IMAGE_FORMAT_RGB565:
@@ -267,6 +268,7 @@ intel_create_image_from_renderbuffer(__DRIcontext *context,
 
    image->internal_format = rb->InternalFormat;
    image->format = rb->Format;
+   image->offset = 0;
    image->data = loaderPrivate;
    intel_region_reference(&image->region, irb->mt->region);
 
@@ -376,6 +378,7 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
    image->usage           = orig_image->usage;
    image->dri_format      = orig_image->dri_format;
    image->format          = orig_image->format;
+   image->offset          = orig_image->offset;
    image->data            = loaderPrivate;
    
    return image;
@@ -412,8 +415,50 @@ intel_image_write(__DRIimage *image, const void *buf, size_t count)
    return 0;
 }
 
+static __DRIimage *
+intel_create_sub_image(__DRIimage *parent,
+                       int width, int height, int dri_format,
+                       int offset, int pitch, void *loaderPrivate)
+{
+    __DRIimage *image;
+    int cpp;
+    uint32_t mask_x, mask_y;
+
+    image = intel_allocate_image(dri_format, loaderPrivate);
+    cpp = _mesa_get_format_bytes(image->format);
+    if (offset + height * cpp * pitch > parent->region->bo->size) {
+       _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds");
+       FREE(image);
+       return NULL;
+    }
+
+    image->region = calloc(sizeof(*image->region), 1);
+    if (image->region == NULL) {
+       FREE(image);
+       return NULL;
+    }
+
+    image->region->cpp = _mesa_get_format_bytes(image->format);
+    image->region->width = width;
+    image->region->height = height;
+    image->region->pitch = pitch;
+    image->region->refcount = 1;
+    image->region->bo = parent->region->bo;
+    drm_intel_bo_reference(image->region->bo);
+    image->region->tiling = parent->region->tiling;
+    image->region->screen = parent->region->screen;
+    image->offset = offset;
+
+    intel_region_get_tile_masks(image->region, &mask_x, &mask_y);
+    if (offset & mask_x)
+       _mesa_warning(NULL,
+                     "intel_create_sub_image: offset not on tile boundary");
+
+    return image;
+}
+
 static struct __DRIimageExtensionRec intelImageExtension = {
-    { __DRI_IMAGE, 4 },
+    { __DRI_IMAGE, 5 },
     intel_create_image_from_name,
     intel_create_image_from_renderbuffer,
     intel_destroy_image,
@@ -421,7 +466,8 @@ static struct __DRIimageExtensionRec intelImageExtension = {
     intel_query_image,
     intel_dup_image,
     intel_validate_usage,
-    intel_image_write
+    intel_image_write,
+    intel_create_sub_image
 };
 
 static const __DRIextension *intelScreenExtensions[] = {
index 0caa2e2d66e01e56c7596a1789e1c16f8c7c894e..70fe762a101a5e98f1d861cdd9ba4f50d718d492 100644 (file)
@@ -350,7 +350,7 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
 
    intel_set_texture_image_region(ctx, texImage, image->region,
                                  target, image->internal_format,
-                                  image->format, 0);
+                                  image->format, image->offset);
 }
 #endif