[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