Abdiel Janulgue <abdiel.janul...@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.janul...@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.
pgpi9m_bB2lhe.pgp
Description: PGP signature
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev