diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2008-10-14 12:11:52 -0600 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2008-10-14 12:54:30 -0600 | 
| commit | f8bddf698d523f597fea0f721b064daee81d8005 (patch) | |
| tree | 788ad495cf57b77835bb9432eb3e6c263f81720d | |
| parent | 3baf83db3c60be8185bc68a0aa3adbce80d9025e (diff) | |
cell: basic mipmap filtering works now
Though, only GL_MIPMAP_NEAREST / GL_LINEAR works right now.
| -rw-r--r-- | src/gallium/drivers/cell/spu/spu_command.c | 21 | ||||
| -rw-r--r-- | src/gallium/drivers/cell/spu/spu_funcs.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/cell/spu/spu_main.h | 3 | ||||
| -rw-r--r-- | src/gallium/drivers/cell/spu/spu_texture.c | 106 | ||||
| -rw-r--r-- | src/gallium/drivers/cell/spu/spu_texture.h | 8 | 
5 files changed, 79 insertions, 61 deletions
| diff --git a/src/gallium/drivers/cell/spu/spu_command.c b/src/gallium/drivers/cell/spu/spu_command.c index 089af22415..4e98eea338 100644 --- a/src/gallium/drivers/cell/spu/spu_command.c +++ b/src/gallium/drivers/cell/spu/spu_command.c @@ -301,16 +301,18 @@ cmd_state_sampler(const struct cell_command_sampler *sampler)     DEBUG_PRINTF("SAMPLER [%u]\n", sampler->unit);     spu.sampler[sampler->unit] = sampler->state; -#if 0 +     if (spu.sampler[sampler->unit].min_mip_filter != PIPE_TEX_MIPFILTER_NONE) { +      /* use lambda/lod to determine min vs. mag filter */        spu.sample_texture4[sampler->unit] = sample_texture4_lod;     } -   else -#endif -   if (spu.sampler[sampler->unit].min_img_filter == PIPE_TEX_FILTER_LINEAR) { +   else if (spu.sampler[sampler->unit].min_img_filter +            == PIPE_TEX_FILTER_LINEAR) { +      /* min = mag = bilinear */        spu.sample_texture4[sampler->unit] = sample_texture4_bilinear;     }     else { +      /* min = mag = inearest */        spu.sample_texture4[sampler->unit] = sample_texture4_nearest;     }  } @@ -322,8 +324,12 @@ cmd_state_texture(const struct cell_command_texture *texture)     const uint unit = texture->unit;     uint i; +   //if (spu.init.id==0) Debug=1; +     DEBUG_PRINTF("TEXTURE [%u]\n", texture->unit); +   spu.texture[unit].max_level = 0; +     for (i = 0; i < CELL_MAX_TEXTURE_LEVELS; i++) {        uint width = texture->width[i];        uint height = texture->height[i]; @@ -335,14 +341,19 @@ cmd_state_texture(const struct cell_command_texture *texture)        spu.texture[unit].level[i].width = width;        spu.texture[unit].level[i].height = height; -      spu.texture[unit].level[i].tiles_per_row = width / TILE_SIZE; +      spu.texture[unit].level[i].tiles_per_row = +         (width + TILE_SIZE - 1) / TILE_SIZE;        spu.texture[unit].level[i].width4 = spu_splats((float) width);        spu.texture[unit].level[i].height4 = spu_splats((float) height);        spu.texture[unit].level[i].tex_size_x_mask = spu_splats(width - 1);        spu.texture[unit].level[i].tex_size_y_mask = spu_splats(height - 1); + +      if (texture->start[i]) +         spu.texture[unit].max_level = i;     } +   //Debug=0;  } diff --git a/src/gallium/drivers/cell/spu/spu_funcs.c b/src/gallium/drivers/cell/spu/spu_funcs.c index f2946010bd..66b82f673d 100644 --- a/src/gallium/drivers/cell/spu/spu_funcs.c +++ b/src/gallium/drivers/cell/spu/spu_funcs.c @@ -106,7 +106,7 @@ spu_txp(vector float s, vector float t, vector float r, vector float q,          unsigned unit)  {     struct vec_4x4 colors; -   spu.sample_texture4[unit](s, t, r, q, unit, colors.v); +   spu.sample_texture4[unit](s, t, r, q, unit, 0, colors.v);     return colors;  } diff --git a/src/gallium/drivers/cell/spu/spu_main.h b/src/gallium/drivers/cell/spu/spu_main.h index 9515543efe..cfb645add0 100644 --- a/src/gallium/drivers/cell/spu/spu_main.h +++ b/src/gallium/drivers/cell/spu/spu_main.h @@ -68,7 +68,7 @@ typedef void (*spu_sample_texture4_func)(vector float s,                                           vector float t,                                           vector float r,                                           vector float q, -                                         uint unit, +                                         uint unit, uint level,                                           vector float colors[4]); @@ -121,6 +121,7 @@ struct spu_texture_level  struct spu_texture  {     struct spu_texture_level level[CELL_MAX_TEXTURE_LEVELS]; +   uint max_level;  } ALIGN16_ATTRIB; diff --git a/src/gallium/drivers/cell/spu/spu_texture.c b/src/gallium/drivers/cell/spu/spu_texture.c index 96c09e3ccb..10036330c6 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.c +++ b/src/gallium/drivers/cell/spu/spu_texture.c @@ -26,7 +26,6 @@   **************************************************************************/ -#include <transpose_matrix4x4.h>  #include <math.h>  #include "pipe/p_compiler.h" @@ -43,12 +42,14 @@  void  invalidate_tex_cache(void)  { -   uint lvl = 0; -   uint unit = 0; -   uint bytes = 4 * spu.texture[unit].level[lvl].width -      * spu.texture[unit].level[lvl].height; +   uint lvl; +   for (lvl = 0; lvl < CELL_MAX_TEXTURE_LEVELS; lvl++) { +      uint unit = 0; +      uint bytes = 4 * spu.texture[unit].level[lvl].width +         * spu.texture[unit].level[lvl].height; -   spu_dcache_mark_dirty((unsigned) spu.texture[unit].level[lvl].start, bytes); +      spu_dcache_mark_dirty((unsigned) spu.texture[unit].level[lvl].start, bytes); +   }  } @@ -71,8 +72,8 @@ get_four_texels(uint unit, uint level, vec_uint4 x, vec_uint4 y,  {     const struct spu_texture_level *tlevel = &spu.texture[unit].level[level];     const unsigned texture_ea = (uintptr_t) tlevel->start; -   vec_uint4 tile_x = spu_rlmask(x, -5);  /* tile_x = x / 32 */ -   vec_uint4 tile_y = spu_rlmask(y, -5);  /* tile_y = y / 32 */ +   const vec_uint4 tile_x = spu_rlmask(x, -5);  /* tile_x = x / 32 */ +   const vec_uint4 tile_y = spu_rlmask(y, -5);  /* tile_y = y / 32 */     const qword offset_x = si_andi((qword) x, 0x1f); /* offset_x = x & 0x1f */     const qword offset_y = si_andi((qword) y, 0x1f); /* offset_y = y & 0x1f */ @@ -106,20 +107,19 @@ get_four_texels(uint unit, uint level, vec_uint4 x, vec_uint4 y,  void  sample_texture4_nearest(vector float s, vector float t,                          vector float r, vector float q, -                        uint unit, vector float colors[4]) +                        uint unit, uint level, vector float colors[4])  { -   const uint lvl = 0; -   vector float ss = spu_mul(s, spu.texture[unit].level[lvl].width4); -   vector float tt = spu_mul(t, spu.texture[unit].level[lvl].height4); +   vector float ss = spu_mul(s, spu.texture[unit].level[level].width4); +   vector float tt = spu_mul(t, spu.texture[unit].level[level].height4);     vector unsigned int is = spu_convtu(ss, 0);     vector unsigned int it = spu_convtu(tt, 0);     vec_uint4 texels[4];     /* PIPE_TEX_WRAP_REPEAT */ -   is = spu_and(is, spu.texture[unit].level[lvl].tex_size_x_mask); -   it = spu_and(it, spu.texture[unit].level[lvl].tex_size_y_mask); +   is = spu_and(is, spu.texture[unit].level[level].tex_size_x_mask); +   it = spu_and(it, spu.texture[unit].level[level].tex_size_y_mask); -   get_four_texels(unit, lvl, is, it, texels); +   get_four_texels(unit, level, is, it, texels);     /* convert four packed ARGBA pixels to float RRRR,GGGG,BBBB,AAAA */     spu_unpack_A8R8G8B8_transpose4(texels, colors); @@ -133,11 +133,10 @@ sample_texture4_nearest(vector float s, vector float t,  void  sample_texture4_bilinear(vector float s, vector float t,                           vector float r, vector float q, -                         uint unit, vector float colors[4]) +                         uint unit, uint level, vector float colors[4])  { -   const uint lvl = 0; -   vector float ss = spu_madd(s, spu.texture[unit].level[lvl].width4,  spu_splats(-0.5f)); -   vector float tt = spu_madd(t, spu.texture[unit].level[lvl].height4, spu_splats(-0.5f)); +   vector float ss = spu_madd(s, spu.texture[unit].level[level].width4,  spu_splats(-0.5f)); +   vector float tt = spu_madd(t, spu.texture[unit].level[level].height4, spu_splats(-0.5f));     vector unsigned int is0 = spu_convtu(ss, 0);     vector unsigned int it0 = spu_convtu(tt, 0); @@ -147,17 +146,17 @@ sample_texture4_bilinear(vector float s, vector float t,     vector unsigned int it1 = spu_add(it0, 1);     /* PIPE_TEX_WRAP_REPEAT */ -   is0 = spu_and(is0, spu.texture[unit].level[lvl].tex_size_x_mask); -   it0 = spu_and(it0, spu.texture[unit].level[lvl].tex_size_y_mask); -   is1 = spu_and(is1, spu.texture[unit].level[lvl].tex_size_x_mask); -   it1 = spu_and(it1, spu.texture[unit].level[lvl].tex_size_y_mask); +   is0 = spu_and(is0, spu.texture[unit].level[level].tex_size_x_mask); +   it0 = spu_and(it0, spu.texture[unit].level[level].tex_size_y_mask); +   is1 = spu_and(is1, spu.texture[unit].level[level].tex_size_x_mask); +   it1 = spu_and(it1, spu.texture[unit].level[level].tex_size_y_mask);     /* get packed int texels */     vector unsigned int texels[16]; -   get_four_texels(unit, lvl, is0, it0, texels + 0);  /* upper-left */ -   get_four_texels(unit, lvl, is1, it0, texels + 4);  /* upper-right */ -   get_four_texels(unit, lvl, is0, it1, texels + 8);  /* lower-left */ -   get_four_texels(unit, lvl, is1, it1, texels + 12); /* lower-right */ +   get_four_texels(unit, level, is0, it0, texels + 0);  /* upper-left */ +   get_four_texels(unit, level, is1, it0, texels + 4);  /* upper-right */ +   get_four_texels(unit, level, is0, it1, texels + 8);  /* lower-left */ +   get_four_texels(unit, level, is1, it1, texels + 12); /* lower-right */     /* XXX possibly rework following code to compute the weighted sample      * colors with integer arithmetic for fewer int->float conversions. @@ -273,14 +272,13 @@ transpose(vector unsigned int *mOut0,   */  void  sample_texture4_bilinear_2(vector float s, vector float t, -                         vector float r, vector float q, -                         uint unit, vector float colors[4]) +                           vector float r, vector float q, +                           uint unit, uint level, vector float colors[4])  { -   const uint lvl = 0;     static const vector float half = {-0.5f, -0.5f, -0.5f, -0.5f};     /* Scale texcoords by size of texture, and add half pixel bias */ -   vector float ss = spu_madd(s, spu.texture[unit].level[lvl].width4, half); -   vector float tt = spu_madd(t, spu.texture[unit].level[lvl].height4, half); +   vector float ss = spu_madd(s, spu.texture[unit].level[level].width4, half); +   vector float tt = spu_madd(t, spu.texture[unit].level[level].height4, half);     /* convert float coords to fixed-pt coords with 8 fraction bits */     vector unsigned int is = spu_convtu(ss, 8); @@ -301,17 +299,17 @@ sample_texture4_bilinear_2(vector float s, vector float t,     vector unsigned int it1 = spu_add(it0, 1);     /* PIPE_TEX_WRAP_REPEAT */ -   is0 = spu_and(is0, spu.texture[unit].level[lvl].tex_size_x_mask); -   it0 = spu_and(it0, spu.texture[unit].level[lvl].tex_size_y_mask); -   is1 = spu_and(is1, spu.texture[unit].level[lvl].tex_size_x_mask); -   it1 = spu_and(it1, spu.texture[unit].level[lvl].tex_size_y_mask); +   is0 = spu_and(is0, spu.texture[unit].level[level].tex_size_x_mask); +   it0 = spu_and(it0, spu.texture[unit].level[level].tex_size_y_mask); +   is1 = spu_and(is1, spu.texture[unit].level[level].tex_size_x_mask); +   it1 = spu_and(it1, spu.texture[unit].level[level].tex_size_y_mask);     /* get packed int texels */     vector unsigned int texels[16]; -   get_four_texels(unit, lvl, is0, it0, texels + 0);  /* upper-left */ -   get_four_texels(unit, lvl, is1, it0, texels + 4);  /* upper-right */ -   get_four_texels(unit, lvl, is0, it1, texels + 8);  /* lower-left */ -   get_four_texels(unit, lvl, is1, it1, texels + 12); /* lower-right */ +   get_four_texels(unit, level, is0, it0, texels + 0);  /* upper-left */ +   get_four_texels(unit, level, is1, it0, texels + 4);  /* upper-right */ +   get_four_texels(unit, level, is0, it1, texels + 8);  /* lower-left */ +   get_four_texels(unit, level, is1, it1, texels + 12); /* lower-right */     /* twiddle packed 32-bit BGRA pixels into RGBA as four unsigned ints */     { @@ -379,9 +377,9 @@ sample_texture4_bilinear_2(vector float s, vector float t,  static float  compute_lambda(uint unit, vector float s, vector float t)  { -   uint lvl = 0; -   float width = spu.texture[unit].level[lvl].width; -   float height = spu.texture[unit].level[lvl].width; +   uint baseLevel = 0; +   float width = spu.texture[unit].level[baseLevel].width; +   float height = spu.texture[unit].level[baseLevel].width;     float dsdx = width * (spu_extract(s, 1) - spu_extract(s, 0));     float dsdy = width * (spu_extract(s, 2) - spu_extract(s, 0));     float dtdx = height * (spu_extract(t, 1) - spu_extract(t, 0)); @@ -402,22 +400,30 @@ compute_lambda(uint unit, vector float s, vector float t)  void  sample_texture4_lod(vector float s, vector float t,                      vector float r, vector float q, -                    uint unit, vector float colors[4]) +                    uint unit, uint level, vector float colors[4])  { +   /* +    * Note that we're computing a lambda/lod here that's used for all +    * four pixels in the quad. +    */     float lambda = compute_lambda(unit, s, t); +   /* apply lod bias */ +   lambda += spu.sampler[unit].lod_bias; + +   /* clamp */     if (lambda < spu.sampler[unit].min_lod)        lambda = spu.sampler[unit].min_lod;     else if (lambda > spu.sampler[unit].max_lod)        lambda = spu.sampler[unit].max_lod; -   /* hack for now */ -   int level = (int) lambda; -   if (level > 3) -      level = 3; +   /* convert to int level */ +   level = (int) (lambda + 0.5f); +   ASSERT(level >= 0); + +   if (level > spu.texture[unit].max_level) +      level = spu.texture[unit].max_level; -   /*     sample_texture4_bilinear_2(s, t, r, q, unit, level, colors); -   */  } diff --git a/src/gallium/drivers/cell/spu/spu_texture.h b/src/gallium/drivers/cell/spu/spu_texture.h index 4802f7c47c..ec06a50b4a 100644 --- a/src/gallium/drivers/cell/spu/spu_texture.h +++ b/src/gallium/drivers/cell/spu/spu_texture.h @@ -39,24 +39,24 @@ invalidate_tex_cache(void);  extern void  sample_texture4_nearest(vector float s, vector float t,                          vector float r, vector float q, -                        uint unit, vector float colors[4]); +                        uint unit, uint level, vector float colors[4]);  extern void  sample_texture4_bilinear(vector float s, vector float t,                           vector float r, vector float q, -                         uint unit, vector float colors[4]); +                         uint unit, uint level, vector float colors[4]);  extern void  sample_texture4_bilinear_2(vector float s, vector float t,                           vector float r, vector float q, -                         uint unit, vector float colors[4]); +                           uint unit, uint level, vector float colors[4]);  extern void  sample_texture4_lod(vector float s, vector float t,                      vector float r, vector float q, -                    uint unit, vector float colors[4]); +                    uint unit, uint level, vector float colors[4]);  #endif /* SPU_TEXTURE_H */ | 
