gallivm: split sampler and texture state
authorRoland Scheidegger <sroland@vmware.com>
Mon, 28 Jan 2013 14:50:36 +0000 (06:50 -0800)
committerRoland Scheidegger <sroland@vmware.com>
Mon, 28 Jan 2013 14:50:36 +0000 (06:50 -0800)
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.

v3: fix more of PIPE_MAX_SAMPLER / PIPE_MAX_SHADER_SAMPLER_VIEWS mismatches
(both in draw and llvmpipe), based on feedback from José get rid of unneeded
static sampler derived state.(which also fixes the only 2 piglit regressions
due to a forgotten assignment), fix comments based on Brian's feedback.

v4: remove some accidental unrelated whitespace changes

Reviewed-by: José Fonseca <jfonseca@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
20 files changed:
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/draw/draw_llvm_sample.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/gallivm/lp_bld_sample.c
src/gallium/auxiliary/gallivm/lp_bld_sample.h
src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c
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_context.h
src/gallium/drivers/llvmpipe/lp_jit.c
src/gallium/drivers/llvmpipe/lp_jit.h
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_setup_context.h
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/llvmpipe/lp_state_fs.h
src/gallium/drivers/llvmpipe/lp_state_sampler.c
src/gallium/drivers/llvmpipe/lp_tex_sample.c

index bc2f0e1d03f999fdc28f5bb88d9016b11518c41f..dfa8927bc0808f63c44c980ba91addee5a64784a 100644 (file)
@@ -762,11 +762,11 @@ draw_set_sampler_views(struct draw_context *draw,
    unsigned i;
 
    debug_assert(shader_stage < PIPE_SHADER_TYPES);
-   debug_assert(num <= PIPE_MAX_SAMPLERS);
+   debug_assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
 
    for (i = 0; i < num; ++i)
       draw->sampler_views[shader_stage][i] = views[i];
-   for (i = num; i < PIPE_MAX_SAMPLERS; ++i)
+   for (i = num; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; ++i)
       draw->sampler_views[shader_stage][i] = NULL;
 
    draw->num_sampler_views[shader_stage] = num;
index a3a3bbfea489322dd1bb99d878d9679e448c46b3..afb10a6a33acd995d02a0af37621af20823daded 100644 (file)
@@ -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_texture
+ * 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_context
  */
 static LLVMTypeRef
 create_jit_context_type(struct gallivm_state *gallivm,
-                        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);
@@ -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));
    }
 }
 
@@ -1430,15 +1480,15 @@ 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);
       }
    }
 }
index 892973c3725dae2dbe5df027223f07e9f54e65bc..a6648573aa523463eb50c30bc6a60e706dcbda38 100644 (file)
@@ -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
index 67d4e9339d674c5aa95946120b19a3436a91f858..9932b911120ebb0296295746ec81534f1a4c3348 100644 (file)
@@ -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,53 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
 }
 
 
+/**
+ * Fetch the specified member of the lp_jit_sampler structure.
+ * \param emit_load  if TRUE, emit the LLVM load instruction to actually
+ *                   fetch the field's value.  Otherwise, just emit the
+ *                   GEP code to address the field.
+ *
+ * @sa http://llvm.org/docs/GetElementPtr.html
+ */
+static LLVMValueRef
+draw_llvm_sampler_member(const struct lp_sampler_dynamic_state *base,
+                         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 +197,22 @@ 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 +231,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 +242,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 +277,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 +286,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 +307,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;
 
index 2223fcb3f40881fc5f175dfa70cf303674d29802..ec5791cbc17109772cbc82b86e8da758ee592890 100644 (file)
@@ -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];
index 04f41355e7bd491544c27e1ab64740b26582be79..4e4bca3014f3a980170020cd28f2de6e3cb923ff 100644 (file)
@@ -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);
index 87bf5567e425f021d67ce7ff5fc5ee887ecb6052..d0207aa471ead2f62f2e29036eaac79ea11128b3 100644 (file)
@@ -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,18 @@ 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;
+};
 
+
+/**
+ * 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 +116,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 at runtime.
  *
  * There are obtained through callbacks, as we don't want to tie the texture
  * sampling code generation logic to any particular texture layout or pipe
@@ -114,6 +125,7 @@ struct lp_sampler_static_state
  */
 struct lp_sampler_dynamic_state
 {
+   /* First callbacks for sampler view state */
 
    /** Obtain the base texture width (returns int32) */
    LLVMValueRef
@@ -169,6 +181,8 @@ struct lp_sampler_dynamic_state
                    struct gallivm_state *gallivm,
                    unsigned unit);
 
+   /* These are callbacks for sampler state */
+
    /** Obtain texture min lod (returns float) */
    LLVMValueRef
    (*min_lod)(const struct lp_sampler_dynamic_state *state,
@@ -198,7 +212,8 @@ struct lp_build_sample_context
 {
    struct gallivm_state *gallivm;
 
-   const struct lp_sampler_static_state *static_state;
+   const struct lp_static_texture_state *static_texture_state;
+   const struct lp_static_sampler_state *static_sampler_state;
 
    struct lp_sampler_dynamic_state *dynamic_state;
 
@@ -295,10 +310,10 @@ apply_sampler_swizzle(struct lp_build_sample_context *bld,
 {
    unsigned char swizzles[4];
 
-   swizzles[0] = bld->static_state->swizzle_r;
-   swizzles[1] = bld->static_state->swizzle_g;
-   swizzles[2] = bld->static_state->swizzle_b;
-   swizzles[3] = bld->static_state->swizzle_a;
+   swizzles[0] = bld->static_texture_state->swizzle_r;
+   swizzles[1] = bld->static_texture_state->swizzle_g;
+   swizzles[2] = bld->static_texture_state->swizzle_b;
+   swizzles[3] = bld->static_texture_state->swizzle_a;
 
    lp_build_swizzle_soa_inplace(&bld->texel_bld, texel, swizzles);
 }
@@ -338,14 +353,19 @@ lp_sampler_wrap_mode_uses_border_color(unsigned mode,
  * Derive the sampler static state.
  */
 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_sampler_state(struct lp_static_sampler_state *state,
+                                const struct pipe_sampler_state *sampler);
+
+
+void
+lp_sampler_static_texture_state(struct lp_static_texture_state *state,
+                                const struct pipe_sampler_view *view);
 
 
 void
 lp_build_lod_selector(struct lp_build_sample_context *bld,
-                      unsigned unit,
+                      unsigned texture_index,
+                      unsigned sampler_index,
                       const struct lp_derivatives *derivs,
                       LLVMValueRef lod_bias, /* optional */
                       LLVMValueRef explicit_lod, /* optional */
@@ -437,11 +457,13 @@ lp_build_sample_offset(struct lp_build_context *bld,
 
 void
 lp_build_sample_soa(struct gallivm_state *gallivm,
-                    const struct lp_sampler_static_state *static_state,
-                    struct lp_sampler_dynamic_state *dynamic_state,
+                    const struct lp_static_texture_state *static_texture_state,
+                    const struct lp_static_sampler_state *static_sampler_state,
+                    struct lp_sampler_dynamic_state *dynamic_texture_state,
                     struct lp_type fp_type,
                     boolean is_fetch,
-                    unsigned unit,
+                    unsigned texture_index,
+                    unsigned sampler_index,
                     const LLVMValueRef *coords,
                     const LLVMValueRef *offsets,
                     const struct lp_derivatives *derivs,
@@ -461,7 +483,7 @@ lp_build_coord_repeat_npot_linear(struct lp_build_sample_context *bld,
 
 void
 lp_build_size_query_soa(struct gallivm_state *gallivm,
-                        const struct lp_sampler_static_state *static_state,
+                        const struct lp_static_texture_state *static_state,
                         struct lp_sampler_dynamic_state *dynamic_state,
                         struct lp_type int_type,
                         unsigned unit,
index 9371e1c281898b85a642b6637dbbb84090a2bb33..b9c8446032ea70e19c11369b8906777b1f6cf23b 100644 (file)
@@ -152,7 +152,7 @@ lp_build_sample_wrap_nearest_float(struct lp_build_sample_context *bld,
       break;
    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
       length_minus_one = lp_build_sub(coord_bld, length, coord_bld->one);
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* scale coord to length */
          coord = lp_build_mul(coord_bld, coord, length);
       }
@@ -407,7 +407,7 @@ lp_build_sample_wrap_linear_float(struct lp_build_sample_context *bld,
       }
       break;
    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* mul by tex size */
          coord = lp_build_mul(coord_bld, coord, length);
       }
@@ -549,7 +549,7 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
 
    s_float = s; t_float = t; r_float = r;
 
-   if (bld->static_state->normalized_coords) {
+   if (bld->static_sampler_state->normalized_coords) {
       LLVMValueRef scaled_size;
       LLVMValueRef flt_size;
 
@@ -594,8 +594,8 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
                                     bld->format_desc->block.width,
                                     s_ipart, s_float,
                                     width_vec, x_stride,
-                                    bld->static_state->pot_width,
-                                    bld->static_state->wrap_s,
+                                    bld->static_texture_state->pot_width,
+                                    bld->static_sampler_state->wrap_s,
                                     &x_offset, &x_subcoord);
    offset = x_offset;
    if (dims >= 2) {
@@ -604,8 +604,8 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
                                        bld->format_desc->block.height,
                                        t_ipart, t_float,
                                        height_vec, row_stride_vec,
-                                       bld->static_state->pot_height,
-                                       bld->static_state->wrap_t,
+                                       bld->static_texture_state->pot_height,
+                                       bld->static_sampler_state->wrap_t,
                                        &y_offset, &y_subcoord);
       offset = lp_build_add(&bld->int_coord_bld, offset, y_offset);
       if (dims >= 3) {
@@ -614,15 +614,15 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
                                           1, /* block length (depth) */
                                           r_ipart, r_float,
                                           depth_vec, img_stride_vec,
-                                          bld->static_state->pot_depth,
-                                          bld->static_state->wrap_r,
+                                          bld->static_texture_state->pot_depth,
+                                          bld->static_sampler_state->wrap_r,
                                           &z_offset, &z_subcoord);
          offset = lp_build_add(&bld->int_coord_bld, offset, z_offset);
       }
    }
-   if (bld->static_state->target == PIPE_TEXTURE_CUBE ||
-       bld->static_state->target == PIPE_TEXTURE_1D_ARRAY ||
-       bld->static_state->target == PIPE_TEXTURE_2D_ARRAY) {
+   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) {
       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);
@@ -678,28 +678,28 @@ lp_build_sample_image_nearest_afloat(struct lp_build_sample_context *bld,
    /* Do texcoord wrapping */
    lp_build_sample_wrap_nearest_float(bld,
                                       s, width_vec,
-                                      bld->static_state->pot_width,
-                                      bld->static_state->wrap_s,
+                                      bld->static_texture_state->pot_width,
+                                      bld->static_sampler_state->wrap_s,
                                       &x_icoord);
 
    if (dims >= 2) {
       lp_build_sample_wrap_nearest_float(bld,
                                          t, height_vec,
-                                         bld->static_state->pot_height,
-                                         bld->static_state->wrap_t,
+                                         bld->static_texture_state->pot_height,
+                                         bld->static_sampler_state->wrap_t,
                                          &y_icoord);
 
       if (dims >= 3) {
          lp_build_sample_wrap_nearest_float(bld,
                                             r, depth_vec,
-                                            bld->static_state->pot_depth,
-                                            bld->static_state->wrap_r,
+                                            bld->static_texture_state->pot_depth,
+                                            bld->static_sampler_state->wrap_r,
                                             &z_icoord);
       }
    }
-   if (bld->static_state->target == PIPE_TEXTURE_CUBE ||
-       bld->static_state->target == PIPE_TEXTURE_1D_ARRAY ||
-       bld->static_state->target == PIPE_TEXTURE_2D_ARRAY) {
+   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) {
       z_icoord = r;
    }
 
@@ -885,7 +885,7 @@ lp_build_sample_fetch_image_linear(struct lp_build_sample_context *bld,
    /*
     * Linear interpolation with 8.8 fixed point.
     */
-   if (bld->static_state->force_nearest_s) {
+   if (bld->static_sampler_state->force_nearest_s) {
       /* special case 1-D lerp */
       packed_lo = lp_build_lerp(&h16,
                                 t_fpart_lo,
@@ -897,7 +897,7 @@ lp_build_sample_fetch_image_linear(struct lp_build_sample_context *bld,
                                 neighbors_hi[0][1][0],
                                 neighbors_hi[0][1][0]);
    }
-   else if (bld->static_state->force_nearest_t) {
+   else if (bld->static_sampler_state->force_nearest_t) {
       /* special case 1-D lerp */
       packed_lo = lp_build_lerp(&h16,
                                 s_fpart_lo,
@@ -1016,7 +1016,7 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
 
    s_float = s; t_float = t; r_float = r;
 
-   if (bld->static_state->normalized_coords) {
+   if (bld->static_sampler_state->normalized_coords) {
       LLVMValueRef scaled_size;
       LLVMValueRef flt_size;
 
@@ -1045,10 +1045,10 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
 
    /* subtract 0.5 (add -128) */
    i32_c128 = lp_build_const_int_vec(bld->gallivm, i32.type, -128);
-   if (!bld->static_state->force_nearest_s) {
+   if (!bld->static_sampler_state->force_nearest_s) {
       s = LLVMBuildAdd(builder, s, i32_c128, "");
    }
-   if (dims >= 2 && !bld->static_state->force_nearest_t) {
+   if (dims >= 2 && !bld->static_sampler_state->force_nearest_t) {
       t = LLVMBuildAdd(builder, t, i32_c128, "");
    }
    if (dims >= 3) {
@@ -1082,15 +1082,15 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
                                    bld->format_desc->block.width,
                                    s_ipart, &s_fpart, s_float,
                                    width_vec, x_stride,
-                                   bld->static_state->pot_width,
-                                   bld->static_state->wrap_s,
+                                   bld->static_texture_state->pot_width,
+                                   bld->static_sampler_state->wrap_s,
                                    &x_offset0, &x_offset1,
                                    &x_subcoord[0], &x_subcoord[1]);
 
    /* add potential cube/array/mip offsets now as they are constant per pixel */
-   if (bld->static_state->target == PIPE_TEXTURE_CUBE ||
-       bld->static_state->target == PIPE_TEXTURE_1D_ARRAY ||
-       bld->static_state->target == PIPE_TEXTURE_2D_ARRAY) {
+   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) {
       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 */
@@ -1114,8 +1114,8 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
                                       bld->format_desc->block.height,
                                       t_ipart, &t_fpart, t_float,
                                       height_vec, y_stride,
-                                      bld->static_state->pot_height,
-                                      bld->static_state->wrap_t,
+                                      bld->static_texture_state->pot_height,
+                                      bld->static_sampler_state->wrap_t,
                                       &y_offset0, &y_offset1,
                                       &y_subcoord[0], &y_subcoord[1]);
 
@@ -1134,8 +1134,8 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
                                       bld->format_desc->block.height,
                                       r_ipart, &r_fpart, r_float,
                                       depth_vec, z_stride,
-                                      bld->static_state->pot_depth,
-                                      bld->static_state->wrap_r,
+                                      bld->static_texture_state->pot_depth,
+                                      bld->static_sampler_state->wrap_r,
                                       &z_offset0, &z_offset1,
                                       &z_subcoord[0], &z_subcoord[1]);
       for (y = 0; y < 2; y++) {
@@ -1205,28 +1205,28 @@ lp_build_sample_image_linear_afloat(struct lp_build_sample_context *bld,
    lp_build_sample_wrap_linear_float(bld,
                                      bld->format_desc->block.width,
                                      s, width_vec,
-                                     bld->static_state->pot_width,
-                                     bld->static_state->wrap_s,
+                                     bld->static_texture_state->pot_width,
+                                     bld->static_sampler_state->wrap_s,
                                      &x_icoord0, &x_icoord1,
                                      &s_fpart,
-                                     bld->static_state->force_nearest_s);
+                                     bld->static_sampler_state->force_nearest_s);
 
    if (dims >= 2) {
       lp_build_sample_wrap_linear_float(bld,
                                         bld->format_desc->block.height,
                                         t, height_vec,
-                                        bld->static_state->pot_height,
-                                        bld->static_state->wrap_t,
+                                        bld->static_texture_state->pot_height,
+                                        bld->static_sampler_state->wrap_t,
                                         &y_icoord0, &y_icoord1,
                                         &t_fpart,
-                                        bld->static_state->force_nearest_t);
+                                        bld->static_sampler_state->force_nearest_t);
 
       if (dims >= 3) {
          lp_build_sample_wrap_linear_float(bld,
                                            bld->format_desc->block.height,
                                            r, depth_vec,
-                                           bld->static_state->pot_depth,
-                                           bld->static_state->wrap_r,
+                                           bld->static_texture_state->pot_depth,
+                                           bld->static_sampler_state->wrap_r,
                                            &z_icoord0, &z_icoord1,
                                            &r_fpart, 0);
       }
@@ -1259,9 +1259,9 @@ 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_state->target == PIPE_TEXTURE_CUBE ||
-       bld->static_state->target == PIPE_TEXTURE_1D_ARRAY ||
-       bld->static_state->target == PIPE_TEXTURE_2D_ARRAY) {
+   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) {
       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 */
@@ -1582,20 +1582,20 @@ lp_build_sample_aos(struct lp_build_sample_context *bld,
 {
    struct lp_build_context *int_bld = &bld->int_bld;
    LLVMBuilderRef builder = bld->gallivm->builder;
-   const unsigned mip_filter = bld->static_state->min_mip_filter;
-   const unsigned min_filter = bld->static_state->min_img_filter;
-   const unsigned mag_filter = bld->static_state->mag_img_filter;
+   const unsigned mip_filter = bld->static_sampler_state->min_mip_filter;
+   const unsigned min_filter = bld->static_sampler_state->min_img_filter;
+   const unsigned mag_filter = bld->static_sampler_state->mag_img_filter;
    const unsigned dims = bld->dims;
    LLVMValueRef packed, packed_lo, packed_hi;
    LLVMValueRef unswizzled[4];
    struct lp_build_context h16_bld;
 
    /* we only support the common/simple wrap modes at this time */
-   assert(lp_is_simple_wrap_mode(bld->static_state->wrap_s));
+   assert(lp_is_simple_wrap_mode(bld->static_sampler_state->wrap_s));
    if (dims >= 2)
-      assert(lp_is_simple_wrap_mode(bld->static_state->wrap_t));
+      assert(lp_is_simple_wrap_mode(bld->static_sampler_state->wrap_t));
    if (dims >= 3)
-      assert(lp_is_simple_wrap_mode(bld->static_state->wrap_r));
+      assert(lp_is_simple_wrap_mode(bld->static_sampler_state->wrap_r));
 
 
    /* make 16-bit fixed-pt builder context */
index 918dd36fbf56fabbad7a3b62bc22ae5247cdc4c7..0e901948aa2fa6e3a2a51acee95b8f789b3cf548 100644 (file)
@@ -85,7 +85,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
                           LLVMValueRef mipoffsets,
                           LLVMValueRef texel_out[4])
 {
-   const struct lp_sampler_static_state *static_state = bld->static_state;
+   const struct lp_static_sampler_state *static_state = bld->static_sampler_state;
    const unsigned dims = bld->dims;
    struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
    LLVMBuilderRef builder = bld->gallivm->builder;
@@ -317,7 +317,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
       break;
 
    case PIPE_TEX_WRAP_CLAMP:
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* scale coord to length */
          coord = lp_build_mul(coord_bld, coord, length_f);
       }
@@ -337,7 +337,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
          struct lp_build_context abs_coord_bld = bld->coord_bld;
          abs_coord_bld.type.sign = FALSE;
 
-         if (bld->static_state->normalized_coords) {
+         if (bld->static_sampler_state->normalized_coords) {
             /* mul by tex size */
             coord = lp_build_mul(coord_bld, coord, length_f);
          }
@@ -356,7 +356,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
       }
 
    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* scale coord to length */
          coord = lp_build_mul(coord_bld, coord, length_f);
       }
@@ -389,7 +389,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
    case PIPE_TEX_WRAP_MIRROR_CLAMP:
       coord = lp_build_abs(coord_bld, coord);
 
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* scale coord to length */
          coord = lp_build_mul(coord_bld, coord, length_f);
       }
@@ -411,7 +411,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
          abs_coord_bld.type.sign = FALSE;
          coord = lp_build_abs(coord_bld, coord);
 
-         if (bld->static_state->normalized_coords) {
+         if (bld->static_sampler_state->normalized_coords) {
             /* scale coord to length */
             coord = lp_build_mul(coord_bld, coord, length_f);
          }
@@ -433,7 +433,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
       {
          coord = lp_build_abs(coord_bld, coord);
 
-         if (bld->static_state->normalized_coords) {
+         if (bld->static_sampler_state->normalized_coords) {
             /* scale coord to length */
             coord = lp_build_mul(coord_bld, coord, length_f);
          }
@@ -500,7 +500,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
 
    case PIPE_TEX_WRAP_CLAMP:
    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* scale coord to length */
          coord = lp_build_mul(coord_bld, coord, length_f);
       }
@@ -515,7 +515,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
       break;
 
    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* scale coord to length */
          coord = lp_build_mul(coord_bld, coord, length_f);
       }
@@ -528,7 +528,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
       coord = lp_build_coord_mirror(bld, coord);
 
       /* scale coord to length */
-      assert(bld->static_state->normalized_coords);
+      assert(bld->static_sampler_state->normalized_coords);
       coord = lp_build_mul(coord_bld, coord, length_f);
 
       /* itrunc == ifloor here */
@@ -542,7 +542,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
       coord = lp_build_abs(coord_bld, coord);
 
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* scale coord to length */
          coord = lp_build_mul(coord_bld, coord, length_f);
       }
@@ -557,7 +557,7 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
    case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
       coord = lp_build_abs(coord_bld, coord);
 
-      if (bld->static_state->normalized_coords) {
+      if (bld->static_sampler_state->normalized_coords) {
          /* scale coord to length */
          coord = lp_build_mul(coord_bld, coord, length_f);
       }
@@ -620,26 +620,26 @@ lp_build_sample_image_nearest(struct lp_build_sample_context *bld,
     * Compute integer texcoords.
     */
    x = lp_build_sample_wrap_nearest(bld, s, width_vec, flt_width_vec,
-                                    bld->static_state->pot_width,
-                                    bld->static_state->wrap_s);
+                                    bld->static_texture_state->pot_width,
+                                    bld->static_sampler_state->wrap_s);
    lp_build_name(x, "tex.x.wrapped");
 
    if (dims >= 2) {
       y = lp_build_sample_wrap_nearest(bld, t, height_vec, flt_height_vec,
-                                       bld->static_state->pot_height,
-                                       bld->static_state->wrap_t);
+                                       bld->static_texture_state->pot_height,
+                                       bld->static_sampler_state->wrap_t);
       lp_build_name(y, "tex.y.wrapped");
 
       if (dims == 3) {
          z = lp_build_sample_wrap_nearest(bld, r, depth_vec, flt_depth_vec,
-                                          bld->static_state->pot_depth,
-                                          bld->static_state->wrap_r);
+                                          bld->static_texture_state->pot_depth,
+                                          bld->static_sampler_state->wrap_r);
          lp_build_name(z, "tex.z.wrapped");
       }
    }
-   if (bld->static_state->target == PIPE_TEXTURE_CUBE ||
-       bld->static_state->target == PIPE_TEXTURE_1D_ARRAY ||
-       bld->static_state->target == PIPE_TEXTURE_2D_ARRAY) {
+   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) {
       z = r;
       lp_build_name(z, "tex.z.layer");
    }
@@ -703,32 +703,32 @@ lp_build_sample_image_linear(struct lp_build_sample_context *bld,
     * Compute integer texcoords.
     */
    lp_build_sample_wrap_linear(bld, s, width_vec, flt_width_vec,
-                               bld->static_state->pot_width,
-                               bld->static_state->wrap_s,
+                               bld->static_texture_state->pot_width,
+                               bld->static_sampler_state->wrap_s,
                                &x0, &x1, &s_fpart);
    lp_build_name(x0, "tex.x0.wrapped");
    lp_build_name(x1, "tex.x1.wrapped");
 
    if (dims >= 2) {
       lp_build_sample_wrap_linear(bld, t, height_vec, flt_height_vec,
-                                  bld->static_state->pot_height,
-                                  bld->static_state->wrap_t,
+                                  bld->static_texture_state->pot_height,
+                                  bld->static_sampler_state->wrap_t,
                                   &y0, &y1, &t_fpart);
       lp_build_name(y0, "tex.y0.wrapped");
       lp_build_name(y1, "tex.y1.wrapped");
 
       if (dims == 3) {
          lp_build_sample_wrap_linear(bld, r, depth_vec, flt_depth_vec,
-                                     bld->static_state->pot_depth,
-                                     bld->static_state->wrap_r,
+                                     bld->static_texture_state->pot_depth,
+                                     bld->static_sampler_state->wrap_r,
                                      &z0, &z1, &r_fpart);
          lp_build_name(z0, "tex.z0.wrapped");
          lp_build_name(z1, "tex.z1.wrapped");
       }
    }
-   if (bld->static_state->target == PIPE_TEXTURE_CUBE ||
-       bld->static_state->target == PIPE_TEXTURE_1D_ARRAY ||
-       bld->static_state->target == PIPE_TEXTURE_2D_ARRAY) {
+   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) {
       z0 = z1 = r;  /* cube face or array layer */
       lp_build_name(z0, "tex.z0.layer");
       lp_build_name(z1, "tex.z1.layer");
@@ -1004,7 +1004,8 @@ lp_build_layer_coord(struct lp_build_sample_context *bld,
  */
 static void
 lp_build_sample_common(struct lp_build_sample_context *bld,
-                       unsigned unit,
+                       unsigned texture_index,
+                       unsigned sampler_index,
                        LLVMValueRef *s,
                        LLVMValueRef *t,
                        LLVMValueRef *r,
@@ -1016,10 +1017,10 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
                        LLVMValueRef *ilevel0,
                        LLVMValueRef *ilevel1)
 {
-   const unsigned mip_filter = bld->static_state->min_mip_filter;
-   const unsigned min_filter = bld->static_state->min_img_filter;
-   const unsigned mag_filter = bld->static_state->mag_img_filter;
-   const unsigned target = bld->static_state->target;
+   const unsigned mip_filter = bld->static_sampler_state->min_mip_filter;
+   const unsigned min_filter = bld->static_sampler_state->min_img_filter;
+   const unsigned mag_filter = bld->static_sampler_state->mag_img_filter;
+   const unsigned target = bld->static_texture_state->target;
    LLVMValueRef first_level;
    struct lp_derivatives face_derivs;
 
@@ -1046,11 +1047,11 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
    }
    else if (target == PIPE_TEXTURE_1D_ARRAY) {
       *r = lp_build_iround(&bld->coord_bld, *t);
-      *r = lp_build_layer_coord(bld, unit, *r);
+      *r = lp_build_layer_coord(bld, texture_index, *r);
    }
    else if (target == PIPE_TEXTURE_2D_ARRAY) {
       *r = lp_build_iround(&bld->coord_bld, *r);
-      *r = lp_build_layer_coord(bld, unit, *r);
+      *r = lp_build_layer_coord(bld, texture_index, *r);
    }
 
    /*
@@ -1061,8 +1062,8 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
       /* Need to compute lod either to choose mipmap levels or to
        * distinguish between minification/magnification with one mipmap level.
        */
-      lp_build_lod_selector(bld, unit, derivs,
-                            lod_bias, explicit_lod,
+      lp_build_lod_selector(bld, texture_index, sampler_index,
+                            derivs, lod_bias, explicit_lod,
                             mip_filter,
                             lod_ipart, lod_fpart);
    } else {
@@ -1085,23 +1086,23 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
           * XXX should probably disable that on other llvm versions.
           */
          assert(*lod_ipart);
-         lp_build_nearest_mip_level(bld, unit, *lod_ipart, ilevel0);
+         lp_build_nearest_mip_level(bld, texture_index, *lod_ipart, ilevel0);
       }
       else {
          first_level = bld->dynamic_state->first_level(bld->dynamic_state,
-                                                       bld->gallivm, unit);
+                                                       bld->gallivm, texture_index);
          first_level = lp_build_broadcast_scalar(&bld->perquadi_bld, first_level);
          *ilevel0 = first_level;
       }
       break;
    case PIPE_TEX_MIPFILTER_NEAREST:
       assert(*lod_ipart);
-      lp_build_nearest_mip_level(bld, unit, *lod_ipart, ilevel0);
+      lp_build_nearest_mip_level(bld, texture_index, *lod_ipart, ilevel0);
       break;
    case PIPE_TEX_MIPFILTER_LINEAR:
       assert(*lod_ipart);
       assert(*lod_fpart);
-      lp_build_linear_mip_levels(bld, unit,
+      lp_build_linear_mip_levels(bld, texture_index,
                                  *lod_ipart, lod_fpart,
                                  ilevel0, ilevel1);
       break;
@@ -1127,9 +1128,9 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
 {
    struct lp_build_context *int_bld = &bld->int_bld;
    LLVMBuilderRef builder = bld->gallivm->builder;
-   const unsigned mip_filter = bld->static_state->min_mip_filter;
-   const unsigned min_filter = bld->static_state->min_img_filter;
-   const unsigned mag_filter = bld->static_state->mag_img_filter;
+   const unsigned mip_filter = bld->static_sampler_state->min_mip_filter;
+   const unsigned min_filter = bld->static_sampler_state->min_img_filter;
+   const unsigned mag_filter = bld->static_sampler_state->mag_img_filter;
    LLVMValueRef texels[4];
    unsigned chan;
 
@@ -1221,7 +1222,7 @@ lp_build_fetch_texel(struct lp_build_sample_context *bld,
    struct lp_build_context *perquadi_bld = &bld->perquadi_bld;
    struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
    unsigned dims = bld->dims, chan;
-   unsigned target = bld->static_state->target;
+   unsigned target = bld->static_texture_state->target;
    LLVMValueRef size, ilevel;
    LLVMValueRef row_stride_vec = NULL, img_stride_vec = NULL;
    LLVMValueRef x = coords[0], y = coords[1], z = coords[2];
@@ -1229,7 +1230,7 @@ lp_build_fetch_texel(struct lp_build_sample_context *bld,
    LLVMValueRef offset, out_of_bounds, out1;
 
    /* XXX just like ordinary sampling, we don't handle per-pixel lod (yet). */
-   if (explicit_lod && bld->static_state->target != PIPE_BUFFER) {
+   if (explicit_lod && bld->static_texture_state->target != PIPE_BUFFER) {
       ilevel = lp_build_pack_aos_scalars(bld->gallivm, int_coord_bld->type,
                                          perquadi_bld->type, explicit_lod, 0);
       lp_build_nearest_mip_level(bld, unit, ilevel, &ilevel);
@@ -1288,7 +1289,7 @@ lp_build_fetch_texel(struct lp_build_sample_context *bld,
                           x, y, z, row_stride_vec, img_stride_vec,
                           &offset, &i, &j);
 
-   if (bld->static_state->target != PIPE_BUFFER) {
+   if (bld->static_texture_state->target != PIPE_BUFFER) {
       offset = lp_build_add(int_coord_bld, offset,
                             lp_build_get_mip_offsets(bld, ilevel));
    }
@@ -1333,11 +1334,11 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
    LLVMValueRef res, p;
    const unsigned chan = 0;
 
-   if (bld->static_state->compare_mode == PIPE_TEX_COMPARE_NONE)
+   if (bld->static_sampler_state->compare_mode == PIPE_TEX_COMPARE_NONE)
       return;
 
-   if (bld->static_state->target == PIPE_TEXTURE_2D_ARRAY ||
-       bld->static_state->target == PIPE_TEXTURE_CUBE) {
+   if (bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY ||
+       bld->static_texture_state->target == PIPE_TEXTURE_CUBE) {
       p = coords[3];
    }
    else {
@@ -1359,7 +1360,7 @@ lp_build_sample_compare(struct lp_build_sample_context *bld,
                       bld->coord_bld.one);
 
    /* result = (p FUNC texel) ? 1 : 0 */
-   res = lp_build_cmp(texel_bld, bld->static_state->compare_func,
+   res = lp_build_cmp(texel_bld, bld->static_sampler_state->compare_func,
                       p, texel[chan]);
    res = lp_build_select(texel_bld, res, texel_bld->one, texel_bld->zero);
 
@@ -1400,11 +1401,13 @@ lp_build_sample_nop(struct gallivm_state *gallivm,
  */
 void
 lp_build_sample_soa(struct gallivm_state *gallivm,
-                    const struct lp_sampler_static_state *static_state,
+                    const struct lp_static_texture_state *static_texture_state,
+                    const struct lp_static_sampler_state *static_sampler_state,
                     struct lp_sampler_dynamic_state *dynamic_state,
                     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,
@@ -1412,10 +1415,11 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
                     LLVMValueRef explicit_lod, /* optional */
                     LLVMValueRef texel_out[4])
 {
-   unsigned dims = texture_dims(static_state->target);
+   unsigned dims = texture_dims(static_texture_state->target);
    unsigned num_quads = type.length / 4;
-   unsigned mip_filter = static_state->min_mip_filter;
+   unsigned mip_filter;
    struct lp_build_sample_context bld;
+   struct lp_static_sampler_state derived_sampler_state = *static_sampler_state;
    LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
    LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef tex_width, tex_height, tex_depth;
@@ -1424,7 +1428,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
    LLVMValueRef r;
 
    if (0) {
-      enum pipe_format fmt = static_state->format;
+      enum pipe_format fmt = static_texture_state->format;
       debug_printf("Sample from %s\n", util_format_name(fmt));
    }
 
@@ -1433,9 +1437,10 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
    /* Setup our build context */
    memset(&bld, 0, sizeof bld);
    bld.gallivm = gallivm;
-   bld.static_state = static_state;
+   bld.static_sampler_state = &derived_sampler_state;
+   bld.static_texture_state = static_texture_state;
    bld.dynamic_state = dynamic_state;
-   bld.format_desc = util_format_description(static_state->format);
+   bld.format_desc = util_format_description(static_texture_state->format);
    bld.dims = dims;
 
    bld.vector_width = lp_type_width(type);
@@ -1466,11 +1471,22 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
       }
    }
 
+   if (!static_texture_state->level_zero_only) {
+      derived_sampler_state.min_mip_filter = static_sampler_state->min_mip_filter;
+   } else {
+      derived_sampler_state.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+   }
+   mip_filter = derived_sampler_state.min_mip_filter;
+
+   if (0) {
+      debug_printf("  .min_mip_filter = %u\n", derived_sampler_state.min_mip_filter);
+   }
+
    /*
     * There are other situations where at least the multiple int lods could be
     * avoided like min and max lod being equal.
     */
-   if ((is_fetch && explicit_lod && bld.static_state->target != PIPE_BUFFER) ||
+   if ((is_fetch && explicit_lod && bld.static_texture_state->target != PIPE_BUFFER) ||
        (!is_fetch && mip_filter != PIPE_TEX_MIPFILTER_NONE)) {
       bld.num_lods = num_quads;
    }
@@ -1497,13 +1513,13 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
    lp_build_context_init(&bld.perquadi_bld, gallivm, bld.perquadi_type);
 
    /* Get the dynamic state */
-   tex_width = dynamic_state->width(dynamic_state, gallivm, unit);
-   tex_height = dynamic_state->height(dynamic_state, gallivm, unit);
-   tex_depth = dynamic_state->depth(dynamic_state, gallivm, unit);
-   bld.row_stride_array = dynamic_state->row_stride(dynamic_state, gallivm, unit);
-   bld.img_stride_array = dynamic_state->img_stride(dynamic_state, gallivm, unit);
-   bld.base_ptr = dynamic_state->base_ptr(dynamic_state, gallivm, unit);
-   bld.mip_offsets = dynamic_state->mip_offsets(dynamic_state, gallivm, unit);
+   tex_width = dynamic_state->width(dynamic_state, gallivm, texture_index);
+   tex_height = dynamic_state->height(dynamic_state, gallivm, texture_index);
+   tex_depth = dynamic_state->depth(dynamic_state, gallivm, texture_index);
+   bld.row_stride_array = dynamic_state->row_stride(dynamic_state, gallivm, texture_index);
+   bld.img_stride_array = dynamic_state->img_stride(dynamic_state, gallivm, texture_index);
+   bld.base_ptr = dynamic_state->base_ptr(dynamic_state, gallivm, texture_index);
+   bld.mip_offsets = dynamic_state->mip_offsets(dynamic_state, gallivm, texture_index);
    /* Note that mip_offsets is an array[level] of offsets to texture images */
 
    s = coords[0];
@@ -1536,7 +1552,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
    }
 
    else if (is_fetch) {
-      lp_build_fetch_texel(&bld, unit, coords,
+      lp_build_fetch_texel(&bld, texture_index, coords,
                            explicit_lod, offsets,
                            texel_out);
    }
@@ -1545,22 +1561,22 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
       LLVMValueRef lod_ipart = NULL, lod_fpart = NULL;
       LLVMValueRef ilevel0 = NULL, ilevel1 = NULL;
       boolean use_aos = util_format_fits_8unorm(bld.format_desc) &&
-                        lp_is_simple_wrap_mode(static_state->wrap_s) &&
-                        lp_is_simple_wrap_mode(static_state->wrap_t);
+                        lp_is_simple_wrap_mode(static_sampler_state->wrap_s) &&
+                        lp_is_simple_wrap_mode(static_sampler_state->wrap_t);
 
       if ((gallivm_debug & GALLIVM_DEBUG_PERF) &&
           !use_aos && util_format_fits_8unorm(bld.format_desc)) {
          debug_printf("%s: using floating point linear filtering for %s\n",
                       __FUNCTION__, bld.format_desc->short_name);
          debug_printf("  min_img %d  mag_img %d  mip %d  wraps %d  wrapt %d\n",
-                      static_state->min_img_filter,
-                      static_state->mag_img_filter,
-                      static_state->min_mip_filter,
-                      static_state->wrap_s,
-                      static_state->wrap_t);
+                      static_sampler_state->min_img_filter,
+                      static_sampler_state->mag_img_filter,
+                      static_sampler_state->min_mip_filter,
+                      static_sampler_state->wrap_s,
+                      static_sampler_state->wrap_t);
       }
 
-      lp_build_sample_common(&bld, unit,
+      lp_build_sample_common(&bld, texture_index, sampler_index,
                              &s, &t, &r,
                              derivs, lod_bias, explicit_lod,
                              &lod_ipart, &lod_fpart,
@@ -1586,7 +1602,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
          }
          if (use_aos) {
             /* do sampling/filtering with fixed pt arithmetic */
-            lp_build_sample_aos(&bld, unit,
+            lp_build_sample_aos(&bld, sampler_index,
                                 s, t, r,
                                 lod_ipart, lod_fpart,
                                 ilevel0, ilevel1,
@@ -1594,7 +1610,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
          }
 
          else {
-            lp_build_sample_general(&bld, unit,
+            lp_build_sample_general(&bld, sampler_index,
                                     s, t, r,
                                     lod_ipart, lod_fpart,
                                     ilevel0, ilevel1,
@@ -1614,7 +1630,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
          /* Setup our build context */
          memset(&bld4, 0, sizeof bld4);
          bld4.gallivm = bld.gallivm;
-         bld4.static_state = bld.static_state;
+         bld4.static_texture_state = bld.static_texture_state;
+         bld4.static_sampler_state = bld.static_sampler_state;
          bld4.dynamic_state = bld.dynamic_state;
          bld4.format_desc = bld.format_desc;
          bld4.dims = bld.dims;
@@ -1675,7 +1692,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
 
             if (use_aos) {
                /* do sampling/filtering with fixed pt arithmetic */
-               lp_build_sample_aos(&bld4, unit,
+               lp_build_sample_aos(&bld4, sampler_index,
                                    s4, t4, r4,
                                    lod_iparts, lod_fparts,
                                    ilevel0s, ilevel1s,
@@ -1683,7 +1700,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
             }
 
             else {
-               lp_build_sample_general(&bld4, unit,
+               lp_build_sample_general(&bld4, sampler_index,
                                        s4, t4, r4,
                                        lod_iparts, lod_fparts,
                                        ilevel0s, ilevel1s,
@@ -1702,7 +1719,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
       lp_build_sample_compare(&bld, coords, texel_out);
    }
 
-   if (static_state->target != PIPE_BUFFER) {
+   if (static_texture_state->target != PIPE_BUFFER) {
       apply_sampler_swizzle(&bld, texel_out);
    }
 
@@ -1721,7 +1738,7 @@ lp_build_sample_soa(struct gallivm_state *gallivm,
 
 void
 lp_build_size_query_soa(struct gallivm_state *gallivm,
-                        const struct lp_sampler_static_state *static_state,
+                        const struct lp_static_texture_state *static_state,
                         struct lp_sampler_dynamic_state *dynamic_state,
                         struct lp_type int_type,
                         unsigned unit,
index 16d2ed9e6f7ccd76c5a8f5def3ada27ad2fc2bc3..489884906cc042774420038c1907f0a2bac39db1 100644 (file)
@@ -173,7 +173,8 @@ struct lp_build_sampler_soa
                         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,
index fbeb805530c99075852eb07ec4d39217bde51bf3..0621fb482ce55e7fb72823108566c2372e620abd 100644 (file)
@@ -1331,7 +1331,8 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
                                   bld->bld_base.base.gallivm,
                                   bld->bld_base.base.type,
                                   FALSE,
-                                  unit, coords,
+                                  unit, unit,
+                                  coords,
                                   offsets,
                                   &derivs,
                                   lod_bias, explicit_lod,
@@ -1417,7 +1418,8 @@ emit_txf( struct lp_build_tgsi_soa_context *bld,
                                   bld->bld_base.base.gallivm,
                                   bld->bld_base.base.type,
                                   TRUE,
-                                  unit, coords,
+                                  unit, unit,
+                                  coords,
                                   offsets,
                                   &derivs,
                                   NULL, explicit_lod,
index b11a3d838e317003a102c752a363525196a7f70c..9ccb67bdd1f5cdead2fe8adbdee43be834370e66 100644 (file)
@@ -76,12 +76,12 @@ struct llvmpipe_context {
    struct pipe_framebuffer_state framebuffer;
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
-   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];
 
    struct pipe_viewport_state viewport;
    struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
    struct pipe_index_buffer index_buffer;
-   struct pipe_resource *mapped_vs_tex[PIPE_MAX_SAMPLERS];
+   struct pipe_resource *mapped_vs_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS];
 
    unsigned num_samplers[PIPE_SHADER_TYPES];
    unsigned num_sampler_views[PIPE_SHADER_TYPES];
index ea7c8054bfa8108712a511a6d0d62722ffdaa946..d0a791671e644dcaf1f108851ffa3d88427a8287 100644 (file)
@@ -45,7 +45,7 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
 {
    struct gallivm_state *gallivm = lp->gallivm;
    LLVMContextRef lc = gallivm->context;
-   LLVMTypeRef texture_type;
+   LLVMTypeRef texture_type, sampler_type;
 
    /* struct lp_jit_texture */
    {
@@ -61,11 +61,6 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
       elem_types[LP_JIT_TEXTURE_IMG_STRIDE] =
       elem_types[LP_JIT_TEXTURE_MIP_OFFSETS] =
          LLVMArrayType(LLVMInt32TypeInContext(lc), LP_MAX_TEXTURE_LEVELS);
-      elem_types[LP_JIT_TEXTURE_MIN_LOD] =
-      elem_types[LP_JIT_TEXTURE_MAX_LOD] =
-      elem_types[LP_JIT_TEXTURE_LOD_BIAS] = LLVMFloatTypeInContext(lc);
-      elem_types[LP_JIT_TEXTURE_BORDER_COLOR] = 
-         LLVMArrayType(LLVMFloatTypeInContext(lc), 4);
 
       texture_type = LLVMStructTypeInContext(lc, elem_types,
                                              Elements(elem_types), 0);
@@ -102,21 +97,41 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, mip_offsets,
                              gallivm->target, texture_type,
                              LP_JIT_TEXTURE_MIP_OFFSETS);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, min_lod,
+      LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
+                           gallivm->target, texture_type);
+   }
+
+   {
+   /* struct lp_jit_sampler */
+      LLVMTypeRef elem_types[LP_JIT_SAMPLER_NUM_FIELDS];
+      elem_types[LP_JIT_SAMPLER_MIN_LOD] =
+      elem_types[LP_JIT_SAMPLER_MAX_LOD] =
+      elem_types[LP_JIT_SAMPLER_LOD_BIAS] = LLVMFloatTypeInContext(lc);
+      elem_types[LP_JIT_SAMPLER_BORDER_COLOR] =
+         LLVMArrayType(LLVMFloatTypeInContext(lc), 4);
+
+      sampler_type = LLVMStructTypeInContext(lc, elem_types,
+                                             Elements(elem_types), 0);
+#if HAVE_LLVM < 0x0300
+      LLVMAddTypeName(gallivm->module, "texture", texture_type);
+
+      LLVMInvalidateStructLayout(gallivm->target, texture_type);
+#endif
+
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, min_lod,
                              gallivm->target, texture_type,
-                             LP_JIT_TEXTURE_MIN_LOD);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, max_lod,
+                             LP_JIT_SAMPLER_MIN_LOD);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, max_lod,
                              gallivm->target, texture_type,
-                             LP_JIT_TEXTURE_MAX_LOD);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, lod_bias,
+                             LP_JIT_SAMPLER_MAX_LOD);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, lod_bias,
                              gallivm->target, texture_type,
-                             LP_JIT_TEXTURE_LOD_BIAS);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, border_color,
+                             LP_JIT_SAMPLER_LOD_BIAS);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, border_color,
                              gallivm->target, texture_type,
-                             LP_JIT_TEXTURE_BORDER_COLOR);
-
-      LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
-                           gallivm->target, texture_type);
+                             LP_JIT_SAMPLER_BORDER_COLOR);
+      LP_CHECK_STRUCT_SIZE(struct lp_jit_sampler,
+                           gallivm->target, sampler_type);
    }
 
    /* struct lp_jit_context */
@@ -132,6 +147,8 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
       elem_types[LP_JIT_CTX_U8_BLEND_COLOR] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0);
       elem_types[LP_JIT_CTX_F_BLEND_COLOR] = LLVMPointerType(LLVMFloatTypeInContext(lc), 0);
       elem_types[LP_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type,
+                                                      PIPE_MAX_SHADER_SAMPLER_VIEWS);
+      elem_types[LP_JIT_CTX_SAMPLERS] = LLVMArrayType(sampler_type,
                                                       PIPE_MAX_SAMPLERS);
 
       context_type = LLVMStructTypeInContext(lc, elem_types,
@@ -164,6 +181,9 @@ lp_jit_create_types(struct lp_fragment_shader_variant *lp)
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
                              gallivm->target, context_type,
                              LP_JIT_CTX_TEXTURES);
+      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers,
+                             gallivm->target, context_type,
+                             LP_JIT_CTX_SAMPLERS);
       LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
                            gallivm->target, context_type);
 
index 5dc5bc4c4bf34b2d931737e5e26fd118940aa1f5..3057c0dc2b0c36b4cd111d0913de364d28d0a4a1 100644 (file)
@@ -58,7 +58,11 @@ struct lp_jit_texture
    uint32_t row_stride[LP_MAX_TEXTURE_LEVELS];
    uint32_t img_stride[LP_MAX_TEXTURE_LEVELS];
    uint32_t mip_offsets[LP_MAX_TEXTURE_LEVELS];
-   /* sampler state, actually */
+};
+
+
+struct lp_jit_sampler
+{
    float min_lod;
    float max_lod;
    float lod_bias;
@@ -76,14 +80,18 @@ enum {
    LP_JIT_TEXTURE_ROW_STRIDE,
    LP_JIT_TEXTURE_IMG_STRIDE,
    LP_JIT_TEXTURE_MIP_OFFSETS,
-   LP_JIT_TEXTURE_MIN_LOD,
-   LP_JIT_TEXTURE_MAX_LOD,
-   LP_JIT_TEXTURE_LOD_BIAS,
-   LP_JIT_TEXTURE_BORDER_COLOR,
    LP_JIT_TEXTURE_NUM_FIELDS  /* number of fields above */
 };
 
 
+enum {
+   LP_JIT_SAMPLER_MIN_LOD,
+   LP_JIT_SAMPLER_MAX_LOD,
+   LP_JIT_SAMPLER_LOD_BIAS,
+   LP_JIT_SAMPLER_BORDER_COLOR,
+   LP_JIT_SAMPLER_NUM_FIELDS  /* number of fields above */
+};
+
 
 /**
  * This structure is passed directly to the generated fragment shader.
@@ -107,7 +115,8 @@ struct lp_jit_context
    uint8_t *u8_blend_color;
    float *f_blend_color;
 
-   struct lp_jit_texture textures[PIPE_MAX_SAMPLERS];
+   struct lp_jit_texture textures[PIPE_MAX_SHADER_SAMPLER_VIEWS];
+   struct lp_jit_sampler samplers[PIPE_MAX_SAMPLERS];
 };
 
 
@@ -123,6 +132,7 @@ enum {
    LP_JIT_CTX_U8_BLEND_COLOR,
    LP_JIT_CTX_F_BLEND_COLOR,
    LP_JIT_CTX_TEXTURES,
+   LP_JIT_CTX_SAMPLERS,
    LP_JIT_CTX_COUNT
 };
 
@@ -148,6 +158,8 @@ enum {
 #define lp_jit_context_textures(_gallivm, _ptr) \
    lp_build_struct_get_ptr(_gallivm, _ptr, LP_JIT_CTX_TEXTURES, "textures")
 
+#define lp_jit_context_samplers(_gallivm, _ptr) \
+   lp_build_struct_get_ptr(_gallivm, _ptr, LP_JIT_CTX_SAMPLERS, "samplers")
 
 
 /**
index ffa0fe6eaa34e7613b2d1c0f771b2f9661124404..b0bc4a8132fe70724403135d938c9ea2dd056dc4 100644 (file)
@@ -668,9 +668,9 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
 
    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
 
-   assert(num <= PIPE_MAX_SAMPLERS);
+   assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
 
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+   for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
       struct pipe_sampler_view *view = i < num ? views[i] : NULL;
 
       if (view) {
@@ -780,13 +780,13 @@ lp_setup_set_fragment_sampler_state(struct lp_setup_context *setup,
       const struct pipe_sampler_state *sampler = i < num ? samplers[i] : NULL;
 
       if (sampler) {
-         struct lp_jit_texture *jit_tex;
-         jit_tex = &setup->fs.current.jit_context.textures[i];
+         struct lp_jit_sampler *jit_sam;
+         jit_sam = &setup->fs.current.jit_context.samplers[i];
 
-         jit_tex->min_lod = sampler->min_lod;
-         jit_tex->max_lod = sampler->max_lod;
-         jit_tex->lod_bias = sampler->lod_bias;
-         COPY_4V(jit_tex->border_color, sampler->border_color.f);
+         jit_sam->min_lod = sampler->min_lod;
+         jit_sam->max_lod = sampler->max_lod;
+         jit_sam->lod_bias = sampler->lod_bias;
+         COPY_4V(jit_sam->border_color, sampler->border_color.f);
       }
    }
 
index 4d20dd3846131dfa4a615a9c5341155b06917ec7..0e2de648a9198448566781ab008de6a5e36336c5 100644 (file)
@@ -123,7 +123,7 @@ struct lp_setup_context
    struct {
       const struct lp_rast_state *stored; /**< what's in the scene */
       struct lp_rast_state current;  /**< currently set state */
-      struct pipe_resource *current_tex[PIPE_MAX_SAMPLERS];
+      struct pipe_resource *current_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS];
    } fs;
 
    /** fragment shader constants */
index cf936d029b50d189cb74f2954101aac3207a3829..09f37e0ceaddb63d9f8be6d57a29764475724375 100644 (file)
@@ -1904,7 +1904,7 @@ generate_fragment(struct llvmpipe_context *lp,
    LLVMPositionBuilderAtEnd(builder, block);
 
    /* code generated texture sampling */
-   sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr);
+   sampler = lp_llvm_sampler_soa_create(key->state, context_ptr);
 
    zs_format_desc = util_format_description(key->zsbuf_format);
 
@@ -2113,32 +2113,39 @@ dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key)
    }
    debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask);
    for (i = 0; i < key->nr_samplers; ++i) {
+      const struct lp_static_sampler_state *sampler = &key->state[i].sampler_state;
       debug_printf("sampler[%u] = \n", i);
-      debug_printf("  .format = %s\n",
-                   util_format_name(key->sampler[i].format));
-      debug_printf("  .target = %s\n",
-                   util_dump_tex_target(key->sampler[i].target, TRUE));
-      debug_printf("  .pot = %u %u %u\n",
-                   key->sampler[i].pot_width,
-                   key->sampler[i].pot_height,
-                   key->sampler[i].pot_depth);
       debug_printf("  .wrap = %s %s %s\n",
-                   util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
-                   util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
-                   util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
+                   util_dump_tex_wrap(sampler->wrap_s, TRUE),
+                   util_dump_tex_wrap(sampler->wrap_t, TRUE),
+                   util_dump_tex_wrap(sampler->wrap_r, TRUE));
       debug_printf("  .min_img_filter = %s\n",
-                   util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
+                   util_dump_tex_filter(sampler->min_img_filter, TRUE));
       debug_printf("  .min_mip_filter = %s\n",
-                   util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
+                   util_dump_tex_mipfilter(sampler->min_mip_filter, TRUE));
       debug_printf("  .mag_img_filter = %s\n",
-                   util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
-      if (key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE)
-         debug_printf("  .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE));
-      debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
-      debug_printf("  .min_max_lod_equal = %u\n", key->sampler[i].min_max_lod_equal);
-      debug_printf("  .lod_bias_non_zero = %u\n", key->sampler[i].lod_bias_non_zero);
-      debug_printf("  .apply_min_lod = %u\n", key->sampler[i].apply_min_lod);
-      debug_printf("  .apply_max_lod = %u\n", key->sampler[i].apply_max_lod);
+                   util_dump_tex_filter(sampler->mag_img_filter, TRUE));
+      if (sampler->compare_mode != PIPE_TEX_COMPARE_NONE)
+         debug_printf("  .compare_func = %s\n", util_dump_func(sampler->compare_func, TRUE));
+      debug_printf("  .normalized_coords = %u\n", sampler->normalized_coords);
+      debug_printf("  .min_max_lod_equal = %u\n", sampler->min_max_lod_equal);
+      debug_printf("  .lod_bias_non_zero = %u\n", sampler->lod_bias_non_zero);
+      debug_printf("  .apply_min_lod = %u\n", sampler->apply_min_lod);
+      debug_printf("  .apply_max_lod = %u\n", sampler->apply_max_lod);
+   }
+   for (i = 0; i < key->nr_sampler_views; ++i) {
+      const struct lp_static_texture_state *texture = &key->state[i].texture_state;
+      debug_printf("texture[%u] = \n", i);
+      debug_printf("  .format = %s\n",
+                   util_format_name(texture->format));
+      debug_printf("  .target = %s\n",
+                   util_dump_tex_target(texture->target, TRUE));
+      debug_printf("  .level_zero_only = %u\n",
+                   texture->level_zero_only);
+      debug_printf("  .pot = %u %u %u\n",
+                   texture->pot_width,
+                   texture->pot_height,
+                   texture->pot_depth);
    }
 }
 
@@ -2251,6 +2258,7 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    struct lp_fragment_shader *shader;
    int nr_samplers;
+   int nr_sampler_views;
    int i;
 
    shader = CALLOC_STRUCT(lp_fragment_shader);
@@ -2274,9 +2282,10 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
    }
 
    nr_samplers = shader->info.base.file_max[TGSI_FILE_SAMPLER] + 1;
+   nr_sampler_views = shader->info.base.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
 
    shader->variant_key_size = Offset(struct lp_fragment_shader_variant_key,
-                                    sampler[nr_samplers]);
+                                     state[MAX2(nr_samplers, nr_sampler_views)]);
 
    for (i = 0; i < shader->info.base.num_inputs; i++) {
       shader->inputs[i].usage_mask = shader->info.base.input_usage_mask[i];
@@ -2605,9 +2614,32 @@ make_variant_key(struct llvmpipe_context *lp,
 
    for(i = 0; i < key->nr_samplers; ++i) {
       if(shader->info.base.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) {
-         lp_sampler_static_state(&key->sampler[i],
-                                lp->sampler_views[PIPE_SHADER_FRAGMENT][i],
-                                lp->samplers[PIPE_SHADER_FRAGMENT][i]);
+         lp_sampler_static_sampler_state(&key->state[i].sampler_state,
+                                         lp->samplers[PIPE_SHADER_FRAGMENT][i]);
+      }
+   }
+
+   /*
+    * XXX If TGSI_FILE_SAMPLER_VIEW exists assume all texture opcodes
+    * are dx10-style? Can't really have mixed opcodes, at least not
+    * if we want to skip the holes here (without rescanning tgsi).
+    */
+   if (shader->info.base.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) {
+      key->nr_sampler_views = shader->info.base.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
+      for(i = 0; i < key->nr_sampler_views; ++i) {
+         if(shader->info.base.file_mask[TGSI_FILE_SAMPLER_VIEW] & (1 << i)) {
+            lp_sampler_static_texture_state(&key->state[i].texture_state,
+                                            lp->sampler_views[PIPE_SHADER_FRAGMENT][i]);
+         }
+      }
+   }
+   else {
+      key->nr_sampler_views = key->nr_samplers;
+      for(i = 0; i < key->nr_sampler_views; ++i) {
+         if(shader->info.base.file_mask[TGSI_FILE_SAMPLER] & (1 << i)) {
+            lp_sampler_static_texture_state(&key->state[i].texture_state,
+                                            lp->sampler_views[PIPE_SHADER_FRAGMENT][i]);
+         }
       }
    }
 }
index 306f5f9669ae8b1274196ae5611db8d62558c450..c8dc1c33cfed478788c3dd00c5f2d5c87e76aeff 100644 (file)
@@ -47,6 +47,18 @@ struct lp_fragment_shader;
 #define RAST_EDGE_TEST 1
 
 
+struct lp_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 lp_fragment_shader_variant_key
 {
    struct pipe_depth_state depth;
@@ -59,14 +71,15 @@ struct lp_fragment_shader_variant_key
    } alpha;
 
    unsigned nr_cbufs:8;
-   unsigned nr_samplers:8;     /* actually derivable from just the shader */
+   unsigned nr_samplers:8;      /* actually derivable from just the shader */
+   unsigned nr_sampler_views:8; /* actually derivable from just the shader */
    unsigned flatshade:1;
    unsigned occlusion_count:1;
 
    enum pipe_format zsbuf_format;
    enum pipe_format cbuf_format[PIPE_MAX_COLOR_BUFS];
 
-   struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS];
+   struct lp_sampler_static_state state[PIPE_MAX_SHADER_SAMPLER_VIEWS];
 };
 
 
index e7429cc35a1d78c1124d5fc64226b907eef124f8..9736ca94905fddbfd3e05ed80f92e890f7099c4e 100644 (file)
@@ -143,7 +143,7 @@ llvmpipe_set_sampler_views(struct pipe_context *pipe,
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
    uint i;
 
-   assert(num <= PIPE_MAX_SAMPLERS);
+   assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
 
    assert(shader < PIPE_SHADER_TYPES);
    assert(start + num <= Elements(llvmpipe->sampler_views[shader]));
@@ -258,11 +258,11 @@ llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
    uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
    const void *addr;
 
-   assert(num <= PIPE_MAX_SAMPLERS);
+   assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);
    if (!num)
       return;
 
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+   for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
       struct pipe_sampler_view *view = i < num ? views[i] : NULL;
 
       if (view) {
index 0bd5c4aa050d2151fdb669d4c6537be0bb687f1e..25125a0768b7f4459034a479ff831c4e89cc5e9f 100644 (file)
@@ -49,6 +49,7 @@
 #include "gallivm/lp_bld_tgsi.h"
 #include "lp_jit.h"
 #include "lp_tex_sample.h"
+#include "lp_state_fs.h"
 #include "lp_debug.h"
 
 
@@ -103,7 +104,7 @@ lp_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
    LLVMValueRef ptr;
    LLVMValueRef res;
 
-   assert(unit < PIPE_MAX_SAMPLERS);
+   assert(unit < PIPE_MAX_SHADER_SAMPLER_VIEWS);
 
    /* context[0] */
    indices[0] = lp_build_const_int32(gallivm, 0);
@@ -155,10 +156,69 @@ LP_LLVM_TEXTURE_MEMBER(base_ptr,   LP_JIT_TEXTURE_BASE, TRUE)
 LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE)
 LP_LLVM_TEXTURE_MEMBER(img_stride, LP_JIT_TEXTURE_IMG_STRIDE, FALSE)
 LP_LLVM_TEXTURE_MEMBER(mip_offsets, LP_JIT_TEXTURE_MIP_OFFSETS, FALSE)
-LP_LLVM_TEXTURE_MEMBER(min_lod,    LP_JIT_TEXTURE_MIN_LOD, TRUE)
-LP_LLVM_TEXTURE_MEMBER(max_lod,    LP_JIT_TEXTURE_MAX_LOD, TRUE)
-LP_LLVM_TEXTURE_MEMBER(lod_bias,   LP_JIT_TEXTURE_LOD_BIAS, TRUE)
-LP_LLVM_TEXTURE_MEMBER(border_color, LP_JIT_TEXTURE_BORDER_COLOR, FALSE)
+
+
+/**
+ * Fetch the specified member of the lp_jit_sampler structure.
+ * \param emit_load  if TRUE, emit the LLVM load instruction to actually
+ *                   fetch the field's value.  Otherwise, just emit the
+ *                   GEP code to address the field.
+ *
+ * @sa http://llvm.org/docs/GetElementPtr.html
+ */
+static LLVMValueRef
+lp_llvm_sampler_member(const struct lp_sampler_dynamic_state *base,
+                       struct gallivm_state *gallivm,
+                       unsigned unit,
+                       unsigned member_index,
+                       const char *member_name,
+                       boolean emit_load)
+{
+   struct llvmpipe_sampler_dynamic_state *state =
+      (struct llvmpipe_sampler_dynamic_state *)base;
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMValueRef indices[4];
+   LLVMValueRef ptr;
+   LLVMValueRef res;
+
+   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, LP_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;
+}
+
+
+#define LP_LLVM_SAMPLER_MEMBER(_name, _index, _emit_load)  \
+   static LLVMValueRef \
+   lp_llvm_sampler_##_name( const struct lp_sampler_dynamic_state *base, \
+                            struct gallivm_state *gallivm, \
+                            unsigned unit) \
+   { \
+      return lp_llvm_sampler_member(base, gallivm, unit, _index, #_name, _emit_load ); \
+   }
+
+
+LP_LLVM_SAMPLER_MEMBER(min_lod,    LP_JIT_SAMPLER_MIN_LOD, TRUE)
+LP_LLVM_SAMPLER_MEMBER(max_lod,    LP_JIT_SAMPLER_MAX_LOD, TRUE)
+LP_LLVM_SAMPLER_MEMBER(lod_bias,   LP_JIT_SAMPLER_LOD_BIAS, TRUE)
+LP_LLVM_SAMPLER_MEMBER(border_color, LP_JIT_SAMPLER_BORDER_COLOR, FALSE)
 
 
 static void
@@ -177,7 +237,8 @@ lp_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,
@@ -187,7 +248,8 @@ lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
 {
    struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
 
-   assert(unit < PIPE_MAX_SAMPLERS);
+   assert(sampler_index < PIPE_MAX_SAMPLERS);
+   assert(texture_index < PIPE_MAX_SHADER_SAMPLER_VIEWS);
    
    if (LP_PERF & PERF_NO_TEX) {
       lp_build_sample_nop(gallivm, type, coords, texel);
@@ -195,11 +257,13 @@ lp_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
    }
 
    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,
@@ -221,14 +285,14 @@ lp_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
    struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
 
    assert(unit < PIPE_MAX_SAMPLERS);
-   
+
    lp_build_size_query_soa(gallivm,
-                          &sampler->dynamic_state.static_state[unit],
-                          &sampler->dynamic_state.base,
+                           &sampler->dynamic_state.static_state[unit].texture_state,
+                           &sampler->dynamic_state.base,
                            type,
-                          unit,
-                          explicit_lod,
-                          sizes_out);
+                           unit,
+                           explicit_lod,
+                           sizes_out);
 }
 
 
@@ -254,10 +318,10 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
    sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride;
    sampler->dynamic_state.base.img_stride = lp_llvm_texture_img_stride;
    sampler->dynamic_state.base.mip_offsets = lp_llvm_texture_mip_offsets;
-   sampler->dynamic_state.base.min_lod = lp_llvm_texture_min_lod;
-   sampler->dynamic_state.base.max_lod = lp_llvm_texture_max_lod;
-   sampler->dynamic_state.base.lod_bias = lp_llvm_texture_lod_bias;
-   sampler->dynamic_state.base.border_color = lp_llvm_texture_border_color;
+   sampler->dynamic_state.base.min_lod = lp_llvm_sampler_min_lod;
+   sampler->dynamic_state.base.max_lod = lp_llvm_sampler_max_lod;
+   sampler->dynamic_state.base.lod_bias = lp_llvm_sampler_lod_bias;
+   sampler->dynamic_state.base.border_color = lp_llvm_sampler_border_color;
 
    sampler->dynamic_state.static_state = static_state;
    sampler->dynamic_state.context_ptr = context_ptr;