[Mesa-dev] [PATCH] gallivm: split sampler and texture state

Brian Paul brianp at vmware.com
Fri Jan 25 13:07:10 PST 2013


On 01/24/2013 07:48 PM, sroland at vmware.com wrote:
> From: Roland Scheidegger<sroland at vmware.com>
>
> Split the sampler interface to use separate sampler and texture (sampler_view)
> state. This is needed to support dx10-style sampling instructions.
> This is not quite complete since both draw/llvmpipe don't really track
> textures/samplers independently yet, as well as the gallivm code not quite
> using the right sampler or texture index respectively (but it should work
> for the sampling codes used by opengl).
> We are however losing some optimizations in the process, apply_max_lod will
> no longer work, and we potentially could end up with more (unnecessary)
> recompiles (if switching textures with/without mipmaps only so it shouldn't
> be too bad).
>
> v2: don't use different callback structs for sampler/sampler view functions
> (which just complicates things), fix up sampling code to actually use the
> right texture or sampler index, and similar for llvmpipe/draw actually
> distinguish between samplers and sampler views.


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

Reviewed-by: Brian Paul <brianp at vmware.com>

Nice work!


> ---
>   src/gallium/auxiliary/draw/draw_llvm.c            |  129 +++++++++-----
>   src/gallium/auxiliary/draw/draw_llvm.h            |   66 ++++++--
>   src/gallium/auxiliary/draw/draw_llvm_sample.c     |   88 ++++++++--
>   src/gallium/auxiliary/draw/draw_private.h         |    2 +-
>   src/gallium/auxiliary/gallivm/lp_bld_sample.c     |  108 +++++++-----
>   src/gallium/auxiliary/gallivm/lp_bld_sample.h     |   66 ++++++--
>   src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c |  104 ++++++------
>   src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c |  187 ++++++++++++---------
>   src/gallium/auxiliary/gallivm/lp_bld_tgsi.h       |    3 +-
>   src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c   |    6 +-
>   src/gallium/drivers/llvmpipe/lp_jit.c             |   54 ++++--
>   src/gallium/drivers/llvmpipe/lp_jit.h             |   24 ++-
>   src/gallium/drivers/llvmpipe/lp_setup.c           |   12 +-
>   src/gallium/drivers/llvmpipe/lp_state_fs.c        |   84 ++++++---
>   src/gallium/drivers/llvmpipe/lp_state_fs.h        |   17 +-
>   src/gallium/drivers/llvmpipe/lp_state_setup.c     |   16 +-
>   src/gallium/drivers/llvmpipe/lp_tex_sample.c      |  102 ++++++++---
>   17 files changed, 711 insertions(+), 357 deletions(-)
>
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
> index a3a3bbf..9e5ff1c 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm.c
> @@ -85,11 +85,6 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name)
>      elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] =
>      elem_types[DRAW_JIT_TEXTURE_MIP_OFFSETS] =
>         LLVMArrayType(int32_type, PIPE_MAX_TEXTURE_LEVELS);
> -   elem_types[DRAW_JIT_TEXTURE_MIN_LOD] =
> -   elem_types[DRAW_JIT_TEXTURE_MAX_LOD] =
> -   elem_types[DRAW_JIT_TEXTURE_LOD_BIAS] = LLVMFloatTypeInContext(gallivm->context);
> -   elem_types[DRAW_JIT_TEXTURE_BORDER_COLOR] =
> -      LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);
>
>      texture_type = LLVMStructTypeInContext(gallivm->context, elem_types,
>                                             Elements(elem_types), 0);
> @@ -130,18 +125,6 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name)
>      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, mip_offsets,
>                             target, texture_type,
>                             DRAW_JIT_TEXTURE_MIP_OFFSETS);
> -   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, min_lod,
> -                          target, texture_type,
> -                          DRAW_JIT_TEXTURE_MIN_LOD);
> -   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, max_lod,
> -                          target, texture_type,
> -                          DRAW_JIT_TEXTURE_MAX_LOD);
> -   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, lod_bias,
> -                          target, texture_type,
> -                          DRAW_JIT_TEXTURE_LOD_BIAS);
> -   LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, border_color,
> -                          target, texture_type,
> -                          DRAW_JIT_TEXTURE_BORDER_COLOR);
>
>      LP_CHECK_STRUCT_SIZE(struct draw_jit_texture, target, texture_type);
>
> @@ -150,15 +133,63 @@ create_jit_texture_type(struct gallivm_state *gallivm, const char *struct_name)
>
>
>   /**
> + * Create LLVM type for struct draw_jit_sampler
> + */
> +static LLVMTypeRef
> +create_jit_sampler_type(struct gallivm_state *gallivm, const char *struct_name)
> +{
> +   LLVMTargetDataRef target = gallivm->target;
> +   LLVMTypeRef sampler_type;
> +   LLVMTypeRef elem_types[DRAW_JIT_SAMPLER_NUM_FIELDS];
> +
> +   elem_types[DRAW_JIT_SAMPLER_MIN_LOD] =
> +   elem_types[DRAW_JIT_SAMPLER_MAX_LOD] =
> +   elem_types[DRAW_JIT_SAMPLER_LOD_BIAS] = LLVMFloatTypeInContext(gallivm->context);
> +   elem_types[DRAW_JIT_SAMPLER_BORDER_COLOR] =
> +      LLVMArrayType(LLVMFloatTypeInContext(gallivm->context), 4);
> +
> +   sampler_type = LLVMStructTypeInContext(gallivm->context, elem_types,
> +                                          Elements(elem_types), 0);
> +
> +#if HAVE_LLVM<  0x0300
> +   LLVMAddTypeName(gallivm->module, struct_name, sampler_type);
> +
> +   /* Make sure the target's struct layout cache doesn't return
> +    * stale/invalid data.
> +    */
> +   LLVMInvalidateStructLayout(gallivm->target, sampler_type);
> +#endif
> +
> +   LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, min_lod,
> +                          target, sampler_type,
> +                          DRAW_JIT_SAMPLER_MIN_LOD);
> +   LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, max_lod,
> +                          target, sampler_type,
> +                          DRAW_JIT_SAMPLER_MAX_LOD);
> +   LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, lod_bias,
> +                          target, sampler_type,
> +                          DRAW_JIT_SAMPLER_LOD_BIAS);
> +   LP_CHECK_MEMBER_OFFSET(struct draw_jit_sampler, border_color,
> +                          target, sampler_type,
> +                          DRAW_JIT_SAMPLER_BORDER_COLOR);
> +
> +   LP_CHECK_STRUCT_SIZE(struct draw_jit_sampler, target, sampler_type);
> +
> +   return sampler_type;
> +}
> +
> +
> +/**
>    * Create LLVM type for struct draw_jit_texture
>    */
>   static LLVMTypeRef
>   create_jit_context_type(struct gallivm_state *gallivm,

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


> -                        LLVMTypeRef texture_type, const char *struct_name)
> +                        LLVMTypeRef texture_type, LLVMTypeRef sampler_type,
> +                        const char *struct_name)
>   {
>      LLVMTargetDataRef target = gallivm->target;
>      LLVMTypeRef float_type = LLVMFloatTypeInContext(gallivm->context);
> -   LLVMTypeRef elem_types[5];
> +   LLVMTypeRef elem_types[6];
>      LLVMTypeRef context_type;
>
>      elem_types[0] = LLVMArrayType(LLVMPointerType(float_type, 0), /* vs_constants */
> @@ -168,7 +199,9 @@ create_jit_context_type(struct gallivm_state *gallivm,
>                                                    DRAW_TOTAL_CLIP_PLANES), 0);
>      elem_types[3] = LLVMPointerType(float_type, 0); /* viewport */
>      elem_types[4] = LLVMArrayType(texture_type,
> -                                 PIPE_MAX_SAMPLERS); /* textures */
> +                                 PIPE_MAX_SHADER_SAMPLER_VIEWS); /* textures */
> +   elem_types[5] = LLVMArrayType(sampler_type,
> +                                 PIPE_MAX_SAMPLERS); /* samplers */
>      context_type = LLVMStructTypeInContext(gallivm->context, elem_types,
>                                             Elements(elem_types), 0);
>   #if HAVE_LLVM<  0x0300
> @@ -183,9 +216,14 @@ create_jit_context_type(struct gallivm_state *gallivm,
>                             target, context_type, 1);
>      LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, planes,
>                             target, context_type, 2);
> +   LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, viewport,
> +                          target, context_type, 3);
>      LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures,
>                             target, context_type,
>                             DRAW_JIT_CTX_TEXTURES);
> +   LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, samplers,
> +                          target, context_type,
> +                          DRAW_JIT_CTX_SAMPLERS);
>      LP_CHECK_STRUCT_SIZE(struct draw_jit_context,
>                           target, context_type);
>
> @@ -291,11 +329,13 @@ static void
>   create_jit_types(struct draw_llvm_variant *variant)
>   {
>      struct gallivm_state *gallivm = variant->gallivm;
> -   LLVMTypeRef texture_type, context_type, buffer_type, vb_type;
> +   LLVMTypeRef texture_type, sampler_type, context_type, buffer_type, vb_type;
>
>      texture_type = create_jit_texture_type(gallivm, "texture");
> +   sampler_type = create_jit_sampler_type(gallivm, "sampler");
>
> -   context_type = create_jit_context_type(gallivm, texture_type, "draw_jit_context");
> +   context_type = create_jit_context_type(gallivm, texture_type, sampler_type,
> +                                          "draw_jit_context");
>      variant->context_ptr_type = LLVMPointerType(context_type, 0);
>
>      buffer_type = LLVMPointerType(LLVMIntTypeInContext(gallivm->context, 8), 0);
> @@ -1182,8 +1222,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
>
>      /* code generated texture sampling */
>      sampler = draw_llvm_sampler_soa_create(
> -      draw_llvm_variant_key_samplers(&variant->key),
> -      context_ptr);
> +                draw_llvm_variant_key_samplers(&variant->key),
> +                context_ptr);
>
>      if (elts) {
>         start = zero;
> @@ -1319,7 +1359,7 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
>   {
>      unsigned i;
>      struct draw_llvm_variant_key *key;
> -   struct lp_sampler_static_state *sampler;
> +   struct draw_sampler_static_state *draw_sampler;
>
>      key = (struct draw_llvm_variant_key *)store;
>
> @@ -1345,19 +1385,29 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store)
>       * sampler array.
>       */
>      key->nr_samplers = llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER] + 1;
> +   if (llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] != -1) {
> +      key->nr_sampler_views =
> +         llvm->draw->vs.vertex_shader->info.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
> +   }
> +   else {
> +      key->nr_sampler_views = key->nr_samplers;
> +   }
>
> -   sampler = draw_llvm_variant_key_samplers(key);
> +   draw_sampler = draw_llvm_variant_key_samplers(key);
>
>      memcpy(key->vertex_element,
>             llvm->draw->pt.vertex_element,
>             sizeof(struct pipe_vertex_element) * key->nr_vertex_elements);
> -
> -   memset(sampler, 0, key->nr_samplers * sizeof *sampler);
> +
> +   memset(draw_sampler, 0, MAX2(key->nr_samplers, key->nr_sampler_views) * sizeof *draw_sampler);
>
>      for (i = 0 ; i<  key->nr_samplers; i++) {
> -      lp_sampler_static_state(&sampler[i],
> -			      llvm->draw->sampler_views[PIPE_SHADER_VERTEX][i],
> -			      llvm->draw->samplers[PIPE_SHADER_VERTEX][i]);
> +      lp_sampler_static_sampler_state(&draw_sampler[i].sampler_state,
> +                                      llvm->draw->samplers[PIPE_SHADER_VERTEX][i]);
> +   }
> +   for (i = 0 ; i<  key->nr_sampler_views; i++) {
> +      lp_sampler_static_texture_state(&draw_sampler[i].texture_state,
> +                                      llvm->draw->sampler_views[PIPE_SHADER_VERTEX][i]);
>      }
>
>      return key;
> @@ -1368,7 +1418,7 @@ void
>   draw_llvm_dump_variant_key(struct draw_llvm_variant_key *key)
>   {
>      unsigned i;
> -   struct lp_sampler_static_state *sampler = draw_llvm_variant_key_samplers(key);
> +   struct draw_sampler_static_state *sampler = draw_llvm_variant_key_samplers(key);
>
>      debug_printf("clamp_vertex_color = %u\n", key->clamp_vertex_color);
>      debug_printf("clip_xy = %u\n", key->clip_xy);
> @@ -1386,8 +1436,8 @@ draw_llvm_dump_variant_key(struct draw_llvm_variant_key *key)
>         debug_printf("vertex_element[%i].src_format = %s\n", i, util_format_name(key->vertex_element[i].src_format));
>      }
>
> -   for (i = 0 ; i<  key->nr_samplers; i++) {
> -      debug_printf("sampler[%i].src_format = %s\n", i, util_format_name(sampler[i].format));
> +   for (i = 0 ; i<  key->nr_sampler_views; i++) {
> +      debug_printf("sampler[%i].src_format = %s\n", i, util_format_name(sampler[i].texture_state.format));
>      }
>   }
>
> @@ -1428,17 +1478,16 @@ void
>   draw_llvm_set_sampler_state(struct draw_context *draw)
>   {
>      unsigned i;
> -
>      for (i = 0; i<  draw->num_samplers[PIPE_SHADER_VERTEX]; i++) {
> -      struct draw_jit_texture *jit_tex =&draw->llvm->jit_context.textures[i];
> +      struct draw_jit_sampler *jit_sam =&draw->llvm->jit_context.samplers[i];
>
>         if (draw->samplers[i]) {
>            const struct pipe_sampler_state *s
>               = draw->samplers[PIPE_SHADER_VERTEX][i];
> -         jit_tex->min_lod = s->min_lod;
> -         jit_tex->max_lod = s->max_lod;
> -         jit_tex->lod_bias = s->lod_bias;
> -         COPY_4V(jit_tex->border_color, s->border_color.f);
> +         jit_sam->min_lod = s->min_lod;
> +         jit_sam->max_lod = s->max_lod;
> +         jit_sam->lod_bias = s->lod_bias;
> +         COPY_4V(jit_sam->border_color, s->border_color.f);
>         }
>      }
>   }
> diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
> index 892973c..a664857 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm.h
> +++ b/src/gallium/auxiliary/draw/draw_llvm.h
> @@ -52,12 +52,30 @@ struct draw_jit_texture
>      uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];
>      uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];
>      uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];
> +};
> +
> +
> +struct draw_sampler_static_state
> +{
> +   /*
> +    * These attributes are effectively interleaved for more sane key handling.
> +    * However, there might be lots of null space if the amount of samplers and
> +    * textures isn't the same.
> +    */
> +   struct lp_static_sampler_state sampler_state;
> +   struct lp_static_texture_state texture_state;
> +};
> +
> +
> +struct draw_jit_sampler
> +{
>      float min_lod;
>      float max_lod;
>      float lod_bias;
>      float border_color[4];
>   };
>
> +
>   enum {
>      DRAW_JIT_TEXTURE_WIDTH = 0,
>      DRAW_JIT_TEXTURE_HEIGHT,
> @@ -68,13 +86,19 @@ enum {
>      DRAW_JIT_TEXTURE_ROW_STRIDE,
>      DRAW_JIT_TEXTURE_IMG_STRIDE,
>      DRAW_JIT_TEXTURE_MIP_OFFSETS,
> -   DRAW_JIT_TEXTURE_MIN_LOD,
> -   DRAW_JIT_TEXTURE_MAX_LOD,
> -   DRAW_JIT_TEXTURE_LOD_BIAS,
> -   DRAW_JIT_TEXTURE_BORDER_COLOR,
>      DRAW_JIT_TEXTURE_NUM_FIELDS  /* number of fields above */
>   };
>
> +
> +enum {
> +   DRAW_JIT_SAMPLER_MIN_LOD,
> +   DRAW_JIT_SAMPLER_MAX_LOD,
> +   DRAW_JIT_SAMPLER_LOD_BIAS,
> +   DRAW_JIT_SAMPLER_BORDER_COLOR,
> +   DRAW_JIT_SAMPLER_NUM_FIELDS  /* number of fields above */
> +};
> +
> +
>   enum {
>      DRAW_JIT_VERTEX_VERTEX_ID = 0,
>      DRAW_JIT_VERTEX_CLIP,
> @@ -82,6 +106,9 @@ enum {
>      DRAW_JIT_VERTEX_DATA
>   };
>
> +#define DRAW_JIT_CTX_TEXTURES 4
> +#define DRAW_JIT_CTX_SAMPLERS 5
> +
>   /**
>    * This structure is passed directly to the generated vertex shader.
>    *
> @@ -100,7 +127,8 @@ struct draw_jit_context
>      float (*planes) [DRAW_TOTAL_CLIP_PLANES][4];
>      float *viewport;
>
> -   struct draw_jit_texture textures[PIPE_MAX_SAMPLERS];
> +   struct draw_jit_texture textures[PIPE_MAX_SHADER_SAMPLER_VIEWS];
> +   struct draw_jit_sampler samplers[PIPE_MAX_SAMPLERS];
>   };
>
>
> @@ -117,10 +145,14 @@ struct draw_jit_context
>      lp_build_struct_get(_gallivm, _ptr, 3, "viewport")
>
>   #define DRAW_JIT_CTX_TEXTURES 4
> +#define DRAW_JIT_CTX_SAMPLERS 5
>
>   #define draw_jit_context_textures(_gallivm, _ptr) \
>      lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_CTX_TEXTURES, "textures")
>
> +#define draw_jit_context_samplers(_gallivm, _ptr) \
> +   lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_CTX_SAMPLERS, "samplers")
> +
>   #define draw_jit_header_id(_gallivm, _ptr)              \
>      lp_build_struct_get_ptr(_gallivm, _ptr, DRAW_JIT_VERTEX_VERTEX_ID, "id")
>
> @@ -166,6 +198,7 @@ struct draw_llvm_variant_key
>   {
>      unsigned nr_vertex_elements:8;
>      unsigned nr_samplers:8;
> +   unsigned nr_sampler_views:8;
>      unsigned clamp_vertex_color:1;
>      unsigned clip_xy:1;
>      unsigned clip_z:1;
> @@ -174,7 +207,7 @@ struct draw_llvm_variant_key
>      unsigned bypass_viewport:1;
>      unsigned need_edgeflags:1;
>      unsigned ucp_enable:PIPE_MAX_CLIP_PLANES;
> -   unsigned pad:9-PIPE_MAX_CLIP_PLANES;
> +   unsigned pad:33-PIPE_MAX_CLIP_PLANES;
>
>      /* Variable number of vertex elements:
>       */
> @@ -182,34 +215,33 @@ struct draw_llvm_variant_key
>
>      /* Followed by variable number of samplers:
>       */
> -/*   struct lp_sampler_static_state sampler; */
> +/*   struct draw_sampler_static_state sampler; */
>   };
>
>   #define DRAW_LLVM_MAX_VARIANT_KEY_SIZE \
>      (sizeof(struct draw_llvm_variant_key) +	\
> -    PIPE_MAX_SAMPLERS * sizeof(struct lp_sampler_static_state) +	\
> +    PIPE_MAX_SHADER_SAMPLER_VIEWS * sizeof(struct draw_sampler_static_state) +	\
>       (PIPE_MAX_ATTRIBS-1) * sizeof(struct pipe_vertex_element))
>
>
>   static INLINE size_t
>   draw_llvm_variant_key_size(unsigned nr_vertex_elements,
> -			   unsigned nr_samplers)
> +                           unsigned nr_samplers)
>   {
>      return (sizeof(struct draw_llvm_variant_key) +
> -	   nr_samplers * sizeof(struct lp_sampler_static_state) +
> -	   (nr_vertex_elements - 1) * sizeof(struct pipe_vertex_element));
> +           nr_samplers * sizeof(struct draw_sampler_static_state) +
> +           (nr_vertex_elements - 1) * sizeof(struct pipe_vertex_element));
>   }
>
>
> -static INLINE struct lp_sampler_static_state *
> +static INLINE struct draw_sampler_static_state *
>   draw_llvm_variant_key_samplers(struct draw_llvm_variant_key *key)
>   {
> -   return (struct lp_sampler_static_state *)
> +   return (struct draw_sampler_static_state *)
>         &key->vertex_element[key->nr_vertex_elements];
>   }
>
>
> -
>   struct draw_llvm_variant_list_item
>   {
>      struct draw_llvm_variant *base;
> @@ -275,8 +307,8 @@ draw_llvm_destroy(struct draw_llvm *llvm);
>
>   struct draw_llvm_variant *
>   draw_llvm_create_variant(struct draw_llvm *llvm,
> -			 unsigned num_vertex_header_attribs,
> -			 const struct draw_llvm_variant_key *key);
> +                         unsigned num_vertex_header_attribs,
> +                         const struct draw_llvm_variant_key *key);
>
>   void
>   draw_llvm_destroy_variant(struct draw_llvm_variant *variant);
> @@ -288,7 +320,7 @@ void
>   draw_llvm_dump_variant_key(struct draw_llvm_variant_key *key);
>
>   struct lp_build_sampler_soa *
> -draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
> +draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_state,
>                                LLVMValueRef context_ptr);
>
>   void
> diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> index 67d4e93..593d641 100644
> --- a/src/gallium/auxiliary/draw/draw_llvm_sample.c
> +++ b/src/gallium/auxiliary/draw/draw_llvm_sample.c
> @@ -58,7 +58,7 @@ struct draw_llvm_sampler_dynamic_state
>   {
>      struct lp_sampler_dynamic_state base;
>
> -   const struct lp_sampler_static_state *static_state;
> +   const struct draw_sampler_static_state *static_state;
>
>      LLVMValueRef context_ptr;
>   };
> @@ -98,7 +98,7 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
>      LLVMValueRef ptr;
>      LLVMValueRef res;
>
> -   debug_assert(unit<  PIPE_MAX_SAMPLERS);
> +   debug_assert(unit<  PIPE_MAX_SHADER_SAMPLER_VIEWS);
>
>      /* context[0] */
>      indices[0] = lp_build_const_int32(gallivm, 0);
> @@ -122,6 +122,45 @@ draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
>   }
>
>
> +static LLVMValueRef
> +draw_llvm_sampler_member(const struct lp_sampler_dynamic_state *base,

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


> +                         struct gallivm_state *gallivm,
> +                         unsigned unit,
> +                         unsigned member_index,
> +                         const char *member_name,
> +                         boolean emit_load)
> +{
> +   LLVMBuilderRef builder = gallivm->builder;
> +   struct draw_llvm_sampler_dynamic_state *state =
> +      (struct draw_llvm_sampler_dynamic_state *)base;
> +   LLVMValueRef indices[4];
> +   LLVMValueRef ptr;
> +   LLVMValueRef res;
> +
> +   debug_assert(unit<  PIPE_MAX_SAMPLERS);
> +
> +   /* context[0] */
> +   indices[0] = lp_build_const_int32(gallivm, 0);
> +   /* context[0].samplers */
> +   indices[1] = lp_build_const_int32(gallivm, DRAW_JIT_CTX_SAMPLERS);
> +   /* context[0].samplers[unit] */
> +   indices[2] = lp_build_const_int32(gallivm, unit);
> +   /* context[0].samplers[unit].member */
> +   indices[3] = lp_build_const_int32(gallivm, member_index);
> +
> +   ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
> +
> +   if (emit_load)
> +      res = LLVMBuildLoad(builder, ptr, "");
> +   else
> +      res = ptr;
> +
> +   lp_build_name(res, "context.sampler%u.%s", unit, member_name);
> +
> +   return res;
> +}
> +
> +
>   /**
>    * Helper macro to instantiate the functions that generate the code to
>    * fetch the members of lp_jit_texture to fulfill the sampler code
> @@ -150,10 +189,23 @@ DRAW_LLVM_TEXTURE_MEMBER(base_ptr,   DRAW_JIT_TEXTURE_BASE, TRUE)
>   DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE)
>   DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE)
>   DRAW_LLVM_TEXTURE_MEMBER(mip_offsets, DRAW_JIT_TEXTURE_MIP_OFFSETS, FALSE)
> -DRAW_LLVM_TEXTURE_MEMBER(min_lod,    DRAW_JIT_TEXTURE_MIN_LOD, TRUE)
> -DRAW_LLVM_TEXTURE_MEMBER(max_lod,    DRAW_JIT_TEXTURE_MAX_LOD, TRUE)
> -DRAW_LLVM_TEXTURE_MEMBER(lod_bias,   DRAW_JIT_TEXTURE_LOD_BIAS, TRUE)
> -DRAW_LLVM_TEXTURE_MEMBER(border_color, DRAW_JIT_TEXTURE_BORDER_COLOR, FALSE)
> +
> +
> +#define DRAW_LLVM_SAMPLER_MEMBER(_name, _index, _emit_load)  \
> +   static LLVMValueRef \
> +   draw_llvm_sampler_##_name( const struct lp_sampler_dynamic_state *base, \
> +                              struct gallivm_state *gallivm,               \
> +                              unsigned unit)                            \
> +   { \
> +      return draw_llvm_sampler_member(base, gallivm, unit, _index, #_name, _emit_load ); \
> +   }
> +
> +
> +DRAW_LLVM_SAMPLER_MEMBER(min_lod,    DRAW_JIT_SAMPLER_MIN_LOD, TRUE)
> +DRAW_LLVM_SAMPLER_MEMBER(max_lod,    DRAW_JIT_SAMPLER_MAX_LOD, TRUE)
> +DRAW_LLVM_SAMPLER_MEMBER(lod_bias,   DRAW_JIT_SAMPLER_LOD_BIAS, TRUE)
> +DRAW_LLVM_SAMPLER_MEMBER(border_color, DRAW_JIT_SAMPLER_BORDER_COLOR, FALSE)
> +
>
>
>   static void
> @@ -172,7 +224,8 @@ draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
>                                          struct gallivm_state *gallivm,
>                                          struct lp_type type,
>                                          boolean is_fetch,
> -                                       unsigned unit,
> +                                       unsigned texture_index,
> +                                       unsigned sampler_index,
>                                          const LLVMValueRef *coords,
>                                          const LLVMValueRef *offsets,
>                                          const struct lp_derivatives *derivs,
> @@ -182,14 +235,17 @@ draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
>   {
>      struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base;
>
> -   assert(unit<  PIPE_MAX_SAMPLERS);
> +   assert(texture_index<  PIPE_MAX_SHADER_SAMPLER_VIEWS);
> +   assert(sampler_index<  PIPE_MAX_SAMPLERS);
>
>      lp_build_sample_soa(gallivm,
> -&sampler->dynamic_state.static_state[unit],
> +&sampler->dynamic_state.static_state[texture_index].texture_state,
> +&sampler->dynamic_state.static_state[sampler_index].sampler_state,
>                          &sampler->dynamic_state.base,
>                          type,
>                          is_fetch,
> -                       unit,
> +                       texture_index,
> +                       sampler_index,
>                          coords,
>                          offsets,
>                          derivs,
> @@ -214,7 +270,7 @@ draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
>      assert(unit<  PIPE_MAX_SAMPLERS);
>
>      lp_build_size_query_soa(gallivm,
> -&sampler->dynamic_state.static_state[unit],
> +&sampler->dynamic_state.static_state[unit].texture_state,
>                              &sampler->dynamic_state.base,
>                              type,
>                              unit,
> @@ -223,7 +279,7 @@ draw_llvm_sampler_soa_emit_size_query(const struct lp_build_sampler_soa *base,
>   }
>
>   struct lp_build_sampler_soa *
> -draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
> +draw_llvm_sampler_soa_create(const struct draw_sampler_static_state *static_state,
>                                LLVMValueRef context_ptr)
>   {
>      struct draw_llvm_sampler_soa *sampler;
> @@ -244,10 +300,10 @@ draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
>      sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride;
>      sampler->dynamic_state.base.base_ptr = draw_llvm_texture_base_ptr;
>      sampler->dynamic_state.base.mip_offsets = draw_llvm_texture_mip_offsets;
> -   sampler->dynamic_state.base.min_lod = draw_llvm_texture_min_lod;
> -   sampler->dynamic_state.base.max_lod = draw_llvm_texture_max_lod;
> -   sampler->dynamic_state.base.lod_bias = draw_llvm_texture_lod_bias;
> -   sampler->dynamic_state.base.border_color = draw_llvm_texture_border_color;
> +   sampler->dynamic_state.base.min_lod = draw_llvm_sampler_min_lod;
> +   sampler->dynamic_state.base.max_lod = draw_llvm_sampler_max_lod;
> +   sampler->dynamic_state.base.lod_bias = draw_llvm_sampler_lod_bias;
> +   sampler->dynamic_state.base.border_color = draw_llvm_sampler_border_color;
>      sampler->dynamic_state.static_state = static_state;
>      sampler->dynamic_state.context_ptr = context_ptr;
>
> diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
> index 2223fcb..ec5791c 100644
> --- a/src/gallium/auxiliary/draw/draw_private.h
> +++ b/src/gallium/auxiliary/draw/draw_private.h
> @@ -310,7 +310,7 @@ struct draw_context
>       * we only handle vertex and geometry shaders in the draw module, but
>       * there may be more in the future (ex: hull and tessellation).
>       */
> -   struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
> +   struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
>      unsigned num_sampler_views[PIPE_SHADER_TYPES];
>      const struct pipe_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
>      unsigned num_samplers[PIPE_SHADER_TYPES];
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> index 04f4135..4e4bca3 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> @@ -87,24 +87,54 @@ lp_sampler_wrap_mode_uses_border_color(unsigned mode,
>
>
>   /**
> - * Initialize lp_sampler_static_state object with the gallium sampler
> - * and texture state.
> - * The former is considered to be static and the later dynamic.
> + * Initialize lp_sampler_static_texture_state object with the gallium
> + * texture/sampler_view state (this contains the parts which are
> + * considered static).
>    */
>   void
> -lp_sampler_static_state(struct lp_sampler_static_state *state,
> -                        const struct pipe_sampler_view *view,
> -                        const struct pipe_sampler_state *sampler)
> +lp_sampler_static_texture_state(struct lp_static_texture_state *state,
> +                                const struct pipe_sampler_view *view)
>   {
>      const struct pipe_resource *texture;
>
>      memset(state, 0, sizeof *state);
>
> -   if (!sampler || !view || !view->texture)
> +   if (!view || !view->texture)
>         return;
>
>      texture = view->texture;
>
> +   state->format            = view->format;
> +   state->swizzle_r         = view->swizzle_r;
> +   state->swizzle_g         = view->swizzle_g;
> +   state->swizzle_b         = view->swizzle_b;
> +   state->swizzle_a         = view->swizzle_a;
> +
> +   state->target            = texture->target;
> +   state->pot_width         = util_is_power_of_two(texture->width0);
> +   state->pot_height        = util_is_power_of_two(texture->height0);
> +   state->pot_depth         = util_is_power_of_two(texture->depth0);
> +   state->level_zero_only   = !view->u.tex.last_level;
> +
> +   /*
> +    * FIXME: Handle the remainder of pipe_sampler_view.
> +    */
> +}
> +
> +
> +/**
> + * Initialize lp_sampler_static_sampler_state object with the gallium sampler
> + * state (this contains the parts which are considered static).
> + */
> +void
> +lp_sampler_static_sampler_state(struct lp_static_sampler_state *state,
> +                                const struct pipe_sampler_state *sampler)
> +{
> +   memset(state, 0, sizeof *state);
> +
> +   if (!sampler)
> +      return;
> +
>      /*
>       * We don't copy sampler state over unless it is actually enabled, to avoid
>       * spurious recompiles, as the sampler static state is part of the shader
> @@ -117,24 +147,13 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
>       * regarding 1D/2D/3D/CUBE textures, wrap modes, etc.
>       */
>
> -   state->format            = view->format;
> -   state->swizzle_r         = view->swizzle_r;
> -   state->swizzle_g         = view->swizzle_g;
> -   state->swizzle_b         = view->swizzle_b;
> -   state->swizzle_a         = view->swizzle_a;
> -
> -   state->target            = texture->target;
> -   state->pot_width         = util_is_power_of_two(texture->width0);
> -   state->pot_height        = util_is_power_of_two(texture->height0);
> -   state->pot_depth         = util_is_power_of_two(texture->depth0);
> -
>      state->wrap_s            = sampler->wrap_s;
>      state->wrap_t            = sampler->wrap_t;
>      state->wrap_r            = sampler->wrap_r;
>      state->min_img_filter    = sampler->min_img_filter;
>      state->mag_img_filter    = sampler->mag_img_filter;
>
> -   if (view->u.tex.last_level&&  sampler->max_lod>  0.0f) {
> +   if (sampler->max_lod>  0.0f) {
>         state->min_mip_filter = sampler->min_mip_filter;
>      } else {
>         state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
> @@ -155,7 +174,11 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
>               state->apply_min_lod = 1;
>            }
>
> -         if (sampler->max_lod<  (float)view->u.tex.last_level) {
> +         /*
> +          * XXX this won't do anything with the mesa state tracker which always
> +          * sets max_lod to not more than actually present mip maps...
> +          */
> +         if (sampler->max_lod<  (PIPE_MAX_TEXTURE_LEVELS - 1)) {
>               state->apply_max_lod = 1;
>            }
>         }
> @@ -167,10 +190,6 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
>      }
>
>      state->normalized_coords = sampler->normalized_coords;
> -
> -   /*
> -    * FIXME: Handle the remainder of pipe_sampler_view.
> -    */
>   }
>
>
> @@ -182,7 +201,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
>    */
>   static LLVMValueRef
>   lp_build_rho(struct lp_build_sample_context *bld,
> -             unsigned unit,
> +             unsigned texture_unit,
>                const struct lp_derivatives *derivs)
>   {
>      struct gallivm_state *gallivm = bld->gallivm;
> @@ -264,7 +283,7 @@ lp_build_rho(struct lp_build_sample_context *bld,
>      rho_vec = lp_build_max(coord_bld, rho_xvec, rho_yvec);
>
>      first_level = bld->dynamic_state->first_level(bld->dynamic_state,
> -                                                 bld->gallivm, unit);
> +                                                 bld->gallivm, texture_unit);
>      first_level_vec = lp_build_broadcast_scalar(int_size_bld, first_level);
>      int_size = lp_build_minify(int_size_bld, bld->int_size, first_level_vec);
>      float_size = lp_build_int_to_float(float_size_bld, int_size);
> @@ -489,7 +508,8 @@ lp_build_brilinear_rho(struct lp_build_context *bld,
>    */
>   void
>   lp_build_lod_selector(struct lp_build_sample_context *bld,
> -                      unsigned unit,
> +                      unsigned texture_unit,
> +                      unsigned sampler_unit,
>                         const struct lp_derivatives *derivs,
>                         LLVMValueRef lod_bias, /* optional */
>                         LLVMValueRef explicit_lod, /* optional */
> @@ -505,12 +525,13 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>      *out_lod_ipart = bld->perquadi_bld.zero;
>      *out_lod_fpart = perquadf_bld->zero;
>
> -   if (bld->static_state->min_max_lod_equal) {
> +   if (bld->static_sampler_state->min_max_lod_equal) {
>         /* User is forcing sampling from a particular mipmap level.
>          * This is hit during mipmap generation.
>          */
>         LLVMValueRef min_lod =
> -         bld->dynamic_state->min_lod(bld->dynamic_state, bld->gallivm, unit);
> +         bld->dynamic_state->min_lod(bld->dynamic_state,
> +                                     bld->gallivm, sampler_unit);
>
>         lod = lp_build_broadcast_scalar(perquadf_bld, min_lod);
>      }
> @@ -522,16 +543,16 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>         else {
>            LLVMValueRef rho;
>
> -         rho = lp_build_rho(bld, unit, derivs);
> +         rho = lp_build_rho(bld, texture_unit, derivs);
>
>            /*
>             * Compute lod = log2(rho)
>             */
>
>            if (!lod_bias&&
> -             !bld->static_state->lod_bias_non_zero&&
> -             !bld->static_state->apply_max_lod&&
> -             !bld->static_state->apply_min_lod) {
> +             !bld->static_sampler_state->lod_bias_non_zero&&
> +             !bld->static_sampler_state->apply_max_lod&&
> +             !bld->static_sampler_state->apply_min_lod) {
>               /*
>                * Special case when there are no post-log2 adjustments, which
>                * saves instructions but keeping the integer and fractional lod
> @@ -568,25 +589,28 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>         }
>
>         /* add sampler lod bias */
> -      if (bld->static_state->lod_bias_non_zero) {
> +      if (bld->static_sampler_state->lod_bias_non_zero) {
>            LLVMValueRef sampler_lod_bias =
> -            bld->dynamic_state->lod_bias(bld->dynamic_state, bld->gallivm, unit);
> +            bld->dynamic_state->lod_bias(bld->dynamic_state,
> +                                         bld->gallivm, sampler_unit);
>            sampler_lod_bias = lp_build_broadcast_scalar(perquadf_bld,
>                                                         sampler_lod_bias);
>            lod = LLVMBuildFAdd(builder, lod, sampler_lod_bias, "sampler_lod_bias");
>         }
>
>         /* clamp lod */
> -      if (bld->static_state->apply_max_lod) {
> +      if (bld->static_sampler_state->apply_max_lod) {
>            LLVMValueRef max_lod =
> -            bld->dynamic_state->max_lod(bld->dynamic_state, bld->gallivm, unit);
> +            bld->dynamic_state->max_lod(bld->dynamic_state,
> +                                        bld->gallivm, sampler_unit);
>            max_lod = lp_build_broadcast_scalar(perquadf_bld, max_lod);
>
>            lod = lp_build_min(perquadf_bld, lod, max_lod);
>         }
> -      if (bld->static_state->apply_min_lod) {
> +      if (bld->static_sampler_state->apply_min_lod) {
>            LLVMValueRef min_lod =
> -            bld->dynamic_state->min_lod(bld->dynamic_state, bld->gallivm, unit);
> +            bld->dynamic_state->min_lod(bld->dynamic_state,
> +                                        bld->gallivm, sampler_unit);
>            min_lod = lp_build_broadcast_scalar(perquadf_bld, min_lod);
>
>            lod = lp_build_max(perquadf_bld, lod, min_lod);
> @@ -988,9 +1012,9 @@ lp_build_mipmap_level_sizes(struct lp_build_sample_context *bld,
>                                                         ilevel);
>      }
>      if (dims == 3 ||
> -       bld->static_state->target == PIPE_TEXTURE_CUBE ||
> -       bld->static_state->target == PIPE_TEXTURE_1D_ARRAY ||
> -       bld->static_state->target == PIPE_TEXTURE_2D_ARRAY) {
> +       bld->static_texture_state->target == PIPE_TEXTURE_CUBE ||
> +       bld->static_texture_state->target == PIPE_TEXTURE_1D_ARRAY ||
> +       bld->static_texture_state->target == PIPE_TEXTURE_2D_ARRAY) {
>         *img_stride_vec = lp_build_get_level_stride_vec(bld,
>                                                         bld->img_stride_array,
>                                                         ilevel);
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> index 87bf556..a252ea2 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> @@ -61,12 +61,12 @@ struct lp_derivatives
>
>
>   /**
> - * Sampler static state.
> + * Texture static state.
>    *
> - * These are the bits of state from pipe_resource and pipe_sampler_state that
> + * These are the bits of state from pipe_resource/pipe_sampler_view that
>    * are embedded in the generated code.
>    */
> -struct lp_sampler_static_state
> +struct lp_static_texture_state
>   {
>      /* pipe_sampler_view's state */
>      enum pipe_format format;
> @@ -80,7 +80,24 @@ struct lp_sampler_static_state
>      unsigned pot_width:1;     /**<  is the width a power of two? */
>      unsigned pot_height:1;
>      unsigned pot_depth:1;
> +   unsigned level_zero_only:1;
> +};
> +
> +
> +struct lp_derived_sampler_state
> +{
> +   unsigned min_mip_filter:2;
> +};
> +
>
> +/**
> + * Sampler static state.
> + *
> + * These are the bits of state from pipe_sampler_state that
> + * are embedded in the generated code.
> + */
> +struct lp_static_sampler_state
> +{
>      /* pipe_sampler_state's state */
>      unsigned wrap_s:3;
>      unsigned wrap_t:3;
> @@ -105,8 +122,8 @@ struct lp_sampler_static_state
>   /**
>    * Sampler dynamic state.
>    *
> - * These are the bits of state from pipe_resource and pipe_sampler_state that
> - * are computed in runtime.
> + * These are the bits of state from pipe_resource/pipe_sampler_view
> + * as well as from sampler state that are computed in runtime.

"computed at runtime"



More information about the mesa-dev mailing list