Cell: implement basic bilinear texture sampler
authorBrian <brian.paul@tungstengraphics.com>
Mon, 4 Feb 2008 19:50:42 +0000 (12:50 -0700)
committerBen Skeggs <skeggsb@gmail.com>
Fri, 15 Feb 2008 02:50:29 +0000 (13:50 +1100)
src/mesa/pipe/cell/spu/spu_texture.c
src/mesa/pipe/cell/spu/spu_texture.h

index b52df970d07c5f367fd518a48a81da92dbc1880c..26a5eefc482a69813e1b6270473b7705f8b7e061 100644 (file)
@@ -32,6 +32,7 @@
 #include "spu_main.h"
 #include "spu_texture.h"
 #include "spu_tile.h"
+#include "spu_colorpack.h"
 
 
 /**
@@ -140,3 +141,69 @@ sample_texture(vector float texcoord)
    uint texel = tex_tiles[pos].ui[spu_extract(ij, 1)][spu_extract(ij, 0)];
    return texel;
 }
+
+
+uint
+sample_texture_bilinear(vector float texcoord)
+{
+   static const vector unsigned int offset10 = {1, 0, 0, 0};
+   static const vector unsigned int offset01 = {0, 1, 0, 0};
+
+   vector float tc = spu_mul(texcoord, spu.tex_size);
+   /* itcST */
+   vector unsigned int itc00 = spu_convtu(tc, 0);  /* convert to int */
+   vector unsigned int itc01 = spu_add(itc00, offset01);
+   vector unsigned int itc10 = spu_add(itc00, offset10);
+   vector unsigned int itc11 = spu_add(itc10, offset01);
+
+   itc00 = spu_and(itc00, spu.tex_size_mask);        /* mask (GL_REPEAT) */
+   itc01 = spu_and(itc01, spu.tex_size_mask);        /* mask (GL_REPEAT) */
+   itc10 = spu_and(itc10, spu.tex_size_mask);        /* mask (GL_REPEAT) */
+   itc11 = spu_and(itc11, spu.tex_size_mask);        /* mask (GL_REPEAT) */
+
+   /* intra tile addr */
+   vector unsigned int ij00 = spu_and(itc00, TILE_SIZE-1);
+   vector unsigned int ij01 = spu_and(itc01, TILE_SIZE-1);
+   vector unsigned int ij10 = spu_and(itc10, TILE_SIZE-1);
+   vector unsigned int ij11 = spu_and(itc11, TILE_SIZE-1);
+
+   uint pos00 = get_tex_tile(itc00);
+   uint pos01 = get_tex_tile(itc01);
+   uint pos10 = get_tex_tile(itc10);
+   uint pos11 = get_tex_tile(itc11);
+
+   vector float texel00 = spu_unpack_color(tex_tiles[pos00].ui[spu_extract(ij00, 1)][spu_extract(ij00, 0)]);
+   vector float texel01 = spu_unpack_color(tex_tiles[pos01].ui[spu_extract(ij01, 1)][spu_extract(ij01, 0)]);
+   vector float texel10 = spu_unpack_color(tex_tiles[pos10].ui[spu_extract(ij10, 1)][spu_extract(ij10, 0)]);
+   vector float texel11 = spu_unpack_color(tex_tiles[pos11].ui[spu_extract(ij11, 1)][spu_extract(ij11, 0)]);
+
+   /* Compute weighting factors in [0,1]
+    * Multiply texcoord by 1024, AND with 1023, convert back to float.
+    */
+   vector float tc1024 = spu_mul(tc, spu_splats(1024.0f));
+   vector signed int itc1024 = spu_convts(tc1024, 0);
+   itc1024 = spu_and(itc1024, spu_splats((1 << 10) - 1));
+   vector float weight = spu_convtf(itc1024, 10);
+
+   /* smeared frac and 1-frac */
+   vector float sfrac = spu_splats(spu_extract(weight, 0));
+   vector float tfrac = spu_splats(spu_extract(weight, 1));
+   vector float sfrac1 = spu_sub(spu_splats(1.0f), sfrac);
+   vector float tfrac1 = spu_sub(spu_splats(1.0f), tfrac);
+
+   /* multiply the samples (colors) by the S/T weights */
+   texel00 = spu_mul(spu_mul(texel00, sfrac1), tfrac1);
+   texel10 = spu_mul(spu_mul(texel10, sfrac ), tfrac1);
+   texel01 = spu_mul(spu_mul(texel01, sfrac1), tfrac );
+   texel11 = spu_mul(spu_mul(texel11, sfrac ), tfrac );
+
+   /* compute sum of weighted samples */
+   vector float texel_sum = spu_add(texel00, texel01);
+   texel_sum = spu_add(texel_sum, texel10);
+   texel_sum = spu_add(texel_sum, texel11);
+
+   /* convert to uint color */
+   uint texel = spu_pack_R8G8B8A8(texel_sum);
+
+   return texel;
+}
index 5bc8e71879bee70850d5005429f15f185e838866..25cbe9b3c64b9c17c8597c62e2b97f2d8911deef 100644 (file)
@@ -40,4 +40,8 @@ extern uint
 sample_texture(vector float texcoord);
 
 
+extern uint
+sample_texture_bilinear(vector float texcoord);
+
+
 #endif /* SPU_TEXTURE_H */