diff options
Diffstat (limited to 'src/gallium/drivers/softpipe/sp_tex_sample.c')
-rw-r--r-- | src/gallium/drivers/softpipe/sp_tex_sample.c | 177 |
1 files changed, 83 insertions, 94 deletions
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index b3a79732b46..ff83c66d8b2 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -437,8 +437,7 @@ wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size, /** - * For RECT textures / unnormalized texcoords - * Only a subset of wrap modes supported. + * PIPE_TEX_WRAP_CLAMP for nearest sampling, unnormalized coords. */ static void wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4]) @@ -452,7 +451,7 @@ wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4]) /** - * Handles clamp_to_edge and clamp_to_border: + * PIPE_TEX_WRAP_CLAMP_TO_BORDER for nearest sampling, unnormalized coords. */ static void wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size, @@ -460,14 +459,27 @@ wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size, { uint ch; for (ch = 0; ch < 4; ch++) { + icoord[ch]= util_ifloor( CLAMP(s[ch], -0.5F, (float) size + 0.5F) ); + } +} + + +/** + * PIPE_TEX_WRAP_CLAMP_TO_EDGE for nearest sampling, unnormalized coords. + */ +static void +wrap_nearest_unorm_clamp_to_edge(const float s[4], unsigned size, + int icoord[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) ); } } /** - * For RECT textures / unnormalized texcoords. - * Only a subset of wrap modes supported. + * PIPE_TEX_WRAP_CLAMP for linear sampling, unnormalized coords. */ static void wrap_linear_unorm_clamp(const float s[4], unsigned size, @@ -484,13 +496,36 @@ wrap_linear_unorm_clamp(const float s[4], unsigned size, } +/** + * PIPE_TEX_WRAP_CLAMP_TO_BORDER for linear sampling, unnormalized coords. + */ static void wrap_linear_unorm_clamp_to_border(const float s[4], unsigned size, int icoord0[4], int icoord1[4], float w[4]) { uint ch; for (ch = 0; ch < 4; ch++) { - float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F); + float u = CLAMP(s[ch], -0.5F, (float) size + 0.5F); + u -= 0.5F; + icoord0[ch] = util_ifloor(u); + icoord1[ch] = icoord0[ch] + 1; + if (icoord1[ch] > (int) size - 1) + icoord1[ch] = size - 1; + w[ch] = frac(u); + } +} + + +/** + * PIPE_TEX_WRAP_CLAMP_TO_EDGE for linear sampling, unnormalized coords. + */ +static void +wrap_linear_unorm_clamp_to_edge(const float s[4], unsigned size, + int icoord0[4], int icoord1[4], float w[4]) +{ + uint ch; + for (ch = 0; ch < 4; ch++) { + float u = CLAMP(s[ch], +0.5F, (float) size - 0.5F); u -= 0.5F; icoord0[ch] = util_ifloor(u); icoord1[ch] = icoord0[ch] + 1; @@ -512,7 +547,7 @@ compute_lambda_1d(const struct sp_sampler_varient *samp, const float t[QUAD_SIZE], const float p[QUAD_SIZE]) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float rho = MAX2(dsdx, dsdy) * texture->width0; @@ -527,7 +562,7 @@ compute_lambda_2d(const struct sp_sampler_varient *samp, const float t[QUAD_SIZE], const float p[QUAD_SIZE]) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); @@ -546,7 +581,7 @@ compute_lambda_3d(const struct sp_sampler_varient *samp, const float t[QUAD_SIZE], const float p[QUAD_SIZE]) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]); float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]); float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]); @@ -616,7 +651,7 @@ static INLINE const float * get_texel_2d(const struct sp_sampler_varient *samp, union tex_tile_address addr, int x, int y) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level = addr.bits.level; if (x < 0 || x >= (int) u_minify(texture->width0, level) || @@ -709,7 +744,7 @@ static INLINE const float * get_texel_3d(const struct sp_sampler_varient *samp, union tex_tile_address addr, int x, int y, int z) { - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level = addr.bits.level; if (x < 0 || x >= (int) u_minify(texture->width0, level) || @@ -897,7 +932,7 @@ img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width; int x[4]; @@ -933,7 +968,7 @@ img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height; int x[4], y[4]; @@ -981,7 +1016,7 @@ img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; const unsigned *faces = samp->faces; /* zero when not cube-mapping */ unsigned level0, j; int width, height; @@ -1021,7 +1056,7 @@ img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height, depth; int x[4], y[4], z[4]; @@ -1063,7 +1098,7 @@ img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width; int x0[4], x1[4]; @@ -1103,7 +1138,7 @@ img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height; int x0[4], y0[4], x1[4], y1[4]; @@ -1150,7 +1185,7 @@ img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; const unsigned *faces = samp->faces; /* zero when not cube-mapping */ unsigned level0, j; int width, height; @@ -1199,7 +1234,7 @@ img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; unsigned level0, j; int width, height, depth; int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4]; @@ -1275,7 +1310,7 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; int level0; float lambda; float lod[QUAD_SIZE]; @@ -1338,7 +1373,7 @@ mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, float rgba[NUM_CHANNELS][QUAD_SIZE]) { struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; float lambda; float lod[QUAD_SIZE]; @@ -1426,7 +1461,7 @@ mip_filter_linear_2d_linear_repeat_POT( float rgba[NUM_CHANNELS][QUAD_SIZE]) { struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); - const struct pipe_texture *texture = samp->texture; + const struct pipe_resource *texture = samp->texture; int level0; float lambda; float lod[QUAD_SIZE]; @@ -1579,7 +1614,6 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; float ssss[4], tttt[4]; - unsigned face; /* major axis @@ -1593,7 +1627,8 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz */ - /* First choose the cube face. + /* Choose the cube face and compute new s/t coords for the 2D face. + * * Use the same cube face for all four pixels in the quad. * * This isn't ideal, but if we want to use a different cube face @@ -1612,82 +1647,34 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); if (arx >= ary && arx >= arz) { - if (rx >= 0.0F) { - face = PIPE_TEX_FACE_POS_X; - } - else { - face = PIPE_TEX_FACE_NEG_X; + float sign = (rx >= 0.0F) ? 1.0F : -1.0F; + uint face = (rx >= 0.0F) ? PIPE_TEX_FACE_POS_X : PIPE_TEX_FACE_NEG_X; + for (j = 0; j < QUAD_SIZE; j++) { + const float ima = -0.5F / fabsf(s[j]); + ssss[j] = sign * p[j] * ima + 0.5F; + tttt[j] = t[j] * ima + 0.5F; + samp->faces[j] = face; } } else if (ary >= arx && ary >= arz) { - if (ry >= 0.0F) { - face = PIPE_TEX_FACE_POS_Y; - } - else { - face = PIPE_TEX_FACE_NEG_Y; + float sign = (ry >= 0.0F) ? 1.0F : -1.0F; + uint face = (ry >= 0.0F) ? PIPE_TEX_FACE_POS_Y : PIPE_TEX_FACE_NEG_Y; + for (j = 0; j < QUAD_SIZE; j++) { + const float ima = -0.5F / fabsf(t[j]); + ssss[j] = -s[j] * ima + 0.5F; + tttt[j] = sign * -p[j] * ima + 0.5F; + samp->faces[j] = face; } } else { - if (rz > 0.0F) { - face = PIPE_TEX_FACE_POS_Z; + float sign = (rz >= 0.0F) ? 1.0F : -1.0F; + uint face = (rz >= 0.0F) ? PIPE_TEX_FACE_POS_Z : PIPE_TEX_FACE_NEG_Z; + for (j = 0; j < QUAD_SIZE; j++) { + const float ima = -0.5 / fabsf(p[j]); + ssss[j] = sign * -s[j] * ima + 0.5F; + tttt[j] = t[j] * ima + 0.5F; + samp->faces[j] = face; } - else { - face = PIPE_TEX_FACE_NEG_Z; - } - } - } - - /* Now compute the 2D _face_ texture coords from the - * 3D _cube_ texture coords. - */ - for (j = 0; j < QUAD_SIZE; j++) { - const float rx = s[j], ry = t[j], rz = p[j]; - const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); - float sc, tc, ma; - - switch (face) { - case PIPE_TEX_FACE_POS_X: - sc = -rz; - tc = -ry; - ma = arx; - break; - case PIPE_TEX_FACE_NEG_X: - sc = rz; - tc = -ry; - ma = arx; - break; - case PIPE_TEX_FACE_POS_Y: - sc = rx; - tc = rz; - ma = ary; - break; - case PIPE_TEX_FACE_NEG_Y: - sc = rx; - tc = -rz; - ma = ary; - break; - case PIPE_TEX_FACE_POS_Z: - sc = rx; - tc = -ry; - ma = arz; - break; - case PIPE_TEX_FACE_NEG_Z: - sc = -rx; - tc = -ry; - ma = arz; - break; - default: - assert(0 && "bad cube face"); - sc = 0.0F; - tc = 0.0F; - ma = 0.0F; - } - - { - const float ima = 1.0 / ma; - ssss[j] = ( sc * ima + 1.0F ) * 0.5F; - tttt[j] = ( tc * ima + 1.0F ) * 0.5F; - samp->faces[j] = face; } } @@ -1707,6 +1694,7 @@ get_nearest_unorm_wrap(unsigned mode) case PIPE_TEX_WRAP_CLAMP: return wrap_nearest_unorm_clamp; case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return wrap_nearest_unorm_clamp_to_edge; case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return wrap_nearest_unorm_clamp_to_border; default: @@ -1750,6 +1738,7 @@ get_linear_unorm_wrap(unsigned mode) case PIPE_TEX_WRAP_CLAMP: return wrap_linear_unorm_clamp; case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return wrap_linear_unorm_clamp_to_edge; case PIPE_TEX_WRAP_CLAMP_TO_BORDER: return wrap_linear_unorm_clamp_to_border; default: @@ -1878,7 +1867,7 @@ get_img_filter(const union sp_sampler_key key, void sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp, struct softpipe_tex_tile_cache *tex_cache, - const struct pipe_texture *texture ) + const struct pipe_resource *texture ) { const struct pipe_sampler_state *sampler = samp->sampler; |