[Mesa-dev] [PATCH 1/3] softpipe: implement coord clamping for texel fetches (TXF)

Jose Fonseca jfonseca at vmware.com
Tue May 1 09:28:52 PDT 2012


The whole series looks good to me.

Jose

----- Original Message -----
> From: Brian Paul <brianp at vmware.com>
> 
> The GL spec says out of bounds fetches produce undefined results.
> Use clamping to avoid failed assertions or crashes.
> 
> Fixes failed assertion in
> https://bugs.freedesktop.org/show_bug.cgi?id=49125
> but the test still fails.
> ---
>  src/gallium/drivers/softpipe/sp_tex_sample.c |   45
>  ++++++++++++++++++--------
>  1 files changed, 31 insertions(+), 14 deletions(-)
> 
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c
> b/src/gallium/drivers/softpipe/sp_tex_sample.c
> index d54e02e..83d9be8 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
> @@ -799,7 +799,8 @@ get_texel_2d_array(const struct
> sp_sampler_variant *samp,
>     const struct pipe_resource *texture = samp->view->texture;
>     unsigned level = addr.bits.level;
>  
> -   assert(layer < texture->array_size);
> +   assert(layer < (int) texture->array_size);
> +   assert(layer >= 0);
>  
>     if (x < 0 || x >= (int) u_minify(texture->width0, level) ||
>         y < 0 || y >= (int) u_minify(texture->height0, level)) {
> @@ -2630,8 +2631,12 @@ sample_get_dims(struct tgsi_sampler
> *tgsi_sampler, int level,
>      }
>  }
>  
> -/* this function is only used for unfiltered texel gets
> -   via the TGSI TXF opcode. */
> +/**
> + * This function is only used for getting unfiltered texels via the
> + * TXF opcode.  The GL spec says that out-of-bounds texel fetches
> + * produce undefined results.  Instead of crashing, lets just clamp
> + * coords to the texture image size.
> + */
>  static void
>  sample_get_texels(struct tgsi_sampler *tgsi_sampler,
>  	   const int v_i[TGSI_QUAD_SIZE],
> @@ -2650,15 +2655,22 @@ sample_get_texels(struct tgsi_sampler
> *tgsi_sampler,
>                          samp->key.bits.swizzle_g !=
>                          PIPE_SWIZZLE_GREEN ||
>                          samp->key.bits.swizzle_b !=
>                          PIPE_SWIZZLE_BLUE ||
>                          samp->key.bits.swizzle_a !=
>                          PIPE_SWIZZLE_ALPHA);
> +   int width, height, depth, layers;
>  
>     addr.value = 0;
>     /* TODO write a better test for LOD */
>     addr.bits.level = lod[0];
>  
> +   width = u_minify(texture->width0, addr.bits.level);
> +   height = u_minify(texture->height0, addr.bits.level);
> +   depth = u_minify(texture->depth0, addr.bits.level);
> +   layers = texture->array_size;
> +
>     switch(texture->target) {
>     case PIPE_TEXTURE_1D:
>        for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -	 tx = get_texel_2d(samp, addr, v_i[j] + offset[0], 0);
> +         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
> +	 tx = get_texel_2d(samp, addr, x, 0);
>  	 for (c = 0; c < 4; c++) {
>  	    rgba[c][j] = tx[c];
>  	 }
> @@ -2666,8 +2678,9 @@ sample_get_texels(struct tgsi_sampler
> *tgsi_sampler,
>        break;
>     case PIPE_TEXTURE_1D_ARRAY:
>        for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -	 tx = get_texel_1d_array(samp, addr, v_i[j] + offset[0],
> -				 v_j[j] + offset[1]);
> +         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
> +         int y = CLAMP(v_j[j] + offset[1], 0, layers - 1);
> +	 tx = get_texel_1d_array(samp, addr, x, y);
>  	 for (c = 0; c < 4; c++) {
>  	    rgba[c][j] = tx[c];
>  	 }
> @@ -2676,8 +2689,9 @@ sample_get_texels(struct tgsi_sampler
> *tgsi_sampler,
>     case PIPE_TEXTURE_2D:
>     case PIPE_TEXTURE_RECT:
>        for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -	 tx = get_texel_2d(samp, addr, v_i[j] + offset[0],
> -			   v_j[j] + offset[1]);
> +         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
> +         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
> +	 tx = get_texel_2d(samp, addr, x, y);
>  	 for (c = 0; c < 4; c++) {
>  	    rgba[c][j] = tx[c];
>  	 }
> @@ -2685,9 +2699,10 @@ sample_get_texels(struct tgsi_sampler
> *tgsi_sampler,
>        break;
>     case PIPE_TEXTURE_2D_ARRAY:
>        for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -	 tx = get_texel_2d_array(samp, addr, v_i[j] + offset[0],
> -				 v_j[j] + offset[1],
> -				 v_k[j] + offset[2]);
> +         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
> +         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
> +         int layer = CLAMP(v_k[j] + offset[2], 0, layers - 1);
> +	 tx = get_texel_2d_array(samp, addr, x, y, layer);
>  	 for (c = 0; c < 4; c++) {
>  	    rgba[c][j] = tx[c];
>  	 }
> @@ -2695,9 +2710,11 @@ sample_get_texels(struct tgsi_sampler
> *tgsi_sampler,
>        break;
>     case PIPE_TEXTURE_3D:
>        for (j = 0; j < TGSI_QUAD_SIZE; j++) {
> -	 tx = get_texel_3d(samp, addr, v_i[j] + offset[0],
> -			   v_j[j] + offset[1],
> -			   v_k[j] + offset[2]);
> +         int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
> +         int y = CLAMP(v_j[j] + offset[1], 0, height - 1);
> +         int z = CLAMP(v_k[j] + offset[2], 0, depth - 1);
> +
> +	 tx = get_texel_3d(samp, addr, x, y, z);
>  	 for (c = 0; c < 4; c++) {
>  	    rgba[c][j] = tx[c];
>  	 }
> --
> 1.7.4.1
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 


More information about the mesa-dev mailing list