summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c54
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h24
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c84
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.h17
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.c102
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;