diff options
-rw-r--r-- | src/mesa/pipe/cell/spu/spu_texture.c | 67 | ||||
-rw-r--r-- | src/mesa/pipe/cell/spu/spu_texture.h | 4 |
2 files changed, 71 insertions, 0 deletions
diff --git a/src/mesa/pipe/cell/spu/spu_texture.c b/src/mesa/pipe/cell/spu/spu_texture.c index b52df970d0..26a5eefc48 100644 --- a/src/mesa/pipe/cell/spu/spu_texture.c +++ b/src/mesa/pipe/cell/spu/spu_texture.c @@ -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; +} diff --git a/src/mesa/pipe/cell/spu/spu_texture.h b/src/mesa/pipe/cell/spu/spu_texture.h index 5bc8e71879..25cbe9b3c6 100644 --- a/src/mesa/pipe/cell/spu/spu_texture.h +++ b/src/mesa/pipe/cell/spu/spu_texture.h @@ -40,4 +40,8 @@ extern uint sample_texture(vector float texcoord); +extern uint +sample_texture_bilinear(vector float texcoord); + + #endif /* SPU_TEXTURE_H */ |