Module: Mesa
Branch: master
Commit: 614982d320985c04e247293b54b66d7df5c19004
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=614982d320985c04e247293b54b66d7df5c19004

Author: Roland Scheidegger <[email protected]>
Date:   Tue Feb  5 13:37:57 2013 -0800

gallivm: fix up size queries for dx10 sviewinfo opcode

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.

Reviewed-by: Jose Fonseca <[email protected]>

---

 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 837394f..3446a8f 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 94b6f60..f8a3cb6 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 5f03f32..31b6796 100644
--- a/src/gallium/docs/source/tgsi.rst
+++ b/src/gallium/docs/source/tgsi.rst
@@ -1444,7 +1444,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);
 }

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to