-lp_get_samples_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
- unsigned j;
- unsigned level = samp->level;
- unsigned xpot = 1 << (samp->xpot - level);
- unsigned ypot = 1 << (samp->ypot - level);
- unsigned xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */
- unsigned ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */
-
- for (j = 0; j < QUAD_SIZE; j++) {
- int c;
-
- float u = s[j] * xpot - 0.5F;
- float v = t[j] * ypot - 0.5F;
-
- int uflr = util_ifloor(u);
- int vflr = util_ifloor(v);
-
- float xw = u - (float)uflr;
- float yw = v - (float)vflr;
-
- int x0 = uflr & (xpot - 1);
- int y0 = vflr & (ypot - 1);
-
- const float *tx[4];
-
-
- /* Can we fetch all four at once:
- */
- if (x0 < xmax && y0 < ymax)
- {
- get_texel_quad_2d(tgsi_sampler, 0, level, x0, y0, tx);
- }
- else
- {
- unsigned x1 = (x0 + 1) & (xpot - 1);
- unsigned y1 = (y0 + 1) & (ypot - 1);
- get_texel_quad_2d_mt(tgsi_sampler, 0, level,
- x0, y0, x1, y1, tx);
- }
-
-
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp_2d(xw, yw,
- tx[0][c], tx[1][c],
- tx[2][c], tx[3][c]);
- }
- }
-}
-
-
-static void
-lp_get_samples_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
- unsigned j;
- unsigned level = samp->level;
- unsigned xpot = 1 << (samp->xpot - level);
- unsigned ypot = 1 << (samp->ypot - level);
-
- for (j = 0; j < QUAD_SIZE; j++) {
- int c;
-
- float u = s[j] * xpot;
- float v = t[j] * ypot;
-
- int uflr = util_ifloor(u);
- int vflr = util_ifloor(v);
-
- int x0 = uflr & (xpot - 1);
- int y0 = vflr & (ypot - 1);
-
- const float *out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
-
- for (c = 0; c < 4; c++) {
- rgba[c][j] = out[c];
- }
- }
-}
-
-
-static void
-lp_get_samples_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
- unsigned j;
- unsigned level = samp->level;
- unsigned xpot = 1 << (samp->xpot - level);
- unsigned ypot = 1 << (samp->ypot - level);
-
- for (j = 0; j < QUAD_SIZE; j++) {
- int c;
-
- float u = s[j] * xpot;
- float v = t[j] * ypot;
-
- int x0, y0;
- const float *out;
-
- x0 = util_ifloor(u);
- if (x0 < 0)
- x0 = 0;
- else if (x0 > xpot - 1)
- x0 = xpot - 1;
-
- y0 = util_ifloor(v);
- if (y0 < 0)
- y0 = 0;
- else if (y0 > ypot - 1)
- y0 = ypot - 1;
-
- out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
-
- for (c = 0; c < 4; c++) {
- rgba[c][j] = out[c];
- }
- }
-}
-
-
-static void
-lp_get_samples_2d_linear_mip_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
- const struct pipe_texture *texture = samp->texture;
- int level0;
- float lambda;
-
- lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
- level0 = (int)lambda;
-
- if (lambda < 0.0) {
- samp->level = 0;
- lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
- s, t, p, 0, rgba );
- }
- else if (level0 >= texture->last_level) {
- samp->level = texture->last_level;
- lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
- s, t, p, 0, rgba );
- }
- else {
- float levelBlend = lambda - level0;
- float rgba0[4][4];
- float rgba1[4][4];
- int c,j;
-
- samp->level = level0;
- lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
- s, t, p, 0, rgba0 );
-
- samp->level = level0+1;
- lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
- s, t, p, 0, rgba1 );
-
- for (j = 0; j < QUAD_SIZE; j++) {
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]);
- }
- }
- }
-}
-
-/**
- * Common code for sampling 1D/2D/cube textures.
- * Could probably extend for 3D...
- */
-static void
-lp_get_samples_2d_common(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE],
- const unsigned faces[4])
-{
- const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
- const struct pipe_texture *texture = samp->texture;
- const struct pipe_sampler_state *sampler = samp->sampler;
- unsigned level0, level1, j, imgFilter;
- int width, height;
- float levelBlend;
-
- choose_mipmap_levels(tgsi_sampler, s, t, p,
- lodbias,
- &level0, &level1, &levelBlend, &imgFilter);
-
- assert(sampler->normalized_coords);
-
- width = texture->width[level0];
- height = texture->height[level0];
-
- assert(width > 0);
-
- switch (imgFilter) {
- case PIPE_TEX_FILTER_NEAREST:
- {
- int x[4], y[4];
- nearest_texcoord_4(sampler->wrap_s, s, width, x);
- nearest_texcoord_4(sampler->wrap_t, t, height, y);
-
- for (j = 0; j < QUAD_SIZE; j++) {
- get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare(sampler, rgba, p, j);
- }
-
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- unsigned c;
- x[j] /= 2;
- y[j] /= 2;
- get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
- rgba2, j);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
- shadow_compare(sampler, rgba2, p, j);
- }
-
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
- }
- }
- }
- }
- break;
- case PIPE_TEX_FILTER_LINEAR:
- case PIPE_TEX_FILTER_ANISO:
- {
- int x0[4], y0[4], x1[4], y1[4];
- float xw[4], yw[4]; /* weights */
-
- linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
- linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
-
- for (j = 0; j < QUAD_SIZE; j++) {
- float tx[4][4]; /* texels */
- int c;
- get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
- get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
- get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
- get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare4(sampler, tx, p);
- }
-
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp_2d(xw[j], yw[j],
- tx[c][0], tx[c][1],
- tx[c][2], tx[c][3]);
- }
-
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
-
- /* XXX: This is incorrect -- will often end up with (x0
- * == x1 && y0 == y1), meaning that we fetch the same
- * texel four times and linearly interpolate between
- * identical values. The correct approach would be to
- * call linear_texcoord again for the second level.
- */
- x0[j] /= 2;
- y0[j] /= 2;
- x1[j] /= 2;
- y1[j] /= 2;
- get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
- get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
- get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
- get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
- shadow_compare4(sampler, tx, p);
- }
-
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba2[c][j] = lerp_2d(xw[j], yw[j],
- tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
- }
-
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
- }
- }
- }
- }
- break;
- default:
- assert(0);
- }
-}
-
-
-static INLINE void
-lp_get_samples_1d(struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- static const unsigned faces[4] = {0, 0, 0, 0};
- static const float tzero[4] = {0, 0, 0, 0};
- lp_get_samples_2d_common(sampler, s, tzero, NULL,
- lodbias, rgba, faces);
-}
-
-
-static INLINE void
-lp_get_samples_2d(struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- static const unsigned faces[4] = {0, 0, 0, 0};
- lp_get_samples_2d_common(sampler, s, t, p,
- lodbias, rgba, faces);
-}
-
-
-static INLINE void
-lp_get_samples_3d(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
- const struct pipe_texture *texture = samp->texture;
- const struct pipe_sampler_state *sampler = samp->sampler;
- /* get/map pipe_surfaces corresponding to 3D tex slices */
- unsigned level0, level1, j, imgFilter;
- int width, height, depth;
- float levelBlend;
- const uint face = 0;
-
- choose_mipmap_levels(tgsi_sampler, s, t, p,
- lodbias,
- &level0, &level1, &levelBlend, &imgFilter);
-
- assert(sampler->normalized_coords);
-
- width = texture->width[level0];
- height = texture->height[level0];
- depth = texture->depth[level0];
-
- assert(width > 0);
- assert(height > 0);
- assert(depth > 0);
-
- switch (imgFilter) {
- case PIPE_TEX_FILTER_NEAREST:
- {
- int x[4], y[4], z[4];
- nearest_texcoord_4(sampler->wrap_s, s, width, x);
- nearest_texcoord_4(sampler->wrap_t, t, height, y);
- nearest_texcoord_4(sampler->wrap_r, p, depth, z);
- for (j = 0; j < QUAD_SIZE; j++) {
- get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j);
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- unsigned c;
- x[j] /= 2;
- y[j] /= 2;
- z[j] /= 2;
- get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j);
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]);
- }
- }
- }
- }
- break;
- case PIPE_TEX_FILTER_LINEAR:
- case PIPE_TEX_FILTER_ANISO:
- {
- int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
- float xw[4], yw[4], zw[4]; /* interpolation weights */
- linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
- linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
- linear_texcoord_4(sampler->wrap_r, p, depth, z0, z1, zw);
-
- for (j = 0; j < QUAD_SIZE; j++) {
- int c;
- float tx0[4][4], tx1[4][4];
- get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0);
- get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1);
- get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2);
- get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3);
- get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0);
- get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1);
- get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2);
- get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3);
-
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
- tx0[c][0], tx0[c][1],
- tx0[c][2], tx0[c][3],
- tx1[c][0], tx1[c][1],
- tx1[c][2], tx1[c][3]);
- }
-
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- x0[j] /= 2;
- y0[j] /= 2;
- z0[j] /= 2;
- x1[j] /= 2;
- y1[j] /= 2;
- z1[j] /= 2;
- get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0);
- get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1);
- get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2);
- get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3);
- get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0);
- get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1);
- get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2);
- get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3);
-
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j],
- tx0[c][0], tx0[c][1],
- tx0[c][2], tx0[c][3],
- tx1[c][0], tx1[c][1],
- tx1[c][2], tx1[c][3]);
- }
-
- /* blend mipmap levels */
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
- }
- }
- }
- }
- break;
- default:
- assert(0);
- }
-}
-
-
-static void
-lp_get_samples_cube(struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- unsigned faces[QUAD_SIZE], j;
- float ssss[4], tttt[4];
- for (j = 0; j < QUAD_SIZE; j++) {
- faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);