Cell: implement basic bilinear texture sampler

This commit is contained in:
Brian 2008-02-04 12:50:42 -07:00
parent 9a5074217f
commit 0a45f75948
2 changed files with 71 additions and 0 deletions

View 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;
}

View file

@ -40,4 +40,8 @@ extern uint
sample_texture(vector float texcoord);
extern uint
sample_texture_bilinear(vector float texcoord);
#endif /* SPU_TEXTURE_H */