diff options
Diffstat (limited to 'src/gallium')
| -rw-r--r-- | src/gallium/drivers/i915/i915_resource_texture.c | 222 | 
1 files changed, 121 insertions, 101 deletions
| diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index 9b1d1451fa..f3ab4a4e38 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -55,26 +55,39 @@   * Initial offset for Cube map.   */  static const int initial_offsets[6][2] = { -   {0, 0}, -   {0, 2}, -   {1, 0}, -   {1, 2}, -   {1, 1}, -   {1, 3} +   [PIPE_TEX_FACE_POS_X] = {0, 0}, +   [PIPE_TEX_FACE_POS_Y] = {1, 0}, +   [PIPE_TEX_FACE_POS_Z] = {1, 1}, +   [PIPE_TEX_FACE_NEG_X] = {0, 2}, +   [PIPE_TEX_FACE_NEG_Y] = {1, 2}, +   [PIPE_TEX_FACE_NEG_Z] = {1, 3},  };  /**   * Step offsets for Cube map.   */  static const int step_offsets[6][2] = { -   {0, 2}, -   {0, 2}, -   {-1, 2}, -   {-1, 2}, -   {-1, 1}, -   {-1, 1} +   [PIPE_TEX_FACE_POS_X] = { 0, 2}, +   [PIPE_TEX_FACE_POS_Y] = {-1, 2}, +   [PIPE_TEX_FACE_POS_Z] = {-1, 1}, +   [PIPE_TEX_FACE_NEG_X] = { 0, 2}, +   [PIPE_TEX_FACE_NEG_Y] = {-1, 2}, +   [PIPE_TEX_FACE_NEG_Z] = {-1, 1},  }; +/** + * For compressed level 2 + */ +static const int bottom_offsets[6] = { +   [PIPE_TEX_FACE_POS_X] = 16 + 0 * 8, +   [PIPE_TEX_FACE_POS_Y] = 16 + 1 * 8, +   [PIPE_TEX_FACE_POS_Z] = 16 + 2 * 8, +   [PIPE_TEX_FACE_NEG_X] = 16 + 3 * 8, +   [PIPE_TEX_FACE_NEG_Y] = 16 + 4 * 8, +   [PIPE_TEX_FACE_NEG_Z] = 16 + 5 * 8, +}; + +  /* XXX really need twice the size if x is already pot?     Otherwise just use util_next_power_of_two?  */ @@ -221,6 +234,40 @@ i9x5_special_layout(struct i915_texture *tex)     return FALSE;  } +/** + * Cube layout used on i915 and for non-compressed textures on i945. + */ +static void +i9x5_texture_layout_cube(struct i915_texture *tex) +{ +   struct pipe_resource *pt = &tex->b.b; +   const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0); +   unsigned level; +   unsigned face; + +   assert(pt->width0 == pt->height0); /* cubemap images are square */ + +   /* double pitch for cube layouts */ +   tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4); +   tex->total_nblocksy = nblocks * 4; + +   for (level = 0; level <= pt->last_level; level++) +      i915_texture_set_level_info(tex, level, 6); + +   for (face = 0; face < 6; face++) { +      unsigned x = initial_offsets[face][0] * nblocks; +      unsigned y = initial_offsets[face][1] * nblocks; +      unsigned d = nblocks; + +      for (level = 0; level <= pt->last_level; level++) { +         i915_texture_set_image_offset(tex, level, face, x, y); +         d >>= 1; +         x += step_offsets[face][0] * d; +         y += step_offsets[face][1] * d; +      } +   } +} +  /*   * i915 layout functions @@ -300,37 +347,6 @@ i915_texture_layout_3d(struct i915_texture *tex)     tex->total_nblocksy = stack_nblocksy * pt->depth0;  } -static void -i915_texture_layout_cube(struct i915_texture *tex) -{ -   struct pipe_resource *pt = &tex->b.b; -   const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0); -   unsigned level; -   unsigned face; - -   assert(pt->width0 == pt->height0); /* cubemap images are square */ - -   /* double pitch for cube layouts */ -   tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4); -   tex->total_nblocksy = nblocks * 4; - -   for (level = 0; level <= pt->last_level; level++) -      i915_texture_set_level_info(tex, level, 6); - -   for (face = 0; face < 6; face++) { -      unsigned x = initial_offsets[face][0] * nblocks; -      unsigned y = initial_offsets[face][1] * nblocks; -      unsigned d = nblocks; - -      for (level = 0; level <= pt->last_level; level++) { -         i915_texture_set_image_offset(tex, level, face, x, y); -         d >>= 1; -         x += step_offsets[face][0] * d; -         y += step_offsets[face][1] * d; -      } -   } -} -  static boolean  i915_texture_layout(struct i915_texture * tex)  { @@ -346,7 +362,7 @@ i915_texture_layout(struct i915_texture * tex)        i915_texture_layout_3d(tex);        break;     case PIPE_TEXTURE_CUBE: -      i915_texture_layout_cube(tex); +      i9x5_texture_layout_cube(tex);        break;     default:        assert(0); @@ -484,93 +500,94 @@ static void  i945_texture_layout_cube(struct i915_texture *tex)  {     struct pipe_resource *pt = &tex->b.b; -   unsigned level;     const unsigned nblocks = util_format_get_nblocksx(pt->format, pt->width0); +   const unsigned dim = pt->width0; +   unsigned level;     unsigned face; -   /* -   printf("%s %i, %i\n", __FUNCTION__, pt->width0, pt->height0); -   */ -     assert(pt->width0 == pt->height0); /* cubemap images are square */ +   assert(util_next_power_of_two(pt->width0) == pt->width0); /* npot only */ +   assert(util_format_is_s3tc(pt->format)); /* compressed only */     /* -    * XXX Should only be used for compressed formats. But lets -    * keep this code active just in case. -    *      * Depending on the size of the largest images, pitch can be      * determined either by the old-style packing of cubemap faces,      * or the final row of 4x4, 2x2 and 1x1 faces below this. +    * +    * 64  * 2 / 4 = 32 +    * 14 * 2 = 28      */ -   if (nblocks > 32) -      tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4); +   if (pt->width0 >= 64) +      tex->stride = nblocks * 2 * util_format_get_blocksize(pt->format);     else -      tex->stride = 14 * 8 * util_format_get_blocksize(pt->format); +      tex->stride = 14 * 2 * util_format_get_blocksize(pt->format); -   tex->total_nblocksy = nblocks * 4; +   /* +    * Something similary apply for height as well. +    */ +   if (pt->width0 >= 4) +      tex->total_nblocksy = nblocks * 4 + 1; +   else +      tex->total_nblocksy = 1; -   /* Set all the levels to effectively occupy the whole rectangular region. -   */ +   /* Set all the levels to effectively occupy the whole rectangular region */     for (level = 0; level <= pt->last_level; level++)        i915_texture_set_level_info(tex, level, 6);     for (face = 0; face < 6; face++) { -      unsigned x = initial_offsets[face][0] * nblocks; -      unsigned y = initial_offsets[face][1] * nblocks; -      unsigned d = nblocks; +      /* all calculations in pixels */ +      unsigned total_height = tex->total_nblocksy * 4; +      unsigned x = initial_offsets[face][0] * dim; +      unsigned y = initial_offsets[face][1] * dim; +      unsigned d = dim; -#if 0 /* Fix and enable this code for compressed formats */ -      if (nblocks == 4 && face >= 4) { -         y = tex->total_height - 4; +      if (dim == 4 && face >= 4) {           x = (face - 4) * 8; -      } -      else if (nblocks < 4 && (face > 0)) { -         y = tex->total_height - 4; +         y = tex->total_nblocksy * 4 - 4; /* 4 = 1 block */ +      } else if (dim < 4 && (face > 0)) {           x = face * 8; +         y = total_height - 4;        } -#endif        for (level = 0; level <= pt->last_level; level++) { -         i915_texture_set_image_offset(tex, level, face, x, y); +         i915_texture_set_image_offset(tex, level, face, +                                       util_format_get_nblocksx(pt->format, x), +                                       util_format_get_nblocksy(pt->format, y));           d >>= 1; -#if 0 /* Fix and enable this code for compressed formats */           switch (d) { -            case 4: -               switch (face) { -                  case PIPE_TEX_FACE_POS_X: -                  case PIPE_TEX_FACE_NEG_X: -                     x += step_offsets[face][0] * d; -                     y += step_offsets[face][1] * d; -                     break; -                  case PIPE_TEX_FACE_POS_Y: -                  case PIPE_TEX_FACE_NEG_Y: -                     y += 12; -                     x -= 8; -                     break; -                  case PIPE_TEX_FACE_POS_Z: -                  case PIPE_TEX_FACE_NEG_Z: -                     y = tex->total_height - 4; -                     x = (face - 4) * 8; -                     break; -               } -            case 2: -               y = tex->total_height - 4; -               x = 16 + face * 8; -               break; - -            case 1: -               x += 48; -               break; -            default: -#endif +         case 4: +            switch (face) { +            case PIPE_TEX_FACE_POS_X: +            case PIPE_TEX_FACE_NEG_X:                 x += step_offsets[face][0] * d;                 y += step_offsets[face][1] * d; -#if 0                 break; +            case PIPE_TEX_FACE_POS_Y: +            case PIPE_TEX_FACE_NEG_Y: +               y += 12; +               x -= 8; +               break; +            case PIPE_TEX_FACE_POS_Z: +            case PIPE_TEX_FACE_NEG_Z: +               y = total_height - 4; +               x = (face - 4) * 8; +               break; +            } +            break; +         case 2: +            y = total_height - 4; +            x = bottom_offsets[face]; +            break; +         case 1: +            x += 48; +            break; +         default: +            x += step_offsets[face][0] * d; +            y += step_offsets[face][1] * d; +            break;           } -#endif        }     }  } @@ -590,7 +607,10 @@ i945_texture_layout(struct i915_texture * tex)        i945_texture_layout_3d(tex);        break;     case PIPE_TEXTURE_CUBE: -      i945_texture_layout_cube(tex); +      if (!util_format_is_s3tc(pt->format)) +         i9x5_texture_layout_cube(tex); +      else +         i945_texture_layout_cube(tex);        break;     default:        assert(0); | 
