On 01/24/2013 07:48 PM, srol...@vmware.com wrote:
From: Roland Scheidegger<srol...@vmware.com>

Split the sampler interface to use separate sampler and texture (sampler_view)
state. This is needed to support dx10-style sampling instructions.
This is not quite complete since both draw/llvmpipe don't really track
textures/samplers independently yet, as well as the gallivm code not quite
using the right sampler or texture index respectively (but it should work
for the sampling codes used by opengl).
We are however losing some optimizations in the process, apply_max_lod will
no longer work, and we potentially could end up with more (unnecessary)
recompiles (if switching textures with/without mipmaps only so it shouldn't
be too bad).

v2: don't use different callback structs for sampler/sampler view functions
(which just complicates things), fix up sampling code to actually use the
right texture or sampler index, and similar for llvmpipe/draw actually
distinguish between samplers and sampler views.


Looks good AFAICT.  Just a few minor comments (about comments) below.

Reviewed-by: Brian Paul <bri...@vmware.com>

Nice work!


---
  src/gallium/auxiliary/draw/draw_llvm.c            |  129 +++++++++-----
  src/gallium/auxiliary/draw/draw_llvm.h            |   66 ++++++--
  src/gallium/auxiliary/draw/draw_llvm_sample.c     |   88 ++++++++--
  src/gallium/auxiliary/draw/draw_private.h         |    2 +-
  src/gallium/auxiliary/gallivm/lp_bld_sample.c     |  108 +++++++-----
  src/gallium/auxiliary/gallivm/lp_bld_sample.h     |   66 ++++++--
  src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c |  104 ++++++------
  src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c |  187 ++++++++++++---------
  src/gallium/auxiliary/gallivm/lp_bld_tgsi.h       |    3 +-
  src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c   |    6 +-
  src/gallium/drivers/llvmpipe/lp_jit.c             |   54 ++++--
  src/gallium/drivers/llvmpipe/lp_jit.h             |   24 ++-
  src/gallium/drivers/llvmpipe/lp_setup.c           |   12 +-
  src/gallium/drivers/llvmpipe/lp_state_fs.c        |   84 ++++++---
  src/gallium/drivers/llvmpipe/lp_state_fs.h        |   17 +-
  src/gallium/drivers/llvmpipe/lp_state_setup.c     |   16 +-
  src/gallium/drivers/llvmpipe/lp_tex_sample.c      |  102 ++++++++---
  17 files changed, 711 insertions(+), 357 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_llvm.c 
b/src/gallium/auxiliary/draw/draw_llvm.c
index a3a3bbf..9e5ff1c 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -85,11 +85,6 @@ create_jit_texture_type(struct gallivm_state *gallivm, const 
char *struct_name)
     elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] =
     elem_types[DRAW_JIT_TEXTURE_MIP_OFFSETS] =
        LLVMArrayType(int32_type, PIPE_MAX_TEXTURE_LEVELS);
-   elem_types[DRAW_JIT_TEXTURE_MIN_LOD] =
-   elem_types[DRAW_JIT_TEXTURE_MAX_LOD] =
-   elem_types[DRAW_JIT_TEXTURE_LOD_BIAS] = 
LLVMFloatTypeInContext(gallivm->context);
-   elem_types[DRAW_JIT_TEXTURE_BORDER_COLOR] =
-      LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);

     texture_type = LLVMStructTypeInContext(gallivm->context, elem_types,
                                            Elements(elem_types), 0);
@@ -130,18 +125,6 @@ create_jit_texture_type(struct gallivm_state *gallivm, 
const char *struct_name)
     LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, mip_offsets,
                            target, texture_type,
                            DRAW_JIT_TEXTURE_MIP_OFFSETS);
-   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, min_lod,
-                          target, texture_type,
-                          DRAW_JIT_TEXTURE_MIN_LOD);
-   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, max_lod,
-                          target, texture_type,
-                          DRAW_JIT_TEXTURE_MAX_LOD);
-   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, lod_bias,
-                          target, texture_type,
-                          DRAW_JIT_TEXTURE_LOD_BIAS);
-   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, border_color,
-                          target, texture_type,
-                          DRAW_JIT_TEXTURE_BORDER_COLOR);

     LP_CHECK_STRUCT_SIZE(struct draw_jit_texture, target, texture_type);

@@ -150,15 +133,63 @@ create_jit_texture_type(struct gallivm_state *gallivm, 
const char *struct_name)


  /**
+ * Create LLVM type for struct draw_jit_sampler
+ */
+static LLVMTypeRef
+create_jit_sampler_type(struct gallivm_state *gallivm, const char *struct_name)
+{
+   LLVMTargetDataRef target = gallivm->target;
+   LLVMTypeRef sampler_type;
+   LLVMTypeRef elem_types[DRAW_JIT_SAMPLER_NUM_FIELDS];
+
+   elem_types[DRAW_JIT_SAMPLER_MIN_LOD] =
+   elem_types[DRAW_JIT_SAMPLER_MAX_LOD] =
+   elem_types[DRAW_JIT_SAMPLER_LOD_BIAS] = 
LLVMFloatTypeInContext(gallivm->context);
+   elem_types[DRAW_JIT_SAMPLER_BORDER_COLOR] =
+      LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);
+
+   sampler_type = LLVMStructTypeInContext(gallivm->context, elem_types,
+                                          Elements(elem_types), 0);
+
+#if HAVE_LLVM<  0x0300
+   LLVMAddTypeName(gallivm->module, struct_name, sampler_type);
+
+   /* Make sure the target's struct layout cache doesn't return
+    * stale/invalid data.
+    */
+   LLVMInvalidateStructLayout(gallivm->target, sampler_type);
+#endif
+
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, min_lod,
+                          target, sampler_type,
+                          DRAW_JIT_SAMPLER_MIN_LOD);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, max_lod,
+                          target, sampler_type,
+                          DRAW_JIT_SAMPLER_MAX_LOD);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, lod_bias,
+                          target, sampler_type,
+                          DRAW_JIT_SAMPLER_LOD_BIAS);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, border_color,
+                          target, sampler_type,
+                          DRAW_JIT_SAMPLER_BORDER_COLOR);
+
+   LP_CHECK_STRUCT_SIZE(struct draw_jit_sampler, target, sampler_type);
+
+   return sampler_type;
+}
+
+
+/**
   * Create LLVM type for struct draw_jit_texture
   */
  static LLVMTypeRef
  create_jit_context_type(struct gallivm_state *gallivm,

While you're here, can you fix the comment above (looks like a copy&paste error).


-                        LLVMTypeRef texture_type, const char *struct_name)
+                        LLVMTypeRef texture_type, LLVMTypeRef sampler_type,
+                        const char *struct_name)
  {
     LLVMTargetDataRef target = gallivm->target;
     LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context);
-   LLVMTypeRef elem_types[5];
+   LLVMTypeRef elem_types[6];
     LLVMTypeRef context_type;

     elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* 
vs_constants */
@@ -168,7 +199,9 @@ create_jit_context_type(struct gallivm_state *gallivm,
                                                   DRAW_TOTAL_CLIP_PLANES), 0);
     elem_types[3] = LLVMPointerType(float_type, 0); /* viewport */
     elem_types[4] = LLVMArrayType(texture_type,
-                                 PIPE_MAX_SAMPLERS); /* textures */
+                                 PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures */
+   elem_types[5] = LLVMArrayType(sampler_type,
+                                 PIPE_MAX_SAMPLERS); /* samplers */
     context_type = LLVMStructTypeInContext(gallivm->context, elem_types,
                                            Elements(elem_types), 0);
  #if HAVE_LLVM<  0x0300
@@ -183,9 +216,14 @@ create_jit_context_type(struct gallivm_state *gallivm,
                            target, context_type, 1);
     LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, planes,
                            target, context_type, 2);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, viewport,
+                          target, context_type, 3);
     LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures,
                            target, context_type,
                            DRAW_JIT_CTX_TEXTURES);
+   LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, samplers,
+                          target, context_type,
+                          DRAW_JIT_CTX_SAMPLERS);
     LP_CHECK_STRUCT_SIZE(struct draw_jit_context,
                          target, context_type);

@@ -291,11 +329,13 @@ static void
  create_jit_types(struct draw_llvm_variant *variant)
  {
     struct gallivm_state *gallivm = variant->gallivm;
-   LLVMTypeRef texture_type, context_type, buffer_type, vb_type;
+   LLVMTypeRef texture_type, sampler_type, context_type, buffer_type, vb_type;

     texture_type = create_jit_texture_type(gallivm, "texture");
+   sampler_type = create_jit_sampler_type(gallivm, "sampler");

-   context_type = create_jit_context_type(gallivm, texture_type, 
"draw_jit_context");
+   context_type = create_jit_context_type(gallivm, texture_type, sampler_type,
+                                          "draw_jit_context");
     variant->context_ptr_type = LLVMPointerType(context_type, 0);

     buffer_type = LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 8), 
0);
@@ -1182,8 +1222,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct 
draw_llvm_variant *variant,

     /* code generated texture sampling */
     sampler = draw_llvm_sampler_soa_create(
-      draw_llvm_variant_key_samplers(&variant->key),
-      context_ptr);
+                draw_llvm_variant_key_samplers(&variant->key),
+                context_ptr);

     if (elts) {
        start = zero;
@@ -1319,7 +1359,7 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char 
*store)
  {
     unsigned i;
     struct draw_llvm_variant_key *key;
-   struct lp_sampler_static_state *sampler;
+   struct draw_sampler_static_state *draw_sampler;

     key = (struct draw_llvm_variant_key *)store;

@@ -1345,19 +1385,29 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char 
*store)
      * sampler array.
      */
     key->nr_samplers = 
llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER] + 1;
+   if (llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] != 
-1) {
+      key->nr_sampler_views =
+         llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] + 
1;
+   }
+   else {
+      key->nr_sampler_views = key->nr_samplers;
+   }

-   sampler = draw_llvm_variant_key_samplers(key);
+   draw_sampler = draw_llvm_variant_key_samplers(key);

     memcpy(key->vertex_element,
            llvm->draw->pt.vertex_element,
            sizeof(struct pipe_vertex_element) * key->nr_vertex_elements);
-
-   memset(sampler, 0, key->nr_samplers * sizeof *sampler);
+
+   memset(draw_sampler, 0, MAX2(key->nr_samplers, key->nr_sampler_views) * 
sizeof *draw_sampler);

     for (i = 0 ; i<  key->nr_samplers; i++) {
-      lp_sampler_static_state(&sampler[i],
-                             llvm->draw->sampler_views[PIPE_SHADER_VERTEX][i],
-                             llvm->draw->samplers[PIPE_SHADER_VERTEX][i]);
+      lp_sampler_static_sampler_state(&draw_sampler[i].sampler_state,
+                                      
llvm->draw->samplers[PIPE_SHADER_VERTEX][i]);
+   }
+   for (i = 0 ; i<  key->nr_sampler_views; i++) {
+      lp_sampler_static_texture_state(&draw_sampler[i].texture_state,
+                                      
llvm->draw->sampler_views[PIPE_SHADER_VERTEX][i]);
     }

     return key;
@@ -1368,7 +1418,7 @@ void
  draw_llvm_dump_variant_key(struct draw_llvm_variant_key *key)
  {
     unsigned i;
-   struct lp_sampler_static_state *sampler = 
draw_llvm_variant_key_samplers(key);
+   struct draw_sampler_static_state *sampler = 
draw_llvm_variant_key_samplers(key);

     debug_printf("clamp_vertex_color = %u\n", key->clamp_vertex_color);
     debug_printf("clip_xy = %u\n", key->clip_xy);
@@ -1386,8 +1436,8 @@ draw_llvm_dump_variant_key(struct draw_llvm_variant_key 
*key)
        debug_printf("vertex_element[%i].src_format = %s\n", i, 
util_format_name(key->vertex_element[i].src_format));
     }

-   for (i = 0 ; i<  key->nr_samplers; i++) {
-      debug_printf("sampler[%i].src_format = %s\n", i, 
util_format_name(sampler[i].format));
+   for (i = 0 ; i<  key->nr_sampler_views; i++) {
+      debug_printf("sampler[%i].src_format = %s\n", i, 
util_format_name(sampler[i].texture_state.format));
     }
  }

@@ -1428,17 +1478,16 @@ void
  draw_llvm_set_sampler_state(struct draw_context *draw)
  {
     unsigned i;
-
     for (i = 0; i<  draw->num_samplers[PIPE_SHADER_VERTEX]; i++) {
-      struct draw_jit_texture *jit_tex =&draw->llvm->jit_context.textures[i];
+      struct draw_jit_sampler *jit_sam =&draw->llvm->jit_context.samplers[i];

        if (draw->samplers[i]) {
           const struct pipe_sampler_state *s
              = draw->samplers[PIPE_SHADER_VERTEX][i];
-         jit_tex->min_lod = s->min_lod;
-         jit_tex->max_lod = s->max_lod;
-         jit_tex->lod_bias = s->lod_bias;
-         COPY_4V(jit_tex->border_color, s->border_color.f);
+         jit_sam->min_lod = s->min_lod;
+         jit_sam->max_lod = s->max_lod;
+         jit_sam->lod_bias = s->lod_bias;
+         COPY_4V(jit_sam->border_color, s->border_color.f);
        }
     }
  }
diff --git a/src/gallium/auxiliary/draw/draw_llvm.h 
b/src/gallium/auxiliary/draw/draw_llvm.h
index 892973c..a664857 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.h
+++ b/src/gallium/auxiliary/draw/draw_llvm.h
@@ -52,12 +52,30 @@ struct draw_jit_texture
     uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
     uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
     uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
+};
+
+
+struct draw_sampler_static_state
+{
+   /*
+    * These attributes are effectively interleaved for more sane key handling.
+    * However, there might be lots of null space if the amount of samplers and
+    * textures isn't the same.
+    */
+   struct lp_static_sampler_state sampler_state;
+   struct lp_static_texture_state texture_state;
+};
+
+
+struct draw_jit_sampler
+{
     float min_lod;
     float max_lod;
     float lod_bias;
     float border_color[4];
  };

+
  enum {
     DRAW_JIT_TEXTURE_WIDTH = 0,
     DRAW_JIT_TEXTURE_HEIGHT,
@@ -68,13 +86,19 @@ enum {
     DRAW_JIT_TEXTURE_ROW_STRIDE,
     DRAW_JIT_TEXTURE_IMG_STRIDE,
     DRAW_JIT_TEXTURE_MIP_OFFSETS,
-   DRAW_JIT_TEXTURE_MIN_LOD,
-   DRAW_JIT_TEXTURE_MAX_LOD,
-   DRAW_JIT_TEXTURE_LOD_BIAS,
-   DRAW_JIT_TEXTURE_BORDER_COLOR,
     DRAW_JIT_TEXTURE_NUM_FIELDS  /* number of fields above */
  };

+
+enum {
+   DRAW_JIT_SAMPLER_MIN_LOD,
+   DRAW_JIT_SAMPLER_MAX_LOD,
+   DRAW_JIT_SAMPLER_LOD_BIAS,
+   DRAW_JIT_SAMPLER_BORDER_COLOR,
+   DRAW_JIT_SAMPLER_NUM_FIELDS  /* number of fields above */
+};
+
+
  enum {
     DRAW_JIT_VERTEX_VERTEX_ID = 0,
     DRAW_JIT_VERTEX_CLIP,
@@ -82,6 +106,9 @@ enum {
     DRAW_JIT_VERTEX_DATA
  };

+#define DRAW_JIT_CTX_TEXTURES 4
+#define DRAW_JIT_CTX_SAMPLERS 5
+
  /**
   * This structure is passed directly to the generated vertex shader.
   *
@@ -100,7 +127,8 @@ struct draw_jit_context
     float (*planes) [DRAW_TOTAL_CLIP_PLANES][4];
     float *viewport;

-   struct draw_jit_texture textures[PIPE_MAX_SAMPLERS];
+   struct draw_jit_texture textures[PIPE_MAX_SHADER_SAMPLER_VIEWS];
+   struct draw_jit_sampler samplers[PIPE_MAX_SAMPLERS];
  };


@@ -117,10 +145,14 @@ struct draw_jit_context
     lp_build_struct_get(_gallivm, _ptr, 3, "viewport")

  #define DRAW_JIT_CTX_TEXTURES 4
+#define DRAW_JIT_CTX_SAMPLERS 5

  #define draw_jit_context_textures(_gallivm, _ptr) \
     lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_CTX_TEXTURES, "textures")

+#define draw_jit_context_samplers(_gallivm, _ptr) \
+   lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_CTX_SAMPLERS, "samplers")
+
  #define draw_jit_header_id(_gallivm, _ptr)              \
     lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_VERTEX_ID, "id")

@@ -166,6 +198,7 @@ struct draw_llvm_variant_key
  {
     unsigned nr_vertex_elements:8;
     unsigned nr_samplers:8;
+   unsigned nr_sampler_views:8;
     unsigned clamp_vertex_color:1;
     unsigned clip_xy:1;
     unsigned clip_z:1;
@@ -174,7 +207,7 @@ struct draw_llvm_variant_key
     unsigned bypass_viewport:1;
     unsigned need_edgeflags:1;
     unsigned ucp_enable:PIPE_MAX_CLIP_PLANES;
-   unsigned pad:9-PIPE_MAX_CLIP_PLANES;
+   unsigned pad:33-PIPE_MAX_CLIP_PLANES;

     /* Variable number of vertex elements:
      */
@@ -182,34 +215,33 @@ struct draw_llvm_variant_key

     /* Followed by variable number of samplers:
      */
-/*   struct lp_sampler_static_state sampler; */
+/*   struct draw_sampler_static_state sampler; */
  };

  #define DRAW_LLVM_MAX_VARIANT_KEY_SIZE \
     (sizeof(struct draw_llvm_variant_key) +    \
-    PIPE_MAX_SAMPLERS * sizeof(struct lp_sampler_static_state) +       \
+    PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct draw_sampler_static_state) + 
\
      (PIPE_MAX_ATTRIBS-1) * sizeof(struct pipe_vertex_element))


  static INLINE size_t
  draw_llvm_variant_key_size(unsigned nr_vertex_elements,
-                          unsigned nr_samplers)
+                           unsigned nr_samplers)
  {
     return (sizeof(struct draw_llvm_variant_key) +
-          nr_samplers * sizeof(struct lp_sampler_static_state) +
-          (nr_vertex_elements - 1) * sizeof(struct pipe_vertex_element));
+           nr_samplers * sizeof(struct draw_sampler_static_state) +
+           (nr_vertex_elements - 1) * sizeof(struct pipe_vertex_element));
  }


-static INLINE struct lp_sampler_static_state *
+static INLINE struct draw_sampler_static_state *
  draw_llvm_variant_key_samplers(struct draw_llvm_variant_key *key)
  {
-   return (struct lp_sampler_static_state *)
+   return (struct draw_sampler_static_state *)
        &key->vertex_element[key->nr_vertex_elements];
  }


-
  struct draw_llvm_variant_list_item
  {
     struct draw_llvm_variant *base;
@@ -275,8 +307,8 @@ draw_llvm_destroy(struct draw_llvm *llvm);

  struct draw_llvm_variant *
  draw_llvm_create_variant(struct draw_llvm *llvm,
-                        unsigned num_vertex_header_attribs,
-                        const struct draw_llvm_variant_key *key);
+                         unsigned num_vertex_header_attribs,
+                         const struct draw_llvm_variant_key *key);

  void
  draw_llvm_destroy_variant(struct draw_llvm_variant *variant);
@@ -288,7 +320,7 @@ void
  draw_llvm_dump_variant_key(struct draw_llvm_variant_key *key);

  struct lp_build_sampler_soa *
-draw_llvm_sampler_soa_create(const struct lp_sampler_static_state 
*static_state,
+draw_llvm_sampler_soa_create(const struct draw_sampler_static_state 
*static_state,
                               LLVMValueRef context_ptr);

  void
diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c 
b/src/gallium/auxiliary/draw/draw_llvm_sample.c
index 67d4e93..593d641 100644
--- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
+++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
@@ -58,7 +58,7 @@ struct draw_llvm_sampler_dynamic_state
  {
     struct lp_sampler_dynamic_state base;

-   const struct lp_sampler_static_state *static_state;
+   const struct draw_sampler_static_state *static_state;

     LLVMValueRef context_ptr;
  };
@@ -98,7 +98,7 @@ draw_llvm_texture_member(const struct 
lp_sampler_dynamic_state *base,
     LLVMValueRef ptr;
     LLVMValueRef res;

-   debug_assert(unit<  PIPE_MAX_SAMPLERS);
+   debug_assert(unit<  PIPE_MAX_SHADER_SAMPLER_VIEWS);

     /* context[0] */
     indices[0] = lp_build_const_int32(gallivm, 0);
@@ -122,6 +122,45 @@ draw_llvm_texture_member(const struct 
lp_sampler_dynamic_state *base,
  }


+static LLVMValueRef
+draw_llvm_sampler_member(const struct lp_sampler_dynamic_state *base,

Could you put a comment on that function to explain what it does?


+                         struct gallivm_state *gallivm,
+                         unsigned unit,
+                         unsigned member_index,
+                         const char *member_name,
+                         boolean emit_load)
+{
+   LLVMBuilderRef builder = gallivm->builder;
+   struct draw_llvm_sampler_dynamic_state *state =
+      (struct draw_llvm_sampler_dynamic_state *)base;
+   LLVMValueRef indices[4];
+   LLVMValueRef ptr;
+   LLVMValueRef res;
+
+   debug_assert(unit<  PIPE_MAX_SAMPLERS);
+
+   /* context[0] */
+   indices[0] = lp_build_const_int32(gallivm, 0);
+   /* context[0].samplers */
+   indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_SAMPLERS);
+   /* context[0].samplers[unit] */
+   indices[2] = lp_build_const_int32(gallivm, unit);
+   /* context[0].samplers[unit].member */
+   indices[3] = lp_build_const_int32(gallivm, member_index);
+
+   ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), 
"");
+
+   if (emit_load)
+      res = LLVMBuildLoad(builder, ptr, "");
+   else
+      res = ptr;
+
+   lp_build_name(res, "context.sampler%u.%s", unit, member_name);
+
+   return res;
+}
+
+
  /**
   * Helper macro to instantiate the functions that generate the code to
   * fetch the members of lp_jit_texture to fulfill the sampler code
@@ -150,10 +189,23 @@ DRAW_LLVM_TEXTURE_MEMBER(base_ptr,   
DRAW_JIT_TEXTURE_BASE, TRUE)
  DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE)
  DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE)
  DRAW_LLVM_TEXTURE_MEMBER(mip_offsets, DRAW_JIT_TEXTURE_MIP_OFFSETS, FALSE)
-DRAW_LLVM_TEXTURE_MEMBER(min_lod,    DRAW_JIT_TEXTURE_MIN_LOD, TRUE)
-DRAW_LLVM_TEXTURE_MEMBER(max_lod,    DRAW_JIT_TEXTURE_MAX_LOD, TRUE)
-DRAW_LLVM_TEXTURE_MEMBER(lod_bias,   DRAW_JIT_TEXTURE_LOD_BIAS, TRUE)
-DRAW_LLVM_TEXTURE_MEMBER(border_color, DRAW_JIT_TEXTURE_BORDER_COLOR, FALSE)
+
+
+#define DRAW_LLVM_SAMPLER_MEMBER(_name, _index, _emit_load)  \
+   static LLVMValueRef \
+   draw_llvm_sampler_##_name( const struct lp_sampler_dynamic_state *base, \
+                              struct gallivm_state *gallivm,               \
+                              unsigned unit)                            \
+   { \
+      return draw_llvm_sampler_member(base, gallivm, unit, _index, #_name, 
_emit_load ); \
+   }
+
+
+DRAW_LLVM_SAMPLER_MEMBER(min_lod,    DRAW_JIT_SAMPLER_MIN_LOD, TRUE)
+DRAW_LLVM_SAMPLER_MEMBER(max_lod,    DRAW_JIT_SAMPLER_MAX_LOD, TRUE)
+DRAW_LLVM_SAMPLER_MEMBER(lod_bias,   DRAW_JIT_SAMPLER_LOD_BIAS, TRUE)
+DRAW_LLVM_SAMPLER_MEMBER(border_color, DRAW_JIT_SAMPLER_BORDER_COLOR, FALSE)
+


  static void
@@ -172,7 +224,8 @@ draw_llvm_sampler_soa_emit_fetch_texel(const struct 
lp_build_sampler_soa *base,
                                         struct gallivm_state *gallivm,
                                         struct lp_type type,
                                         boolean is_fetch,
-                                       unsigned unit,
+                                       unsigned texture_index,
+                                       unsigned sampler_index,
                                         const LLVMValueRef *coords,
                                         const LLVMValueRef *offsets,
                                         const struct lp_derivatives *derivs,
@@ -182,14 +235,17 @@ draw_llvm_sampler_soa_emit_fetch_texel(const struct 
lp_build_sampler_soa *base,
  {
     struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa 
*)base;

-   assert(unit<  PIPE_MAX_SAMPLERS);
+   assert(texture_index<  PIPE_MAX_SHADER_SAMPLER_VIEWS);
+   assert(sampler_index<  PIPE_MAX_SAMPLERS);

     lp_build_sample_soa(gallivm,
-&sampler->dynamic_state.static_state[unit],
+&sampler->dynamic_state.static_state[texture_index].texture_state,
+&sampler->dynamic_state.static_state[sampler_index].sampler_state,
                         &sampler->dynamic_state.base,
                         type,
                         is_fetch,
-                       unit,
+                       texture_index,
+                       sampler_index,
                         coords,
                         offsets,
                         derivs,
@@ -214,7 +270,7 @@ draw_llvm_sampler_soa_emit_size_query(const struct 
lp_build_sampler_soa *base,
     assert(unit<  PIPE_MAX_SAMPLERS);

     lp_build_size_query_soa(gallivm,
-&sampler->dynamic_state.static_state[unit],
+&sampler->dynamic_state.static_state[unit].texture_state,
                             &sampler->dynamic_state.base,
                             type,
                             unit,
@@ -223,7 +279,7 @@ draw_llvm_sampler_soa_emit_size_query(const struct 
lp_build_sampler_soa *base,
  }

  struct lp_build_sampler_soa *
-draw_llvm_sampler_soa_create(const struct lp_sampler_static_state 
*static_state,
+draw_llvm_sampler_soa_create(const struct draw_sampler_static_state 
*static_state,
                               LLVMValueRef context_ptr)
  {
     struct draw_llvm_sampler_soa *sampler;
@@ -244,10 +300,10 @@ draw_llvm_sampler_soa_create(const struct 
lp_sampler_static_state *static_state,
     sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride;
     sampler->dynamic_state.base.base_ptr = draw_llvm_texture_base_ptr;
     sampler->dynamic_state.base.mip_offsets = draw_llvm_texture_mip_offsets;
-   sampler->dynamic_state.base.min_lod = draw_llvm_texture_min_lod;
-   sampler->dynamic_state.base.max_lod = draw_llvm_texture_max_lod;
-   sampler->dynamic_state.base.lod_bias = draw_llvm_texture_lod_bias;
-   sampler->dynamic_state.base.border_color = draw_llvm_texture_border_color;
+   sampler->dynamic_state.base.min_lod = draw_llvm_sampler_min_lod;
+   sampler->dynamic_state.base.max_lod = draw_llvm_sampler_max_lod;
+   sampler->dynamic_state.base.lod_bias = draw_llvm_sampler_lod_bias;
+   sampler->dynamic_state.base.border_color = draw_llvm_sampler_border_color;
     sampler->dynamic_state.static_state = static_state;
     sampler->dynamic_state.context_ptr = context_ptr;

diff --git a/src/gallium/auxiliary/draw/draw_private.h 
b/src/gallium/auxiliary/draw/draw_private.h
index 2223fcb..ec5791c 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -310,7 +310,7 @@ struct draw_context
      * we only handle vertex and geometry shaders in the draw module, but
      * there may be more in the future (ex: hull and tessellation).
      */
-   struct pipe_sampler_view 
*sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
+   struct pipe_sampler_view 
*sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
     unsigned num_sampler_views[PIPE_SHADER_TYPES];
     const struct pipe_sampler_state 
*samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
     unsigned num_samplers[PIPE_SHADER_TYPES];
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c 
b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index 04f4135..4e4bca3 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -87,24 +87,54 @@ lp_sampler_wrap_mode_uses_border_color(unsigned mode,


  /**
- * Initialize lp_sampler_static_state object with the gallium sampler
- * and texture state.
- * The former is considered to be static and the later dynamic.
+ * Initialize lp_sampler_static_texture_state object with the gallium
+ * texture/sampler_view state (this contains the parts which are
+ * considered static).
   */
  void
-lp_sampler_static_state(struct lp_sampler_static_state *state,
-                        const struct pipe_sampler_view *view,
-                        const struct pipe_sampler_state *sampler)
+lp_sampler_static_texture_state(struct lp_static_texture_state *state,
+                                const struct pipe_sampler_view *view)
  {
     const struct pipe_resource *texture;

     memset(state, 0, sizeof *state);

-   if (!sampler || !view || !view->texture)
+   if (!view || !view->texture)
        return;

     texture = view->texture;

+   state->format            = view->format;
+   state->swizzle_r         = view->swizzle_r;
+   state->swizzle_g         = view->swizzle_g;
+   state->swizzle_b         = view->swizzle_b;
+   state->swizzle_a         = view->swizzle_a;
+
+   state->target            = texture->target;
+   state->pot_width         = util_is_power_of_two(texture->width0);
+   state->pot_height        = util_is_power_of_two(texture->height0);
+   state->pot_depth         = util_is_power_of_two(texture->depth0);
+   state->level_zero_only   = !view->u.tex.last_level;
+
+   /*
+    * FIXME: Handle the remainder of pipe_sampler_view.
+    */
+}
+
+
+/**
+ * Initialize lp_sampler_static_sampler_state object with the gallium sampler
+ * state (this contains the parts which are considered static).
+ */
+void
+lp_sampler_static_sampler_state(struct lp_static_sampler_state *state,
+                                const struct pipe_sampler_state *sampler)
+{
+   memset(state, 0, sizeof *state);
+
+   if (!sampler)
+      return;
+
     /*
      * We don't copy sampler state over unless it is actually enabled, to avoid
      * spurious recompiles, as the sampler static state is part of the shader
@@ -117,24 +147,13 @@ lp_sampler_static_state(struct lp_sampler_static_state 
*state,
      * regarding 1D/2D/3D/CUBE textures, wrap modes, etc.
      */

-   state->format            = view->format;
-   state->swizzle_r         = view->swizzle_r;
-   state->swizzle_g         = view->swizzle_g;
-   state->swizzle_b         = view->swizzle_b;
-   state->swizzle_a         = view->swizzle_a;
-
-   state->target            = texture->target;
-   state->pot_width         = util_is_power_of_two(texture->width0);
-   state->pot_height        = util_is_power_of_two(texture->height0);
-   state->pot_depth         = util_is_power_of_two(texture->depth0);
-
     state->wrap_s            = sampler->wrap_s;
     state->wrap_t            = sampler->wrap_t;
     state->wrap_r            = sampler->wrap_r;
     state->min_img_filter    = sampler->min_img_filter;
     state->mag_img_filter    = sampler->mag_img_filter;

-   if (view->u.tex.last_level&&  sampler->max_lod>  0.0f) {
+   if (sampler->max_lod>  0.0f) {
        state->min_mip_filter = sampler->min_mip_filter;
     } else {
        state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
@@ -155,7 +174,11 @@ lp_sampler_static_state(struct lp_sampler_static_state 
*state,
              state->apply_min_lod = 1;
           }

-         if (sampler->max_lod<  (float)view->u.tex.last_level) {
+         /*
+          * XXX this won't do anything with the mesa state tracker which always
+          * sets max_lod to not more than actually present mip maps...
+          */
+         if (sampler->max_lod<  (PIPE_MAX_TEXTURE_LEVELS - 1)) {
              state->apply_max_lod = 1;
           }
        }
@@ -167,10 +190,6 @@ lp_sampler_static_state(struct lp_sampler_static_state 
*state,
     }

     state->normalized_coords = sampler->normalized_coords;
-
-   /*
-    * FIXME: Handle the remainder of pipe_sampler_view.
-    */
  }


@@ -182,7 +201,7 @@ lp_sampler_static_state(struct lp_sampler_static_state 
*state,
   */
  static LLVMValueRef
  lp_build_rho(struct lp_build_sample_context *bld,
-             unsigned unit,
+             unsigned texture_unit,
               const struct lp_derivatives *derivs)
  {
     struct gallivm_state *gallivm = bld->gallivm;
@@ -264,7 +283,7 @@ lp_build_rho(struct lp_build_sample_context *bld,
     rho_vec = lp_build_max(coord_bld, rho_xvec, rho_yvec);

     first_level = bld->dynamic_state->first_level(bld->dynamic_state,
-                                                 bld->gallivm, unit);
+                                                 bld->gallivm, texture_unit);
     first_level_vec = lp_build_broadcast_scalar(int_size_bld, first_level);
     int_size = lp_build_minify(int_size_bld, bld->int_size, first_level_vec);
     float_size = lp_build_int_to_float(float_size_bld, int_size);
@@ -489,7 +508,8 @@ lp_build_brilinear_rho(struct lp_build_context *bld,
   */
  void
  lp_build_lod_selector(struct lp_build_sample_context *bld,
-                      unsigned unit,
+                      unsigned texture_unit,
+                      unsigned sampler_unit,
                        const struct lp_derivatives *derivs,
                        LLVMValueRef lod_bias, /* optional */
                        LLVMValueRef explicit_lod, /* optional */
@@ -505,12 +525,13 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
     *out_lod_ipart = bld->perquadi_bld.zero;
     *out_lod_fpart = perquadf_bld->zero;

-   if (bld->static_state->min_max_lod_equal) {
+   if (bld->static_sampler_state->min_max_lod_equal) {
        /* User is forcing sampling from a particular mipmap level.
         * This is hit during mipmap generation.
         */
        LLVMValueRef min_lod =
-         bld->dynamic_state->min_lod(bld->dynamic_state, bld->gallivm, unit);
+         bld->dynamic_state->min_lod(bld->dynamic_state,
+                                     bld->gallivm, sampler_unit);

        lod = lp_build_broadcast_scalar(perquadf_bld, min_lod);
     }
@@ -522,16 +543,16 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
        else {
           LLVMValueRef rho;

-         rho = lp_build_rho(bld, unit, derivs);
+         rho = lp_build_rho(bld, texture_unit, derivs);

           /*
            * Compute lod = log2(rho)
            */

           if (!lod_bias&&
-             !bld->static_state->lod_bias_non_zero&&
-             !bld->static_state->apply_max_lod&&
-             !bld->static_state->apply_min_lod) {
+             !bld->static_sampler_state->lod_bias_non_zero&&
+             !bld->static_sampler_state->apply_max_lod&&
+             !bld->static_sampler_state->apply_min_lod) {
              /*
               * Special case when there are no post-log2 adjustments, which
               * saves instructions but keeping the integer and fractional lod
@@ -568,25 +589,28 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
        }

        /* add sampler lod bias */
-      if (bld->static_state->lod_bias_non_zero) {
+      if (bld->static_sampler_state->lod_bias_non_zero) {
           LLVMValueRef sampler_lod_bias =
-            bld->dynamic_state->lod_bias(bld->dynamic_state, bld->gallivm, 
unit);
+            bld->dynamic_state->lod_bias(bld->dynamic_state,
+                                         bld->gallivm, sampler_unit);
           sampler_lod_bias = lp_build_broadcast_scalar(perquadf_bld,
                                                        sampler_lod_bias);
           lod = LLVMBuildFAdd(builder, lod, sampler_lod_bias, 
"sampler_lod_bias");
        }

        /* clamp lod */
-      if (bld->static_state->apply_max_lod) {
+      if (bld->static_sampler_state->apply_max_lod) {
           LLVMValueRef max_lod =
-            bld->dynamic_state->max_lod(bld->dynamic_state, bld->gallivm, 
unit);
+            bld->dynamic_state->max_lod(bld->dynamic_state,
+                                        bld->gallivm, sampler_unit);
           max_lod = lp_build_broadcast_scalar(perquadf_bld, max_lod);

           lod = lp_build_min(perquadf_bld, lod, max_lod);
        }
-      if (bld->static_state->apply_min_lod) {
+      if (bld->static_sampler_state->apply_min_lod) {
           LLVMValueRef min_lod =
-            bld->dynamic_state->min_lod(bld->dynamic_state, bld->gallivm, 
unit);
+            bld->dynamic_state->min_lod(bld->dynamic_state,
+                                        bld->gallivm, sampler_unit);
           min_lod = lp_build_broadcast_scalar(perquadf_bld, min_lod);

           lod = lp_build_max(perquadf_bld, lod, min_lod);
@@ -988,9 +1012,9 @@ lp_build_mipmap_level_sizes(struct lp_build_sample_context 
*bld,
                                                        ilevel);
     }
     if (dims == 3 ||
-       bld->static_state->target == PIPE_TEXTURE_CUBE ||
-       bld->static_state->target == PIPE_TEXTURE_1D_ARRAY ||
-       bld->static_state->target == PIPE_TEXTURE_2D_ARRAY) {
+       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) {
        *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 87bf556..a252ea2 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -61,12 +61,12 @@ struct lp_derivatives


  /**
- * Sampler static state.
+ * Texture static state.
   *
- * These are the bits of state from pipe_resource and pipe_sampler_state that
+ * These are the bits of state from pipe_resource/pipe_sampler_view that
   * are embedded in the generated code.
   */
-struct lp_sampler_static_state
+struct lp_static_texture_state
  {
     /* pipe_sampler_view's state */
     enum pipe_format format;
@@ -80,7 +80,24 @@ struct lp_sampler_static_state
     unsigned pot_width:1;     /**<  is the width a power of two? */
     unsigned pot_height:1;
     unsigned pot_depth:1;
+   unsigned level_zero_only:1;
+};
+
+
+struct lp_derived_sampler_state
+{
+   unsigned min_mip_filter:2;
+};
+

+/**
+ * Sampler static state.
+ *
+ * These are the bits of state from pipe_sampler_state that
+ * are embedded in the generated code.
+ */
+struct lp_static_sampler_state
+{
     /* pipe_sampler_state's state */
     unsigned wrap_s:3;
     unsigned wrap_t:3;
@@ -105,8 +122,8 @@ struct lp_sampler_static_state
  /**
   * Sampler dynamic state.
   *
- * These are the bits of state from pipe_resource and pipe_sampler_state that
- * are computed in runtime.
+ * These are the bits of state from pipe_resource/pipe_sampler_view
+ * as well as from sampler state that are computed in runtime.

"computed at runtime"

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to