[Mesa-dev] [PATCH V7 8/8] intel: implement create image from texture

Kristian Høgsberg hoegsberg at gmail.com
Wed Jan 30 09:24:13 PST 2013


On Wed, Jan 30, 2013 at 03:40:26PM +0200, Abdiel Janulgue wrote:
> Save miptree level info to DRIImage:
> - Appropriately-aligned base offset pointing to the image
> - Additional x/y adjustment offsets from above.
> 
> In non-tile-aligned surface cases where resolving back to the original image
> located in mip-levels higher than the base level proves problematic due to
> offset alignment issues, report INVALID_OPERATION as per spec wording.
> 
> Signed-off-by: Abdiel Janulgue <abdiel.janulgue at linux.intel.com>

The series look good to me (the EGL + DRI2 parts, can't speak for the
intel hw details), but shouldn't this patch set the
intelImageExtension version to 6?  I didn't see it happen in any other
patch and at any rate, this is the patch that completes the feature
and this is where we should bump the version.

Kristian

> ---
>  src/mesa/drivers/dri/intel/intel_screen.c |  179 +++++++++++++++++++++++++----
>  1 file changed, 159 insertions(+), 20 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
> index b39bc46..2327590 100644
> --- a/src/mesa/drivers/dri/intel/intel_screen.c
> +++ b/src/mesa/drivers/dri/intel/intel_screen.c
> @@ -31,11 +31,13 @@
>  #include "main/context.h"
>  #include "main/framebuffer.h"
>  #include "main/renderbuffer.h"
> +#include "main/texobj.h"
>  #include "main/hash.h"
>  #include "main/fbobject.h"
>  #include "main/mfeatures.h"
>  #include "main/version.h"
>  #include "swrast/s_renderbuffer.h"
> +#include "egl/main/eglcurrent.h"
>  
>  #include "utils.h"
>  #include "xmlpool.h"
> @@ -105,6 +107,10 @@ const GLuint __driNConfigOptions = 16;
>  #include "intel_tex.h"
>  #include "intel_regions.h"
>  
> +#ifndef I915
> +#include "brw_context.h"
> +#endif
> +
>  #include "i915_drm.h"
>  
>  #ifdef USE_NEW_INTERFACE
> @@ -296,6 +302,87 @@ intel_allocate_image(int dri_format, void *loaderPrivate)
>      return image;
>  }
>  
> +static void
> +intel_image_set_level_info(__DRIimage *image, struct intel_mipmap_tree *mt,
> +                           int level, int slice)
> +{
> +   unsigned int draw_x, draw_y;
> +   uint32_t mask_x, mask_y;
> +
> +   intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);
> +   intel_miptree_get_image_offset(mt, level, slice, &draw_x, &draw_y);
> +
> +   image->width = mt->level[level].width;
> +   image->height = mt->level[level].height;
> +   image->tile_x = draw_x & mask_x;
> +   image->tile_y = draw_y & mask_y;
> +
> +   image->offset = intel_region_get_aligned_offset(mt->region,
> +                                                   draw_x & ~mask_x,
> +                                                   draw_y & ~mask_y,
> +                                                   false);
> +}
> +
> +/**
> + * Sets up a DRIImage structure to point to our shared image in a region
> + */
> +static bool
> +intel_setup_image_from_mipmap_tree(struct intel_context *intel, __DRIimage *image,
> +                                   struct intel_mipmap_tree *mt, GLuint level,
> +                                   GLuint zoffset)
> +{
> +   bool has_surface_tile_offset = false;
> +   uint32_t draw_x, draw_y;
> +
> +   intel_miptree_check_level_layer(mt, level, zoffset);
> +   intel_miptree_get_tile_offsets(mt, level, zoffset, &draw_x, &draw_y);
> +
> +#ifndef I915
> +   has_surface_tile_offset = brw_context(&intel->ctx)->has_surface_tile_offset;
> +#endif
> +   if (!has_surface_tile_offset &&
> +       (draw_x != 0 || draw_y != 0))
> +      /* Non-tile aligned sufaces in gen4 hw and earlier have problems resolving
> +       * back to our destination due to alignment issues. Bail-out and report error
> +       */
> +      return false;
> +
> +   intel_image_set_level_info(image, mt, level, zoffset);
> +   intel_region_reference(&image->region, mt->region);
> +
> +   return true;
> +}
> +
> +static void
> +intel_setup_image_from_dimensions(__DRIimage *image)
> +{
> +   image->width    = image->region->width;
> +   image->height   = image->region->height;
> +   image->tile_x = 0;
> +   image->tile_y = 0;
> +}
> +
> +static inline uint32_t
> +intel_dri_format(GLuint format)
> +{
> +   switch (format) {
> +   case MESA_FORMAT_RGB565:
> +      return __DRI_IMAGE_FORMAT_RGB565;
> +   case MESA_FORMAT_XRGB8888:
> +      return __DRI_IMAGE_FORMAT_XRGB8888;
> +   case MESA_FORMAT_ARGB8888:
> +      return __DRI_IMAGE_FORMAT_ARGB8888;
> +   case MESA_FORMAT_RGBA8888_REV:
> +      return __DRI_IMAGE_FORMAT_ABGR8888;
> +   case MESA_FORMAT_R8:
> +      return __DRI_IMAGE_FORMAT_R8;
> +   case MESA_FORMAT_RG88:
> +      return __DRI_IMAGE_FORMAT_GR88;
> +   }
> +
> +   return MESA_FORMAT_NONE;
> +}
> +
>  static __DRIimage *
>  intel_create_image_from_name(__DRIscreen *screen,
>  			     int width, int height, int format,
> @@ -318,6 +405,8 @@ intel_create_image_from_name(__DRIscreen *screen,
>         return NULL;
>      }
>  
> +    intel_setup_image_from_dimensions(image);
> +
>      return image;	
>  }
>  
> @@ -347,26 +436,69 @@ intel_create_image_from_renderbuffer(__DRIcontext *context,
>     image->offset = 0;
>     image->data = loaderPrivate;
>     intel_region_reference(&image->region, irb->mt->region);
> +   intel_setup_image_from_dimensions(image);
> +   image->dri_format = intel_dri_format(image->format);
>  
> -   switch (image->format) {
> -   case MESA_FORMAT_RGB565:
> -      image->dri_format = __DRI_IMAGE_FORMAT_RGB565;
> -      break;
> -   case MESA_FORMAT_XRGB8888:
> -      image->dri_format = __DRI_IMAGE_FORMAT_XRGB8888;
> -      break;
> -   case MESA_FORMAT_ARGB8888:
> -      image->dri_format = __DRI_IMAGE_FORMAT_ARGB8888;
> -      break;
> -   case MESA_FORMAT_RGBA8888_REV:
> -      image->dri_format = __DRI_IMAGE_FORMAT_ABGR8888;
> -      break;
> -   case MESA_FORMAT_R8:
> -      image->dri_format = __DRI_IMAGE_FORMAT_R8;
> -      break;
> -   case MESA_FORMAT_RG88:
> -      image->dri_format = __DRI_IMAGE_FORMAT_GR88;
> -      break;
> +   return image;
> +}
> +
> +static __DRIimage *
> +intel_create_image_from_texture(__DRIcontext *context, int target,
> +                                unsigned texture, int zoffset,
> +                                int level,
> +                                void *loaderPrivate)
> +{
> +   __DRIimage *image;
> +   struct intel_context *intel = context->driverPrivate;
> +   struct gl_texture_object *obj;
> +   struct intel_texture_object *iobj;
> +   GLuint face = 0;
> +
> +   obj = _mesa_lookup_texture(&intel->ctx, texture);
> +   if (!obj || obj->Target != target) {
> +      _eglError(EGL_BAD_PARAMETER, __func__);
> +      return NULL;
> +   }
> +
> +   if (target == GL_TEXTURE_CUBE_MAP)
> +      face = zoffset;
> +
> +   _mesa_test_texobj_completeness(&intel->ctx, obj);
> +   iobj = intel_texture_object(obj);
> +   if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
> +      _eglError(EGL_BAD_PARAMETER, __func__);
> +      return NULL;
> +   }
> +
> +   if (level < obj->BaseLevel || level > obj->_MaxLevel) {
> +      _eglError(EGL_BAD_MATCH, __func__);
> +      return NULL;
> +   }
> +
> +   if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < zoffset) {
> +      _eglError(EGL_BAD_MATCH, __func__);
> +      return NULL;
> +   }
> +   image = calloc(1, sizeof *image);
> +   if (image == NULL) {
> +      _eglError(EGL_BAD_ALLOC, __func__);
> +      return NULL;
> +   }
> +
> +   image->internal_format = obj->Image[face][level]->InternalFormat;
> +   image->format = obj->Image[face][level]->TexFormat;
> +   image->data = loaderPrivate;
> +   if (iobj->mt->stencil_mt ||
> +       !intel_setup_image_from_mipmap_tree(intel, image, iobj->mt, level, zoffset)) {
> +      _mesa_error(&intel->ctx, GL_INVALID_OPERATION, __func__);
> +      free(image);
> +      return NULL;
> +   }
> +   image->dri_format = intel_dri_format(image->format);
> +   if (image->dri_format == MESA_FORMAT_NONE) {
> +      fprintf(stderr, "%s: Cannot make EGL image from invalid format.\n", __func__);
> +      free(image);
> +      return NULL;
>     }
>  
>     return image;
> @@ -406,6 +538,8 @@ intel_create_image(__DRIscreen *screen,
>        return NULL;
>     }
>     
> +   intel_setup_image_from_dimensions(image);
> +
>     return image;
>  }
>  
> @@ -460,6 +594,10 @@ intel_dup_image(__DRIimage *orig_image, void *loaderPrivate)
>     image->dri_format      = orig_image->dri_format;
>     image->format          = orig_image->format;
>     image->offset          = orig_image->offset;
> +   image->width           = orig_image->width;
> +   image->height          = orig_image->height;
> +   image->tile_x          = orig_image->tile_x;
> +   image->tile_y          = orig_image->tile_y;
>     image->data            = loaderPrivate;
>  
>     memcpy(image->strides, orig_image->strides, sizeof(image->strides));
> @@ -586,7 +724,8 @@ static struct __DRIimageExtensionRec intelImageExtension = {
>      .dupImage                           = intel_dup_image,
>      .validateUsage                      = intel_validate_usage,
>      .createImageFromNames               = intel_create_image_from_names,
> -    .fromPlanar                         = intel_from_planar
> +    .fromPlanar                         = intel_from_planar,
> +    .createImageFromTexture             = intel_create_image_from_texture
>  };
>  
>  static const __DRIextension *intelScreenExtensions[] = {
> -- 
> 1.7.9.5
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list