[Mesa-dev] [PATCH V4 5/6] intel: implement create image from texture

Eric Anholt eric at anholt.net
Tue Jan 15 14:05:00 PST 2013


Abdiel Janulgue <abdiel.janulgue at linux.intel.com> writes:

> Save miptree level info to DRIImage, taking offsets into consideration.
> 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>
> ---
>  src/mesa/drivers/dri/intel/intel_screen.c |  178 +++++++++++++++++++++++++----
>  1 file changed, 158 insertions(+), 20 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
> index e0fe8c1..ea62933 100644
> --- a/src/mesa/drivers/dri/intel/intel_screen.c
> +++ b/src/mesa/drivers/dri/intel/intel_screen.c
> @@ -31,6 +31,7 @@
>  #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"
> @@ -104,6 +105,10 @@ const GLuint __driNConfigOptions = 15;
>  #include "intel_tex.h"
>  #include "intel_regions.h"
>  
> +#ifndef I915
> +#include "brw_context.h"
> +#endif
> +
>  #include "i915_drm.h"
>  
>  #ifdef USE_NEW_INTERFACE
> @@ -295,6 +300,92 @@ 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,
> +                           uint32_t mask_x,  uint32_t mask_y)
> +{
> +   image->width = mt->level[level].width;
> +   image->height = mt->level[level].height;
> +   image->level_x = mt->level[level].level_x;
> +   image->level_y = mt->level[level].level_y;
> +   image->slice_x_offset = mt->level[level].slice[slice].x_offset;
> +   image->slice_y_offset = mt->level[level].slice[slice].y_offset;
> +
> +   image->offset = intel_region_get_aligned_offset(mt->region,
> +                                                   image->slice_x_offset & ~mask_x,
> +                                                   image->slice_y_offset & ~mask_y,
> +                                                   false);
> +}

I think you end up double-counting the slice_x/y_offset offset here --
you have a tile-aligned byte offset from the base of the region (which I
don't think you want at all), and then you reference from
slice_x/y_offset from that offset when texturing.

> +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 mask_x, mask_y;
> +   uint32_t draw_x, draw_y;
> +
> +   intel_miptree_check_level_layer(mt, level, zoffset);
> +   intel_miptree_get_image_offset(mt, level, zoffset,
> +                                  &draw_x, &draw_y);
> +   intel_region_get_tile_masks(mt->region, &mask_x, &mask_y, false);

use the new intel_region_get_tile_offsets() instead, which would clean
up the if statement below.

> +   if (!has_surface_tile_offset &&
> +       ((draw_x & mask_x) != 0 || (draw_y & mask_y) != 0) &&
> +       (level > 0 || zoffset > 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
> +       */
> +      _mesa_warning(NULL, "%s: can't resolve miptree level", __func__);
> +      return false;

OK, this covers the original gen4 case, and we decided that we can't get
misalignment for non-depth textures in the gm45+ case.  But we need to
check for tile_x/tile_yy not aligned to 8x8 for depth textures, since
those have more strict alignment requirements for rendering.

We also need to fail if mt->stencil_mt is set (we don't have a way to
pass the separate stencil miptree of a GL_DEPTH_STENCIL texture
through).

> +   } else {
> +      intel_image_set_level_info(image, mt, level, zoffset, mask_x, mask_y);
> +      intel_region_reference(&image->region, mt->region);
> +   }

Drop the else and unindent, since you returned in the previous error
handling block.

> @@ -346,27 +439,63 @@ 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);

> +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) {
> +      _mesa_warning(NULL, "%s: invalid texture", __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)) {
> +      _mesa_warning(NULL, "%s: texture object incomplete", __func__);
> +      return NULL;
> +   }

How does this map to:

        * If EGL_GL_TEXTURE_LEVEL_KHR is 0, and <target> is
          EGL_GL_TEXTURE_2D_KHR or EGL_GL_TEXTURE_3D_KHR and <buffer> is not
          the name of a complete texture object, and mipmap level 0 is not
          specified, the error EGL_BAD_PARAMETER is generated.

Every place I see _mesa_warning() in this code, I think it's something
that should be generating a specific EGL error.

> +
> +   if (level < obj->BaseLevel || level > obj->_MaxLevel) {
> +      _mesa_warning(NULL, "%s: invalid mipmap level", __func__);
> +      return NULL;
> +   }

> +   image->internal_format = obj->Image[face][level]->InternalFormat;
> +   image->format = obj->Image[face][level]->TexFormat;
> +   image->data = loaderPrivate;
> +   if (!intel_setup_image_from_mipmap_tree(intel, image, iobj->mt, level, zoffset)) {
> +      _mesa_error(&intel->ctx,
> +		  GL_INVALID_OPERATION, "intel_create_image_from_texture");
> +      free(image);
> +      return NULL;
>     }
> +   image->dri_format = intel_dri_format(image->format);

Needs error handling when the format isn't one we can make an EGLImage for.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130115/09bafb30/attachment.pgp>


More information about the mesa-dev mailing list