gallivm: use texture target from shader instead of static state for size query
authorRoland Scheidegger <sroland@vmware.com>
Thu, 8 Aug 2013 01:42:46 +0000 (03:42 +0200)
committerRoland Scheidegger <sroland@vmware.com>
Fri, 9 Aug 2013 18:49:18 +0000 (20:49 +0200)
d3d10 has no notion of distinct array resources neither at the resource nor
sampler view level. However, shader dcl of resources certainly has, and
d3d10 expects resinfo to return the values according to that - in particular
a resource might have been a 1d texture with some array layers, then the
sampler view might have only used 1 layer so it can be accessed both as 1d
or 1d array texture (I think - the former definitely works). resinfo of a
resource decleared as array needs to return number of array layers but
non-array resource needs to return 0 (and not 1). Hence fix this by passing
the target from the shader decl to emit_size_query and use that (in case of
OpenGL the target will come from the instruction itself).
Could probably do the same for actual sampling, though it may not matter there
(as the bogus components will essentially get clamped away), possibly could
wreak havoc though if it REALLY doesn't match (which is of course an error
but still).

Reviewed-by: Zack Rusin <zackr@vmware.com>
src/gallium/auxiliary/draw/draw_llvm_sample.c
src/gallium/auxiliary/gallivm/lp_bld_sample.h
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/drivers/llvmpipe/lp_tex_sample.c

index 3016d7c49208f2fca8997ab1fe0212713dff20aa..f10cba3279c590e30dd5c2baf3555807a3810662 100644 (file)
@@ -270,6 +270,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,
+                                      unsigned target,
                                       boolean need_nr_mips,
                                       boolean scalar_lod,
                                       LLVMValueRef explicit_lod, /* optional */
@@ -284,6 +285,7 @@ draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
                            &sampler->dynamic_state.base,
                            type,
                            texture_unit,
+                           target,
                            need_nr_mips,
                            scalar_lod,
                            explicit_lod,
index dff8be22f6e646bcb59e3be783ba9e377ee30996..db3ea1df59f49f7a299b2457acff5925634bfeb2 100644 (file)
@@ -497,6 +497,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,
+                        unsigned target,
                         boolean need_nr_mips,
                         boolean scalar_lod,
                         LLVMValueRef explicit_lod,
index b0bb58bdf0b5aa184a6b6c70c0c18f0c033ef0f4..e403ac83c6a5c0cd186832f477da1a53a11c9cb6 100644 (file)
@@ -1943,6 +1943,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,
+                        unsigned target,
                         boolean need_nr_mips,
                         boolean scalar_lod,
                         LLVMValueRef explicit_lod,
@@ -1955,9 +1956,36 @@ lp_build_size_query_soa(struct gallivm_state *gallivm,
    unsigned num_lods = 1;
    struct lp_build_context bld_int_vec;
 
-   dims = texture_dims(static_state->target);
+   /*
+    * Do some sanity verification about bound texture and shader dcl target.
+    * Not entirely sure what's possible but assume array/non-array
+    * always compatible (probably not ok for OpenGL but d3d10 has no
+    * distinction of arrays at the resource level).
+    * Everything else looks bogus (though not entirely sure about rect/2d).
+    * Currently disabled because it causes assertion failures if there's
+    * nothing bound (or rather a dummy texture, not that this case would
+    * return the right values).
+    */
+   if (0 && static_state->target != target) {
+      if (static_state->target == PIPE_TEXTURE_1D)
+         assert(target == PIPE_TEXTURE_1D_ARRAY);
+      else if (static_state->target == PIPE_TEXTURE_1D_ARRAY)
+         assert(target == PIPE_TEXTURE_1D);
+      else if (static_state->target == PIPE_TEXTURE_2D)
+         assert(target == PIPE_TEXTURE_2D_ARRAY);
+      else if (static_state->target == PIPE_TEXTURE_2D_ARRAY)
+         assert(target == PIPE_TEXTURE_2D);
+      else if (static_state->target == PIPE_TEXTURE_CUBE)
+         assert(target == PIPE_TEXTURE_CUBE_ARRAY);
+      else if (static_state->target == PIPE_TEXTURE_CUBE_ARRAY)
+         assert(target == PIPE_TEXTURE_CUBE);
+      else
+         assert(0);
+   }
+
+   dims = texture_dims(target);
 
-   switch (static_state->target) {
+   switch (target) {
    case PIPE_TEXTURE_1D_ARRAY:
    case PIPE_TEXTURE_2D_ARRAY:
       has_array = TRUE;
index aec019a1a6b008aa1a3cfbd04522de8174bd0cf7..9d27f5fa94d91834c69c16dc3945ff9af3035716 100644 (file)
@@ -192,6 +192,7 @@ struct lp_build_sampler_soa
                        struct gallivm_state *gallivm,
                        struct lp_type type,
                        unsigned unit,
+                       unsigned target,
                        boolean need_nr_mips,
                        boolean scalar_lod,
                        LLVMValueRef explicit_lod, /* optional */
index 02d804abf52b71b60f5b1b231b017a02ca690b59..affe0592a44e0d2c74ff398e60126286e6f62070 100644 (file)
@@ -1564,6 +1564,43 @@ emit_store(
    }
 }
 
+static unsigned
+tgsi_to_pipe_tex_target(unsigned tgsi_target)
+{
+   switch (tgsi_target) {
+   case TGSI_TEXTURE_BUFFER:
+      return PIPE_BUFFER;
+   case TGSI_TEXTURE_1D:
+   case TGSI_TEXTURE_SHADOW1D:
+      return PIPE_TEXTURE_1D;
+   case TGSI_TEXTURE_2D:
+   case TGSI_TEXTURE_SHADOW2D:
+   case TGSI_TEXTURE_2D_MSAA:
+      return PIPE_TEXTURE_2D;
+   case TGSI_TEXTURE_3D:
+      return PIPE_TEXTURE_3D;
+   case TGSI_TEXTURE_CUBE:
+   case TGSI_TEXTURE_SHADOWCUBE:
+      return PIPE_TEXTURE_CUBE;
+   case TGSI_TEXTURE_RECT:
+   case TGSI_TEXTURE_SHADOWRECT:
+      return PIPE_TEXTURE_RECT;
+   case TGSI_TEXTURE_1D_ARRAY:
+   case TGSI_TEXTURE_SHADOW1D_ARRAY:
+      return PIPE_TEXTURE_1D_ARRAY;
+   case TGSI_TEXTURE_2D_ARRAY:
+   case TGSI_TEXTURE_SHADOW2D_ARRAY:
+   case TGSI_TEXTURE_2D_ARRAY_MSAA:
+      return PIPE_TEXTURE_2D_ARRAY;
+   case TGSI_TEXTURE_CUBE_ARRAY:
+   case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
+      return PIPE_TEXTURE_CUBE_ARRAY;
+   default:
+      assert(0);
+      return PIPE_BUFFER;
+   }
+}
+
 /**
  * High-level instruction translators.
  */
@@ -1994,7 +2031,7 @@ emit_size_query( struct lp_build_tgsi_soa_context *bld,
    unsigned has_lod;
    unsigned i;
    unsigned unit = inst->Src[1].Register.Index;
-   unsigned target;
+   unsigned target, pipe_target;
 
    if (is_sviewinfo) {
       target = bld->sv[unit].Resource;
@@ -2025,13 +2062,15 @@ emit_size_query( struct lp_build_tgsi_soa_context *bld,
    else
       explicit_lod = NULL;
 
+   pipe_target = tgsi_to_pipe_tex_target(target);
+
    /* TODO: use scalar lod if explicit_lod is broadcasted scalar */
    scalar_lod = bld->bld_base.info->processor == TGSI_PROCESSOR_FRAGMENT;
 
    bld->sampler->emit_size_query(bld->sampler,
                                  bld->bld_base.base.gallivm,
                                  bld->bld_base.int_bld.type,
-                                 unit,
+                                 unit, pipe_target,
                                  is_sviewinfo,
                                  scalar_lod,
                                  explicit_lod,
index 2aec6ea86979fdcfb0bf0aa010dccf56b54a1974..5402de407d567cfbf18bc6d93a3d2f82eef79829 100644 (file)
@@ -280,6 +280,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,
+                                    unsigned target,
                                     boolean need_nr_mips,
                                     boolean scalar_lod,
                                     LLVMValueRef explicit_lod, /* optional */
@@ -294,6 +295,7 @@ lp_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
                            &sampler->dynamic_state.base,
                            type,
                            texture_unit,
+                           target,
                            need_nr_mips,
                            scalar_lod,
                            explicit_lod,