diff options
Diffstat (limited to 'src/gallium')
20 files changed, 709 insertions, 357 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index bc2f0e1d03f..dfa8927bc08 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -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; diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index a3a3bbfea48..afb10a6a33a 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_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); } } } diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index 892973c3725..a6648573aa5 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 67d4e9339d6..9932b911120 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); @@ -123,6 +123,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 * generator requests. @@ -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; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 2223fcb3f40..ec5791cbc17 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 04f41355e7b..4e4bca3014f 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 87bf5567e42..d0207aa471e 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,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, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c index 9371e1c2818..b9c8446032e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c @@ -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 */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 918dd36fbf5..0e901948aa2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -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, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 16d2ed9e6f7..489884906cc 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -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, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index fbeb805530c..0621fb482ce 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -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, diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index b11a3d838e3..9ccb67bdd1f 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -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]; diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c index ea7c8054bfa..d0a791671e6 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.c +++ b/src/gallium/drivers/llvmpipe/lp_jit.c @@ -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); diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h index 5dc5bc4c4bf..3057c0dc2b0 100644 --- a/src/gallium/drivers/llvmpipe/lp_jit.h +++ b/src/gallium/drivers/llvmpipe/lp_jit.h @@ -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") /** diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index ffa0fe6eaa3..b0bc4a8132f 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -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); } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 4d20dd38461..0e2de648a91 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -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 */ diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index cf936d029b5..09f37e0cead 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -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]); + } } } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h index 306f5f9669a..c8dc1c33cfe 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.h +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h @@ -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]; }; diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c index e7429cc35a1..9736ca94905 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c @@ -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) { diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.c b/src/gallium/drivers/llvmpipe/lp_tex_sample.c index 0bd5c4aa050..25125a0768b 100644 --- a/src/gallium/drivers/llvmpipe/lp_tex_sample.c +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.c @@ -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; |