diff options
| author | Keith Packard <keithp@keithp.com> | 2007-12-17 22:43:48 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2007-12-18 10:22:04 -0800 | 
| commit | a183efc132c8db1bb42525ac177ffff96f69a59b (patch) | |
| tree | e4106d93ea70e4b9fbe635704983e34b1dd24a78 /src | |
| parent | 6f1bfdc4bf5b72ac705b8cbb2dc431e133dcb5b8 (diff) | |
[Intel] Centralize mipmap pitch computations.
mipmap pitches must account for the device alignment requirements, which
used to be fairly simple; just align to a 4-byte boundary. However, to allow
textures to be drawn to under TTM, they now need to be aligned to a 64-byte
boundary. Placing all of the alignment constraints in a single function
allows this new constraint to be applied uniformly.
There was some pitch constraining code in intel_miptree_create, but that was
modifying the pitch long after the miptree had been layed out, so it only
served to wreck the mipmap and cause rendering errors.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/dri/i915/i915_tex_layout.c | 16 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 81 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 13 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_layout.c | 4 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_layout.h | 2 | 
5 files changed, 72 insertions, 44 deletions
| diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c index 7b761a7b22..dfd02112ba 100644 --- a/src/mesa/drivers/dri/i915/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c @@ -54,7 +54,7 @@ static GLint step_offsets[6][2] = { {0, 2},  };  GLboolean -i915_miptree_layout(struct intel_mipmap_tree * mt) +i915_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)  {     GLint level; @@ -67,7 +67,7 @@ i915_miptree_layout(struct intel_mipmap_tree * mt)           assert(lvlWidth == lvlHeight); /* cubemap images are square */           /* double pitch for cube layouts */ -         mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; +         mt->pitch = intel_miptree_pitch_align (intel, mt, dim * 2);           mt->total_height = dim * 4;           for (level = mt->first_level; level <= mt->last_level; level++) { @@ -107,7 +107,7 @@ i915_miptree_layout(struct intel_mipmap_tree * mt)           /* Calculate the size of a single slice.             */ -         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; +         mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);           /* XXX: hardware expects/requires 9 levels at minimum.            */ @@ -150,7 +150,7 @@ i915_miptree_layout(struct intel_mipmap_tree * mt)           GLuint height = mt->height0;  	 GLuint img_height; -         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; +         mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);           mt->total_height = 0;           for (level = mt->first_level; level <= mt->last_level; level++) { @@ -180,7 +180,7 @@ i915_miptree_layout(struct intel_mipmap_tree * mt)  GLboolean -i945_miptree_layout(struct intel_mipmap_tree * mt) +i945_miptree_layout(struct intel_context *intel, struct intel_mipmap_tree * mt)  {     GLint level; @@ -197,7 +197,7 @@ i945_miptree_layout(struct intel_mipmap_tree * mt)            * or the final row of 4x4, 2x2 and 1x1 faces below this.             */           if (dim > 32) -            mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp; +            mt->pitch = intel_miptree_pitch_align (intel, mt, dim);           else              mt->pitch = 14 * 8; @@ -279,7 +279,7 @@ i945_miptree_layout(struct intel_mipmap_tree * mt)           GLuint pack_y_pitch;           GLuint level; -         mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp; +         mt->pitch = intel_miptree_pitch_align (intel, mt, mt->width0);           mt->total_height = 0;           pack_y_pitch = MAX2(mt->height0, 2); @@ -329,7 +329,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/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 3517939066..6610771b6e 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -78,44 +78,19 @@ intel_miptree_create(struct intel_context *intel,     mt->cpp = compress_byte ? compress_byte : cpp;     mt->compressed = compress_byte ? 1 : 0;     mt->refcount = 1;  +   mt->pitch = 0;  #ifdef I915     if (IS_945(intel->intelScreen->deviceID)) -      ok = i945_miptree_layout(mt); +      ok = i945_miptree_layout(intel, mt);     else -      ok = i915_miptree_layout(mt); +      ok = i915_miptree_layout(intel, mt);  #else -   ok = brw_miptree_layout(mt); +   ok = brw_miptree_layout(intel, mt);  #endif     if (ok) { -#ifdef I915 -      if (!mt->compressed) { -	 int align; - -	 if (intel->ttm) { -	    /* XXX: Align pitch to multiple of 64 bytes for now to allow -	     * render-to-texture to work in all cases. This should probably be -	     * replaced at some point by some scheme to only do this when really -	     * necessary. -	     */ -	    align = 63; -	 } else { -	    align = 3; -	 } - -	 mt->pitch = (mt->pitch * cpp + align) & ~align; - -	 /* XXX: At least the i915 seems very upset when the pitch is a multiple -	  * of 1024 and sometimes 512 bytes - performance can drop by several -	  * times. Go to the next multiple of the required alignment for now. -	  */ -	 if (!(mt->pitch & 511)) -	    mt->pitch += align + 1; - -	 mt->pitch /= cpp; -      } -#endif /* I915 */ +      assert (mt->pitch);        mt->region = intel_region_alloc(intel,                                        mt->cpp, mt->pitch, mt->total_height); @@ -129,6 +104,52 @@ intel_miptree_create(struct intel_context *intel,     return mt;  } +/** + * intel_miptree_pitch_align: + * + * @intel: intel context pointer + * + * @mt: the miptree to compute pitch alignment for + * + * @pitch: the natural pitch value + * + * Given @pitch, compute a larger value which accounts for + * any necessary alignment required by the device + */ + +int intel_miptree_pitch_align (struct intel_context *intel, +			       struct intel_mipmap_tree *mt, +			       int pitch) +{ +   if (!mt->compressed) { +      int pitch_align; + +      if (intel->ttm) { +	 /* XXX: Align pitch to multiple of 64 bytes for now to allow +	  * render-to-texture to work in all cases. This should probably be +	  * replaced at some point by some scheme to only do this when really +	  * necessary. +	  */ +	 pitch_align = 64; +      } else { +	 pitch_align = 4; +      } + +      pitch = ALIGN(pitch * mt->cpp, pitch_align); + +#ifdef I915 +      /* XXX: At least the i915 seems very upset when the pitch is a multiple +       * of 1024 and sometimes 512 bytes - performance can drop by several +       * times. Go to the next multiple of the required alignment for now. +       */ +      if (!(pitch & 511)) +	 pitch += pitch_align; +#endif + +      pitch /= mt->cpp; +   } +   return pitch; +}  void  intel_miptree_reference(struct intel_mipmap_tree **dst, diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 4a76717688..968eec4fec 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -123,6 +123,10 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel,                                                 GLuint cpp,                                                 GLuint compress_byte); +int intel_miptree_pitch_align (struct intel_context *intel, +			       struct intel_mipmap_tree *mt, +			       int pitch); +  void intel_miptree_reference(struct intel_mipmap_tree **dst,                               struct intel_mipmap_tree *src); @@ -190,8 +194,11 @@ void intel_miptree_image_copy(struct intel_context *intel,  /* i915_mipmap_tree.c:   */ -GLboolean i915_miptree_layout(struct intel_mipmap_tree *mt); -GLboolean i945_miptree_layout(struct intel_mipmap_tree *mt); -GLboolean brw_miptree_layout(struct intel_mipmap_tree *mt); +GLboolean i915_miptree_layout(struct intel_context *intel, +			      struct intel_mipmap_tree *mt); +GLboolean i945_miptree_layout(struct intel_context *intel, +			      struct intel_mipmap_tree *mt); +GLboolean brw_miptree_layout(struct intel_context *intel, +			     struct intel_mipmap_tree *mt);  #endif diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index 4da636021b..edc3a2eaa4 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -52,7 +52,7 @@ GLuint intel_compressed_alignment(GLenum internalFormat)      return alignment;  } -void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) +void i945_miptree_layout_2d( struct intel_context *intel, struct intel_mipmap_tree *mt )  {     GLint align_h = 2, align_w = 4;     GLuint level; @@ -92,7 +92,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )     /* Pitch must be a whole number of dwords, even though we      * express it in texels.      */ -   mt->pitch = ALIGN(mt->pitch * mt->cpp, 4) / mt->cpp; +   mt->pitch = intel_miptree_pitch_align (intel, mt, mt->pitch);     mt->total_height = 0;     for ( level = mt->first_level ; level <= mt->last_level ; level++ ) { diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index 99d41c3629..193699d3f7 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -38,5 +38,5 @@ static 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 );  extern GLuint intel_compressed_alignment(GLenum); | 
