diff options
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_context.h | 4 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.c | 54 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_jit.h | 24 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 16 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_context.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 84 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.h | 17 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_sampler.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_tex_sample.c | 102 |
9 files changed, 225 insertions, 84 deletions
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; |