[Mesa-dev] [PATCH] gallivm: fix up size queries for dx10 sviewinfo opcode

Jose Fonseca jfonseca at vmware.com
Wed Feb 6 02:26:56 PST 2013


Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

----- Original Message -----
> From: Roland Scheidegger <sroland at vmware.com>
> 
> Need to calculate the number of mip levels (if it would be worthwile
> could
> store it in dynamic state).
> While here, the query code also used chan 2 for the lod value.
> This worked with mesa state tracker but it seems safer to use chan 0.
> Still passes piglit textureSize (with some handwaving), though the
> non-GL
> parts are (largely) untested.
> 
> v2: clarify and expect the sviewinfo opcode to return ints, not
> floats,
> just like the OpenGL textureSize (dx10 supports dst modifiers with
> resinfo).
> Also simplify some code.
> ---
>  src/gallium/auxiliary/draw/draw_llvm_sample.c     |    2 +
>  src/gallium/auxiliary/gallivm/lp_bld_sample.h     |    1 +
>  src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c |   64
>  +++++++++++++-------
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi.h       |    1 +
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c   |   66
>  +++++----------------
>  src/gallium/auxiliary/tgsi/tgsi_info.c            |    4 ++
>  src/gallium/docs/source/tgsi.rst                  |    2 +-
>  src/gallium/drivers/llvmpipe/lp_tex_sample.c      |    2 +
>  8 files changed, 67 insertions(+), 75 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c
> b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> index 03a2592..e51e011 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> @@ -269,6 +269,7 @@ draw_llvm_sampler_soa_emit_size_query(const
> struct lp_build_sampler_soa *base,
>                                        struct gallivm_state *gallivm,
>                                        struct lp_type type,
>                                        unsigned texture_unit,
> +                                      boolean need_nr_mips,
>                                        LLVMValueRef explicit_lod, /*
>                                        optional */
>                                        LLVMValueRef *sizes_out)
>  {
> @@ -281,6 +282,7 @@ draw_llvm_sampler_soa_emit_size_query(const
> struct lp_build_sampler_soa *base,
>                             &sampler->dynamic_state.base,
>                             type,
>                             texture_unit,
> +                           need_nr_mips,
>                             explicit_lod,
>                             sizes_out);
>  }
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> index 77ce008..f502216 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> @@ -487,6 +487,7 @@ lp_build_size_query_soa(struct gallivm_state
> *gallivm,
>                          struct lp_sampler_dynamic_state
>                          *dynamic_state,
>                          struct lp_type int_type,
>                          unsigned texture_unit,
> +                        boolean need_nr_mips,
>                          LLVMValueRef explicit_lod,
>                          LLVMValueRef *sizes_out);
>  
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> index 778400a..c5b48b5 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> @@ -1742,39 +1742,27 @@ lp_build_size_query_soa(struct gallivm_state
> *gallivm,
>                          struct lp_sampler_dynamic_state
>                          *dynamic_state,
>                          struct lp_type int_type,
>                          unsigned texture_unit,
> +                        boolean need_nr_mips,
>                          LLVMValueRef explicit_lod,
>                          LLVMValueRef *sizes_out)
>  {
>     LLVMValueRef lod;
>     LLVMValueRef size;
> +   LLVMValueRef first_level = NULL;
>     int dims, i;
> -   boolean has_array = FALSE;
> +   boolean has_array;
>     struct lp_build_context bld_int_vec;
>  
> +   dims = texture_dims(static_state->target);
> +
>     switch (static_state->target) {
> -   case PIPE_TEXTURE_1D:
> -   case PIPE_BUFFER:
> -      dims = 1;
> -      break;
>     case PIPE_TEXTURE_1D_ARRAY:
> -      dims = 1;
> -      has_array = TRUE;
> -      break;
> -   case PIPE_TEXTURE_2D:
> -   case PIPE_TEXTURE_CUBE:
> -   case PIPE_TEXTURE_RECT:
> -      dims = 2;
> -      break;
> -   case PIPE_TEXTURE_3D:
> -      dims = 3;
> -      break;
>     case PIPE_TEXTURE_2D_ARRAY:
> -      dims = 2;
>        has_array = TRUE;
>        break;
>     default:
> -      assert(0);
> -      return;
> +      has_array = FALSE;
> +      break;
>     }
>  
>     assert(!int_type.floating);
> @@ -1782,7 +1770,6 @@ lp_build_size_query_soa(struct gallivm_state
> *gallivm,
>     lp_build_context_init(&bld_int_vec, gallivm, lp_type_int_vec(32,
>     128));
>  
>     if (explicit_lod) {
> -      LLVMValueRef first_level;
>        lod = LLVMBuildExtractElement(gallivm->builder, explicit_lod,
>        lp_build_const_int32(gallivm, 0), "");
>        first_level = dynamic_state->first_level(dynamic_state,
>        gallivm, texture_unit);
>        lod = lp_build_broadcast_scalar(&bld_int_vec,
> @@ -1792,7 +1779,12 @@ lp_build_size_query_soa(struct gallivm_state
> *gallivm,
>        lod = bld_int_vec.zero;
>     }
>  
> -   size = bld_int_vec.undef;
> +   if (need_nr_mips) {
> +      size = bld_int_vec.zero;
> +   }
> +   else {
> +      size = bld_int_vec.undef;
> +   }
>  
>     size = LLVMBuildInsertElement(gallivm->builder, size,
>                                   dynamic_state->width(dynamic_state,
>                                   gallivm, texture_unit),
> @@ -1811,15 +1803,43 @@ lp_build_size_query_soa(struct gallivm_state
> *gallivm,
>     }
>  
>     size = lp_build_minify(&bld_int_vec, size, lod);
> -
> +
>     if (has_array)
>        size = LLVMBuildInsertElement(gallivm->builder, size,
>                                      dynamic_state->depth(dynamic_state,
>                                      gallivm, texture_unit),
>                                      lp_build_const_int32(gallivm,
>                                      dims), "");
>  
> +   /*
> +    * XXX for out-of-bounds lod, should set size to zero vector here
> +    * (for dx10-style only, i.e. need_nr_mips)
> +    */
> +
>     for (i = 0; i < dims + (has_array ? 1 : 0); i++) {
>        sizes_out[i] = lp_build_extract_broadcast(gallivm,
>        bld_int_vec.type, int_type,
>                                                  size,
>                                                  lp_build_const_int32(gallivm,
>                                                  i));
>     }
> +
> +   /*
> +    * if there's no explicit_lod (buffers, rects) queries requiring
> nr of
> +    * mips would be illegal.
> +    */
> +   if (need_nr_mips && explicit_lod) {
> +      struct lp_build_context bld_int_scalar;
> +      LLVMValueRef num_levels;
> +      lp_build_context_init(&bld_int_scalar, gallivm,
> lp_type_int(32));
> +
> +      if (static_state->level_zero_only) {
> +         num_levels = bld_int_scalar.one;
> +      }
> +      else {
> +         LLVMValueRef last_level;
> +
> +         last_level = dynamic_state->last_level(dynamic_state,
> gallivm, texture_unit);
> +         num_levels = lp_build_sub(&bld_int_scalar, last_level,
> first_level);
> +         num_levels = lp_build_add(&bld_int_scalar, num_levels,
> bld_int_scalar.one);
> +      }
> +      sizes_out[3] = lp_build_broadcast(gallivm,
> lp_build_vec_type(gallivm, int_type),
> +                                        num_levels);
> +   }
>  }
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> index adc63ef..407e968 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
> @@ -189,6 +189,7 @@ struct lp_build_sampler_soa
>                         struct gallivm_state *gallivm,
>                         struct lp_type type,
>                         unsigned unit,
> +                       boolean need_nr_mips,
>                         LLVMValueRef explicit_lod, /* optional */
>                         LLVMValueRef *sizes_out);
>  };
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 5eeaaf4..52a60dd 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -1621,69 +1621,35 @@ emit_txf( struct lp_build_tgsi_soa_context
> *bld,
>  }
>  
>  static void
> -emit_txq( struct lp_build_tgsi_soa_context *bld,
> -          const struct tgsi_full_instruction *inst,
> -          LLVMValueRef *sizes_out)
> +emit_size_query( struct lp_build_tgsi_soa_context *bld,
> +                 const struct tgsi_full_instruction *inst,
> +                 LLVMValueRef *sizes_out,
> +                 boolean is_sviewinfo)
>  {
>     LLVMValueRef explicit_lod;
> -   unsigned num_coords, has_lod;
> +   unsigned has_lod;
>     unsigned i;
>  
>     switch (inst->Texture.Texture) {
> -   case TGSI_TEXTURE_1D:
> -   case TGSI_TEXTURE_SHADOW1D:
> -      num_coords = 1;
> -      has_lod = 1;
> -      break;
> -   case TGSI_TEXTURE_2D:
> -   case TGSI_TEXTURE_SHADOW2D:
> -   case TGSI_TEXTURE_CUBE:
> -   case TGSI_TEXTURE_SHADOWCUBE:
> -   case TGSI_TEXTURE_1D_ARRAY:
> -   case TGSI_TEXTURE_SHADOW1D_ARRAY:
> -      num_coords = 2;
> -      has_lod = 1;
> -      break;
> -   case TGSI_TEXTURE_3D:
> -// case TGSI_TEXTURE_CUBE_ARRAY:
> -// case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
> -   case TGSI_TEXTURE_2D_ARRAY:
> -   case TGSI_TEXTURE_SHADOW2D_ARRAY:
> -      num_coords = 3;
> -      has_lod = 1;
> -      break;
> -
>     case TGSI_TEXTURE_BUFFER:
> -      num_coords = 1;
> -      has_lod = 0;
> -      break;
> -
>     case TGSI_TEXTURE_RECT:
>     case TGSI_TEXTURE_SHADOWRECT:
> -// case TGSI_TEXTURE_2D_MS:
> -      num_coords = 2;
>        has_lod = 0;
>        break;
> -
> -// case TGSI_TEXTURE_2D_MS_ARRAY:
> -//    num_coords = 3;
> -//    has_lod = 0;
> -//    break;
> -
>     default:
> -      assert(0);
> -      return;
> +      has_lod = 1;
> +      break;
>     }
>  
>     if (!bld->sampler) {
>        _debug_printf("warning: found texture query instruction but no
>        sampler generator supplied\n");
> -      for (i = 0; i < num_coords; i++)
> -         sizes_out[i] = bld->bld_base.base.undef;
> +      for (i = 0; i < 4; i++)
> +         sizes_out[i] = bld->bld_base.int_bld.undef;
>        return;
>     }
>  
>     if (has_lod)
> -      explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 2
> );
> +      explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 0
> );
>     else
>        explicit_lod = NULL;
>  
> @@ -1691,6 +1657,7 @@ emit_txq( struct lp_build_tgsi_soa_context
> *bld,
>                                   bld->bld_base.base.gallivm,
>                                   bld->bld_base.int_bld.type,
>                                   inst->Src[1].Register.Index,
> +                                 is_sviewinfo,
>                                   explicit_lod,
>                                   sizes_out);
>  }
> @@ -2078,7 +2045,7 @@ txq_emit(
>  {
>     struct lp_build_tgsi_soa_context * bld =
>     lp_soa_context(bld_base);
>  
> -   emit_txq(bld, emit_data->inst, emit_data->output);
> +   emit_size_query(bld, emit_data->inst, emit_data->output, FALSE);
>  }
>  
>  static void
> @@ -2174,13 +2141,8 @@ sviewinfo_emit(
>     struct lp_build_emit_data * emit_data)
>  {
>     struct lp_build_tgsi_soa_context * bld =
>     lp_soa_context(bld_base);
> -   /*
> -    * FIXME: unlike txq we are required to return number of mipmap
> levels
> -    * too, and the unused channels are defined to be zero.
> -    * Either always do that (and hope llvm can optimize it away?)
> -    * or pass a parameter all the way down.
> -    */
> -   emit_txq(bld, emit_data->inst, emit_data->output);
> +
> +   emit_size_query(bld, emit_data->inst, emit_data->output, TRUE);
>  }
>  
>  static void
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c
> b/src/gallium/auxiliary/tgsi/tgsi_info.c
> index 458bc69..f87cf4c 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_info.c
> +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
> @@ -293,7 +293,10 @@ tgsi_opcode_infer_src_type( uint opcode )
>     case TGSI_OPCODE_USHR:
>     case TGSI_OPCODE_SHL:
>     case TGSI_OPCODE_TXQ:
> +   case TGSI_OPCODE_SVIEWINFO:
>     case TGSI_OPCODE_TXF:
> +   case TGSI_OPCODE_SAMPLE_I:
> +   case TGSI_OPCODE_SAMPLE_I_MS:
>        return TGSI_TYPE_UNSIGNED;
>     case TGSI_OPCODE_MOD:
>     case TGSI_OPCODE_I2F:
> @@ -343,6 +346,7 @@ tgsi_opcode_infer_dst_type( uint opcode )
>     case TGSI_OPCODE_SHL:
>     case TGSI_OPCODE_TXQ:
>     case TGSI_OPCODE_TXQ_LZ:
> +   case TGSI_OPCODE_SVIEWINFO:
>        return TGSI_TYPE_UNSIGNED;
>     case TGSI_OPCODE_F2I:
>     case TGSI_OPCODE_IDIV:
> diff --git a/src/gallium/docs/source/tgsi.rst
> b/src/gallium/docs/source/tgsi.rst
> index 548a9a3..e0a65f7 100644
> --- a/src/gallium/docs/source/tgsi.rst
> +++ b/src/gallium/docs/source/tgsi.rst
> @@ -1435,7 +1435,7 @@ instructions. If in doubt double check Direct3D
> documentation.
>  
>  .. opcode:: SVIEWINFO - query the dimensions of a given sampler
>  view.
>                 dst receives width, height, depth or array size and
> -               number of mipmap levels. The dst can have a writemask
> +               number of mipmap levels as int4. The dst can have a
> writemask
>                 which will specify what info is the caller interested
>                 in.
>                 SVIEWINFO dst, src_mip_level, sampler_view
> diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> index 69ac888..df2a610 100644
> --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c
> @@ -279,6 +279,7 @@ lp_llvm_sampler_soa_emit_size_query(const struct
> lp_build_sampler_soa *base,
>                                      struct gallivm_state *gallivm,
>                                      struct lp_type type,
>                                      unsigned texture_unit,
> +                                    boolean need_nr_mips,
>                                      LLVMValueRef explicit_lod, /*
>                                      optional */
>                                      LLVMValueRef *sizes_out)
>  {
> @@ -291,6 +292,7 @@ lp_llvm_sampler_soa_emit_size_query(const struct
> lp_build_sampler_soa *base,
>                             &sampler->dynamic_state.base,
>                             type,
>                             texture_unit,
> +                           need_nr_mips,
>                             explicit_lod,
>                             sizes_out);
>  }
> --
> 1.7.9.5
> 


More information about the mesa-dev mailing list