[Mesa-dev] [PATCH 1/3] gallivm: handle cube map arrays for texture sampling

Jose Fonseca jfonseca at vmware.com
Thu Aug 28 09:19:47 PDT 2014


On 28/08/14 04:15, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
>
> Pretty easy, just make sure that all paths testing for PIPE_TEXTURE_CUBE
> also recognize PIPE_TEXTURE_CUBE_ARRAY, and add the layer * 6 calculation
> to the calculated face.
> Also handle it for texture size query, looks like OpenGL wants the number
> of cubes, not layers (so need division by 6).
>
> No piglit regressions.
> ---
>   src/gallium/auxiliary/gallivm/lp_bld_sample.c     |  5 +-
>   src/gallium/auxiliary/gallivm/lp_bld_sample.h     | 17 ++++++-
>   src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c | 16 ++----
>   src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 59 ++++++++++++++++-------
>   src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c   |  2 +-
>   5 files changed, 62 insertions(+), 37 deletions(-)
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> index f1bf285..85c0d4e 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> @@ -1313,10 +1313,7 @@ lp_build_mipmap_level_sizes(struct lp_build_sample_context *bld,
>                                                         bld->row_stride_array,
>                                                         ilevel);
>      }
> -   if (dims == 3 ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
> +   if (dims == 3 || has_layer_coord(bld->static_texture_state->target)) {
>         *img_stride_vec = lp_build_get_level_stride_vec(bld,
>                                                         bld->img_stride_array,
>                                                         ilevel);
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> index fd4e053..be05b13 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> @@ -356,9 +356,7 @@ texture_dims(enum pipe_texture_target tex)
>      case PIPE_TEXTURE_2D_ARRAY:
>      case PIPE_TEXTURE_RECT:
>      case PIPE_TEXTURE_CUBE:
> -      return 2;
>      case PIPE_TEXTURE_CUBE_ARRAY:
> -      assert(0);
>         return 2;
>      case PIPE_TEXTURE_3D:
>         return 3;
> @@ -368,6 +366,21 @@ texture_dims(enum pipe_texture_target tex)
>      }
>   }
>
> +static INLINE boolean
> +has_layer_coord(enum pipe_texture_target tex)
> +{
> +   switch (tex) {
> +   case PIPE_TEXTURE_1D_ARRAY:
> +   case PIPE_TEXTURE_2D_ARRAY:
> +   /* cube is not layered but 3rd coord (after cube mapping) behaves the same */
> +   case PIPE_TEXTURE_CUBE:
> +   case PIPE_TEXTURE_CUBE_ARRAY:
> +      return TRUE;
> +   default:
> +      return FALSE;
> +   }
> +}
> +
>
>   boolean
>   lp_sampler_wrap_mode_uses_border_color(unsigned mode,
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
> index 2f02606..394521d 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
> @@ -704,9 +704,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
>            offset = lp_build_add(&bld->int_coord_bld, offset, z_offset);
>         }
>      }
> -   if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
> +   if (has_layer_coord(bld->static_texture_state->target)) {
>         LLVMValueRef z_offset;
>         /* The r coord is the cube face in [0,5] or array layer */
>         z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
> @@ -781,9 +779,7 @@ lp_build_sample_image_nearest_afloat(struct lp_build_sample_context *bld,
>                                               &z_icoord);
>         }
>      }
> -   if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
> +   if (has_layer_coord(bld->static_texture_state->target)) {
>         z_icoord = r;
>      }
>
> @@ -1130,9 +1126,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
>                                      &x_subcoord[0], &x_subcoord[1]);
>
>      /* add potential cube/array/mip offsets now as they are constant per pixel */
> -   if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
> +   if (has_layer_coord(bld->static_texture_state->target)) {
>         LLVMValueRef z_offset;
>         z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
>         /* The r coord is the cube face in [0,5] or array layer */
> @@ -1301,9 +1295,7 @@ lp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld,
>                                     &x_offset1, &x_subcoord[1]);
>
>      /* add potential cube/array/mip offsets now as they are constant per pixel */
> -   if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
> +   if (has_layer_coord(bld->static_texture_state->target)) {
>         LLVMValueRef z_offset;
>         z_offset = lp_build_mul(&bld->int_coord_bld, r, img_stride_vec);
>         /* The r coord is the cube face in [0,5] or array layer */
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> index e29f503..ec9f851 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> @@ -752,9 +752,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
>            lp_build_name(z, "tex.z.wrapped");
>         }
>      }
> -   if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
> -       bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
> +   if (has_layer_coord(bld->static_texture_state->target)) {
>         z = coords[2];
>         lp_build_name(z, "tex.z.layer");
>      }
> @@ -868,7 +866,8 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
>      int chan, texel_index;
>      boolean seamless_cube_filter, accurate_cube_corners;
>
> -   seamless_cube_filter = bld->static_texture_state->target == PIPE_TEXTURE_CUBE &&
> +   seamless_cube_filter = (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> +                           bld->static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) &&
>                             bld->static_sampler_state->seamless_cube_map;
>      accurate_cube_corners = ACCURATE_CUBE_CORNERS && seamless_cube_filter;
>
> @@ -923,9 +922,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
>               lp_build_name(z1, "tex.z1.wrapped");
>            }
>         }
> -      if (bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> -          bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
> -          bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
> +      if (has_layer_coord(bld->static_texture_state->target)) {
>            z00 = z01 = z10 = z11 = z1 = coords[2];  /* cube face or layer */
>            lp_build_name(z00, "tex.z0.layer");
>            lp_build_name(z1, "tex.z1.layer");
> @@ -1644,6 +1641,7 @@ lp_build_sample_mipmap_both(struct lp_build_sample_context *bld,
>   static LLVMValueRef
>   lp_build_layer_coord(struct lp_build_sample_context *bld,
>                        unsigned texture_unit,
> +                     boolean is_cube_array,
>                        LLVMValueRef layer,
>                        LLVMValueRef *out_of_bounds)
>   {
> @@ -1655,6 +1653,7 @@ lp_build_layer_coord(struct lp_build_sample_context *bld,
>
>      if (out_of_bounds) {
>         LLVMValueRef out1, out;
> +      assert(!is_cube_array);
>         num_layers = lp_build_broadcast_scalar(int_coord_bld, num_layers);
>         out = lp_build_cmp(int_coord_bld, PIPE_FUNC_LESS, layer, int_coord_bld->zero);
>         out1 = lp_build_cmp(int_coord_bld, PIPE_FUNC_GEQUAL, layer, num_layers);
> @@ -1663,7 +1662,9 @@ lp_build_layer_coord(struct lp_build_sample_context *bld,
>      }
>      else {
>         LLVMValueRef maxlayer;
> -      maxlayer = lp_build_sub(&bld->int_bld, num_layers, bld->int_bld.one);
> +      LLVMValueRef s = is_cube_array ? lp_build_const_int32(bld->gallivm, 6) :
> +                                       bld->int_bld.one;
> +      maxlayer = lp_build_sub(&bld->int_bld, num_layers, s);
>         maxlayer = lp_build_broadcast_scalar(int_coord_bld, maxlayer);
>         return lp_build_clamp(int_coord_bld, layer, int_coord_bld->zero, maxlayer);
>      }
> @@ -1703,7 +1704,7 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
>       * Choose cube face, recompute texcoords for the chosen face and
>       * compute rho here too (as it requires transform of derivatives).
>       */
> -   if (target == PIPE_TEXTURE_CUBE) {
> +   if (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY) {
>         boolean need_derivs;
>         need_derivs = ((min_filter != mag_filter ||
>                         mip_filter != PIPE_TEX_MIPFILTER_NONE) &&
> @@ -1711,11 +1712,19 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
>                         !explicit_lod);
>         lp_build_cube_lookup(bld, coords, derivs, &cube_rho, &cube_derivs, need_derivs);
>         derivs = &cube_derivs;
> +      if (target == PIPE_TEXTURE_CUBE_ARRAY) {
> +         /* just add effective layer to face coord now */
> +         LLVMValueRef layer = lp_build_iround(&bld->coord_bld, coords[3]);
> +         LLVMValueRef six = lp_build_const_int_vec(bld->gallivm, bld->int_coord_type, 6);
> +         layer = lp_build_mul(&bld->int_coord_bld, layer, six);
> +         layer = lp_build_layer_coord(bld, texture_index, TRUE, layer, NULL);
> +         coords[2] = lp_build_add(&bld->int_coord_bld, coords[2], layer);
> +      }
>      }
>      else if (target == PIPE_TEXTURE_1D_ARRAY ||
>               target == PIPE_TEXTURE_2D_ARRAY) {
>         coords[2] = lp_build_iround(&bld->coord_bld, coords[2]);
> -      coords[2] = lp_build_layer_coord(bld, texture_index, coords[2], NULL);
> +      coords[2] = lp_build_layer_coord(bld, texture_index, FALSE, coords[2], NULL);
>      }
>
>      if (bld->static_sampler_state->compare_mode != PIPE_TEX_COMPARE_NONE) {
> @@ -2223,11 +2232,11 @@ lp_build_fetch_texel(struct lp_build_sample_context *bld,
>      if (target == PIPE_TEXTURE_1D_ARRAY ||
>          target == PIPE_TEXTURE_2D_ARRAY) {
>         if (out_of_bound_ret_zero) {
> -         z = lp_build_layer_coord(bld, texture_unit, z, &out1);
> +         z = lp_build_layer_coord(bld, texture_unit, FALSE, z, &out1);
>            out_of_bounds = lp_build_or(int_coord_bld, out_of_bounds, out1);
>         }
>         else {
> -         z = lp_build_layer_coord(bld, texture_unit, z, NULL);
> +         z = lp_build_layer_coord(bld, texture_unit, FALSE, z, NULL);
>         }
>      }
>
> @@ -2463,7 +2472,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>
>      if ((gallivm_debug & GALLIVM_DEBUG_NO_QUAD_LOD) &&
>          (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX) &&
> -       (static_texture_state->target == PIPE_TEXTURE_CUBE) &&
> +       (static_texture_state->target == PIPE_TEXTURE_CUBE ||
> +        static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) &&
>          (!is_fetch && mip_filter != PIPE_TEX_MIPFILTER_NONE)) {
>         /*
>          * special case for using per-pixel lod even for implicit lod,
> @@ -2601,7 +2611,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>               use_aos &= lp_is_simple_wrap_mode(derived_sampler_state.wrap_r);
>            }
>         }
> -      if (static_texture_state->target == PIPE_TEXTURE_CUBE &&
> +      if ((static_texture_state->target == PIPE_TEXTURE_CUBE ||
> +           static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) &&
>             derived_sampler_state.seamless_cube_map &&
>             (derived_sampler_state.min_img_filter == PIPE_TEX_FILTER_LINEAR ||
>              derived_sampler_state.mag_img_filter == PIPE_TEX_FILTER_LINEAR)) {
> @@ -2695,7 +2706,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
>            bld4.num_mips = bld4.num_lods = 1;
>            if ((gallivm_debug & GALLIVM_DEBUG_NO_QUAD_LOD) &&
>                (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX) &&
> -             (static_texture_state->target == PIPE_TEXTURE_CUBE) &&
> +             (static_texture_state->target == PIPE_TEXTURE_CUBE ||
> +              static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) &&
>                (!is_fetch && mip_filter != PIPE_TEX_MIPFILTER_NONE)) {
>               bld4.num_mips = type4.length;
>               bld4.num_lods = type4.length;
> @@ -2891,6 +2903,7 @@ lp_build_size_query_soa(struct gallivm_state *gallivm,
>      switch (target) {
>      case PIPE_TEXTURE_1D_ARRAY:
>      case PIPE_TEXTURE_2D_ARRAY:
> +   case PIPE_TEXTURE_CUBE_ARRAY:
>         has_array = TRUE;
>         break;
>      default:
> @@ -2932,10 +2945,20 @@ lp_build_size_query_soa(struct gallivm_state *gallivm,
>
>      size = lp_build_minify(&bld_int_vec4, size, lod, TRUE);
>
> -   if (has_array)
> -      size = LLVMBuildInsertElement(gallivm->builder, size,
> -                                    dynamic_state->depth(dynamic_state, gallivm, texture_unit),
> +   if (has_array) {
> +      LLVMValueRef layers = dynamic_state->depth(dynamic_state, gallivm, texture_unit);
> +      if (target == PIPE_TEXTURE_CUBE_ARRAY) {
> +         /*
> +          * It looks like GL wants number of cubes, d3d10.1 has it undefined?
> +          * Could avoid this by passing in number of cubes instead of total
> +          * number of layers (might make things easier elsewhere too).
> +          */
> +         LLVMValueRef six = lp_build_const_int32(gallivm, 6);
> +         layers = LLVMBuildSDiv(gallivm->builder, layers, six, "");
> +      }
> +      size = LLVMBuildInsertElement(gallivm->builder, size, layers,
>                                       lp_build_const_int32(gallivm, dims), "");
> +   }
>
>      /*
>       * d3d10 requires zero for x/y/z values (but not w, i.e. mip levels)
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 93c926a..6731e32 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -2333,7 +2333,7 @@ emit_fetch_texels( struct lp_build_tgsi_soa_context *bld,
>      unsigned unit, target;
>      LLVMValueRef coord_undef = LLVMGetUndef(bld->bld_base.base.int_vec_type);
>      LLVMValueRef explicit_lod = NULL;
> -   LLVMValueRef coords[3];
> +   LLVMValueRef coords[5];


Is this really necessary? AFAICT, only coord[0..2] is ever writte.


Otherwise series looks good AFAICT.  (Though I only skimmed through 
softpipe.)

Jose

>      LLVMValueRef offsets[3] = { NULL };
>      enum lp_sampler_lod_property lod_property = LP_SAMPLER_LOD_SCALAR;
>      unsigned dims, i;
>



More information about the mesa-dev mailing list