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. Signed-off-by: Yuanhan Liu <yuanhan....@linux.intel.com> --- src/mesa/drivers/dri/i915/i915_reg.h | 1 + src/mesa/drivers/dri/i915/i915_tex_layout.c | 4 +- src/mesa/drivers/dri/i915/i915_texstate.c | 2 + src/mesa/drivers/dri/i965/brw_tex_layout.c | 4 +- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 2 +- src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 2 +- src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 7 ++- src/mesa/drivers/dri/intel/intel_tex_layout.c | 70 +++++++++++++++------- src/mesa/drivers/dri/intel/intel_tex_layout.h | 3 +- 9 files changed, 65 insertions(+), 30 deletions(-) diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h index 766547a..0ca0acf 100644 --- a/src/mesa/drivers/dri/i915/i915_reg.h +++ b/src/mesa/drivers/dri/i915/i915_reg.h @@ -645,6 +645,7 @@ #define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) #define MS4_MAX_LOD_SHIFT 9 #define MS4_MAX_LOD_MASK (0x3f<<9) +#define MS4_MIP_LAYOUT_MODE_SHIFT 8 #define MS4_MIP_LAYOUT_LEGACY (0<<8) #define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) #define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c index 1e3cfad..6600734 100644 --- a/src/mesa/drivers/dri/i915/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c @@ -454,7 +454,7 @@ i945_miptree_layout_3d(struct intel_mipmap_tree * mt) } void -i945_miptree_layout(struct intel_mipmap_tree * mt) +i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt) { switch (mt->target) { case GL_TEXTURE_CUBE_MAP: @@ -469,7 +469,7 @@ i945_miptree_layout(struct intel_mipmap_tree * mt) case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE_ARB: - i945_miptree_layout_2d(mt); + i945_miptree_layout_2d(intel, mt); break; default: _mesa_problem(NULL, "Unexpected tex target in i945_miptree_layout()"); 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; diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 7a1b91f..5a66f90 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -53,7 +53,7 @@ brw_miptree_layout_texture_array(struct intel_context *intel, if (mt->compressed) qpitch /= 4; - i945_miptree_layout_2d(mt); + i945_miptree_layout_2d(intel, mt); for (level = mt->first_level; level <= mt->last_level; level++) { for (q = 0; q < mt->depth0; q++) { @@ -164,7 +164,7 @@ brw_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree *mt) break; default: - i945_miptree_layout_2d(mt); + i945_miptree_layout_2d(intel, mt); break; } DBG("%s: %dx%dx%d\n", __FUNCTION__, 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, diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 3601f5e..cb97ebe 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -151,7 +151,7 @@ intel_miptree_create_internal(struct intel_context *intel, #ifdef I915 (void) intel; if (intel->is_945) - i945_miptree_layout(mt); + i945_miptree_layout(intel, mt); else i915_miptree_layout(mt); #else 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; }; @@ -390,7 +394,8 @@ intel_miptree_all_slices_resolve_depth(struct intel_context *intel, /* i915_mipmap_tree.c: */ void i915_miptree_layout(struct intel_mipmap_tree *mt); -void i945_miptree_layout(struct intel_mipmap_tree *mt); +void i945_miptree_layout(struct intel_context *intel, + struct intel_mipmap_tree *mt); void brw_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree *mt); 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; +} + +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; } } @@ -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; } width = minify(width); diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index 12ed16d..87c708e 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -38,7 +38,8 @@ static INLINE GLuint minify( GLuint d ) return MAX2(1, d>>1); } -extern void i945_miptree_layout_2d(struct intel_mipmap_tree *mt); +extern void i945_miptree_layout_2d(struct intel_context *intel, + struct intel_mipmap_tree *mt); void intel_get_texture_alignment_unit(struct intel_context *intel, -- 1.7.4.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev