[Mesa-dev] [PATCH] intel:i915:i965: enable mipmap layout right mode
Yuanhan Liu
yuanhan.liu at linux.intel.com
Sun Mar 18 23:41:09 PDT 2012
On Fri, Mar 16, 2012 at 11:13:23AM -0700, Eric Anholt wrote:
> On Thu, 15 Mar 2012 14:42:53 +0800, Yuanhan Liu <yuanhan.liu at linux.intel.com> wrote:
> > There are two mipmap layout modes: below and right. And we currently just
> > use _below_ mode. And in some cases, like height is greater than width,
> > it would be better to use the _right_ mode for saving memory.
> >
> > And it also fix some issues like the gl-max-texture-dimensions.html webglc
> > test case on pineview in a hardware way(no fallback). Since when
> > rendering with 1x2048 texture using below mode would make the draw
> > offset exceed the max allowed size, but will not when using right mode.
>
> I think you should be able to get hardware rendering without changing
> layouts by taking advantage of intel_renderbuffer_get_tile_offsets().
>
> > diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
> > index 9022548..54f32a4 100644
> > --- a/src/mesa/drivers/dri/i915/i915_texstate.c
> > +++ b/src/mesa/drivers/dri/i915/i915_texstate.c
> > @@ -192,6 +192,8 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
> > (U_FIXED(CLAMP(maxlod, 0.0, 11.0), 2) << MS4_MAX_LOD_SHIFT) |
> > ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
> >
> > + if (intel->is_945)
> > + state[I915_TEXREG_MS4] |= intelObj->mt->layout << MS4_MIP_LAYOUT_MODE_SHIFT;
> >
> > {
> > GLuint minFilt, mipFilt, magFilt;
>
> You're checking 945 here, but your decision to choose right layout
> didn't check for 945.
The decision to choose right layout is done at i945_miptree_choose_layout, that's where we did check.
>
> > diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> > index a3de2e3..b6565fe 100644
> > --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> > +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> > @@ -654,7 +654,7 @@ brw_update_texture_surface( struct gl_context *ctx, GLuint unit )
> > 6 * 4, 32, &brw->wm.surf_offset[surf_index]);
> >
> > surf[0] = (translate_tex_target(tObj->Target) << BRW_SURFACE_TYPE_SHIFT |
> > - BRW_SURFACE_MIPMAPLAYOUT_BELOW << BRW_SURFACE_MIPLAYOUT_SHIFT |
> > + mt->layout << BRW_SURFACE_MIPLAYOUT_SHIFT |
> > BRW_SURFACE_CUBEFACE_ENABLES |
> > (translate_tex_format(mt->format,
> > firstImage->InternalFormat,
>
> You didn't update gen7.
Wierdly, I didn't find mipmap layout mode option at SURFRACE_STATE for
IVB. But you remind me that I forgot to do that for gen6 hiz.
>
> > diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
> > index 9082864..d175f50 100644
> > --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
> > +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
> > @@ -215,6 +215,10 @@ struct intel_mipmap_tree
> > /* These are also refcounted:
> > */
> > GLuint refcount;
> > +
> > +#define INTEL_LAYOUT_BELOW 0
> > +#define INTEL_LAYOUT_RIGHT 1
> > + int layout;
> > };
>
> Make it a bool called "miplayout_right" or something instead of
> #defines.
It's fine to me. But I guess it's less readable than using macros, say
the following code:
if ((mt->layout == INTEL_LAYOUT_BELOW && level == mt->first_level + 1) ||
(mt->layout == INTEL_LAYOUT_RIGHT && level == mt->first_level)) {
x += ALIGN(width, mt->align_w);
} else {
y += img_height;
}
which translated to
if ((mt->miplayout_right && level == mt->first_level) ||
(!mt->miplayout_right && level == mt->first_level + 1)) {
x += ALIGN(width, mt->align_w);
} else {
y += img_height;
}
>
> > diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c
> > index 65645bc..4687dd3 100644
> > --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c
> > +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c
> > @@ -138,7 +138,27 @@ intel_get_texture_alignment_unit(struct intel_context *intel,
> > *h = intel_vertical_texture_alignment_unit(intel, format);
> > }
> >
> > -void i945_miptree_layout_2d(struct intel_mipmap_tree *mt)
> > +static int
> > +i945_miptree_choose_layout(struct intel_context *intel, GLenum target,
> > + GLuint width, GLuint height)
> > +{
> > + int layout = INTEL_LAYOUT_BELOW; /* Use layout _below_ by default */
> > +
> > + /*
> > + * INTEL_LAYOUT_RIGHT is only for:
> > + * GL_TEXTURE_1D, GL_TEXTURE_2D [945+, aka all platforms here]
> > + * GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP [gen5+]
> > + */
> > + if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D ||
> > + (intel->gen >= 5 && target == GL_TEXTURE_CUBE_MAP)) {
> > + if ((height >> 1) >= width)
> > + layout = INTEL_LAYOUT_RIGHT;
> > + }
> > +
> > + return layout;
> > +}
>
> You should explain why the choice is being made here.
Yes, will add it.
>
> > +void i945_miptree_layout_2d(struct intel_context *intel, struct intel_mipmap_tree *mt)
> > {
> > GLuint level;
> > GLuint x = 0;
> > @@ -153,24 +173,32 @@ void i945_miptree_layout_2d(struct intel_mipmap_tree *mt)
> > mt->total_width = ALIGN(mt->width0, mt->align_w);
> > }
> >
> > - /* May need to adjust width to accomodate the placement of
> > - * the 2nd mipmap. This occurs when the alignment
> > - * constraints of mipmap placement push the right edge of the
> > - * 2nd mipmap out past the width of its parent.
> > - */
> > + mt->layout = i945_miptree_choose_layout(intel, mt->target, width, height);
> > + /* Determine the max width */
> > if (mt->first_level != mt->last_level) {
> > - GLuint mip1_width;
> > -
> > - if (mt->compressed) {
> > - mip1_width = ALIGN(minify(mt->width0), mt->align_w)
> > - + ALIGN(minify(minify(mt->width0)), mt->align_w);
> > + GLuint tmp;
> > +
> > + if (mt->layout == INTEL_LAYOUT_BELOW) {
> > + if (mt->compressed) {
> > + tmp = ALIGN(minify(mt->width0), mt->align_w) +
> > + ALIGN(minify(minify(mt->width0)), mt->align_w);
> > + } else {
> > + tmp = ALIGN(minify(mt->width0), mt->align_w) +
> > + minify(minify(mt->width0));
> > + }
> > + } else if (mt->layout == INTEL_LAYOUT_RIGHT) {
> > + if (mt->compressed) {
> > + tmp = ALIGN(mt->width0, mt->align_w) +
> > + ALIGN(minify(mt->width0), mt->align_w);
> > + } else {
> > + tmp = ALIGN(mt->width0, mt->align_w) + minify(mt->width0);
> > + }
> > } else {
> > - mip1_width = ALIGN(minify(mt->width0), mt->align_w)
> > - + minify(minify(mt->width0));
> > + assert(!"mipmap: wrong layout!\n");
> > }
> >
> > - if (mip1_width > mt->total_width) {
> > - mt->total_width = mip1_width;
> > + if (tmp > mt->total_width) {
> > + mt->total_width = tmp;
> > }
> > }
>
> don't call variables "tmp"
Yes, but I don't think that 'mip1_width' is good, too. Since it's
not the width of mip1, but maybe the width of mip1 plus mip2(below mode)
or mip0 plus mip1(right mode). So, I may call it max_mip_width.
Thanks,
Yuanhan Liu
>
> > @@ -191,13 +219,11 @@ void i945_miptree_layout_2d(struct intel_mipmap_tree *mt)
> > */
> > mt->total_height = MAX2(mt->total_height, y + img_height);
> >
> > - /* Layout_below: step right after second mipmap.
> > - */
> > - if (level == mt->first_level + 1) {
> > - x += ALIGN(width, mt->align_w);
> > - }
> > - else {
> > - y += img_height;
> > + if ((mt->layout == INTEL_LAYOUT_BELOW && level == mt->first_level + 1) ||
> > + (mt->layout == INTEL_LAYOUT_RIGHT && level == mt->first_level)) {
> > + x += ALIGN(width, mt->align_w);
> > + } else {
> > + y += img_height;
> > }
More information about the mesa-dev
mailing list