summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2010-03-08 15:19:13 -0700
committerBrian Paul <[email protected]>2010-03-08 16:26:44 -0700
commitf027d5612901de8e6167e6288c4e24d91d964e7f (patch)
tree279896ca1f4af62cd5eb7e8d0d48c096db82f6fa /src/gallium
parent891f7f4d52656ddbb445ef1992e8de05763ce680 (diff)
llvmpipe/gallivm: checkpoint: array of pointers to mipmap levels
Change the texture data_ptr from just a single image pointer to an array of image pointers, indexed by mipmap level. We'll use this for mipmap filtering. For now, the mipmap level is hard-coded to zero.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.c3
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.h3
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c69
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c27
7 files changed, 81 insertions, 44 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index 29cadcc15ae..311c9f1b9e4 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -162,8 +162,7 @@ lp_build_sample_offset(struct lp_build_context *bld,
const struct util_format_description *format_desc,
LLVMValueRef x,
LLVMValueRef y,
- LLVMValueRef y_stride,
- LLVMValueRef data_ptr)
+ LLVMValueRef y_stride)
{
LLVMValueRef x_stride;
LLVMValueRef offset;
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
index 5ba0925bb69..68db91d6fd6 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
@@ -148,8 +148,7 @@ lp_build_sample_offset(struct lp_build_context *bld,
const struct util_format_description *format_desc,
LLVMValueRef x,
LLVMValueRef y,
- LLVMValueRef y_stride,
- LLVMValueRef data_ptr);
+ LLVMValueRef y_stride);
void
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index 9058f76c1df..1dca29cdd58 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -124,13 +124,14 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
LLVMValueRef x,
LLVMValueRef y,
LLVMValueRef y_stride,
- LLVMValueRef data_ptr,
+ LLVMValueRef data_array,
LLVMValueRef *texel)
{
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
LLVMValueRef offset;
LLVMValueRef packed;
LLVMValueRef use_border = NULL;
+ LLVMValueRef data_ptr;
/* use_border = x < 0 || x >= width || y < 0 || y >= height */
if (wrap_mode_uses_border_color(bld->static_state->wrap_s)) {
@@ -153,6 +154,16 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
}
}
+ /* XXX always use mipmap level 0 for now */
+ {
+ const int level = 0;
+ LLVMValueRef indexes[2];
+ indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ indexes[1] = LLVMConstInt(LLVMInt32Type(), level, 0);
+ data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
+ data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
+ }
+
/*
* Note: if we find an app which frequently samples the texture border
* we might want to implement a true conditional here to avoid sampling
@@ -171,8 +182,7 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
/* convert x,y coords to linear offset from start of texture, in bytes */
offset = lp_build_sample_offset(&bld->uint_coord_bld,
bld->format_desc,
- x, y, y_stride,
- data_ptr);
+ x, y, y_stride);
assert(bld->format_desc->block.width == 1);
assert(bld->format_desc->block.height == 1);
@@ -210,19 +220,31 @@ lp_build_sample_packed(struct lp_build_sample_context *bld,
LLVMValueRef x,
LLVMValueRef y,
LLVMValueRef y_stride,
- LLVMValueRef data_ptr)
+ LLVMValueRef data_array)
{
LLVMValueRef offset;
+ LLVMValueRef data_ptr;
offset = lp_build_sample_offset(&bld->uint_coord_bld,
bld->format_desc,
- x, y, y_stride,
- data_ptr);
+ x, y, y_stride);
assert(bld->format_desc->block.width == 1);
assert(bld->format_desc->block.height == 1);
assert(bld->format_desc->block.bits <= bld->texel_type.width);
+ /* XXX always use mipmap level 0 for now */
+ {
+ const int level = 0;
+ LLVMValueRef indexes[2];
+ /* get data_ptr[level] */
+ indexes[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ indexes[1] = LLVMConstInt(LLVMInt32Type(), level, 0);
+ data_ptr = LLVMBuildGEP(bld->builder, data_array, indexes, 2, "");
+ /* load texture base address */
+ data_ptr = LLVMBuildLoad(bld->builder, data_ptr, "");
+ }
+
return lp_build_gather(bld->builder,
bld->texel_type.length,
bld->format_desc->block.bits,
@@ -720,7 +742,7 @@ lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef stride,
- LLVMValueRef data_ptr,
+ LLVMValueRef data_array,
LLVMValueRef *texel)
{
LLVMValueRef x, y;
@@ -735,7 +757,7 @@ lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
lp_build_name(x, "tex.x.wrapped");
lp_build_name(y, "tex.y.wrapped");
- lp_build_sample_texel_soa(bld, width, height, x, y, stride, data_ptr, texel);
+ lp_build_sample_texel_soa(bld, width, height, x, y, stride, data_array, texel);
}
@@ -749,7 +771,7 @@ lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef stride,
- LLVMValueRef data_ptr,
+ LLVMValueRef data_array,
LLVMValueRef *texel)
{
LLVMValueRef s_fpart;
@@ -764,10 +786,10 @@ lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
lp_build_sample_wrap_linear(bld, t, height, bld->static_state->pot_height,
bld->static_state->wrap_t, &y0, &y1, &t_fpart);
- lp_build_sample_texel_soa(bld, width, height, x0, y0, stride, data_ptr, neighbors[0][0]);
- lp_build_sample_texel_soa(bld, width, height, x1, y0, stride, data_ptr, neighbors[0][1]);
- lp_build_sample_texel_soa(bld, width, height, x0, y1, stride, data_ptr, neighbors[1][0]);
- lp_build_sample_texel_soa(bld, width, height, x1, y1, stride, data_ptr, neighbors[1][1]);
+ lp_build_sample_texel_soa(bld, width, height, x0, y0, stride, data_array, neighbors[0][0]);
+ lp_build_sample_texel_soa(bld, width, height, x1, y0, stride, data_array, neighbors[0][1]);
+ lp_build_sample_texel_soa(bld, width, height, x0, y1, stride, data_array, neighbors[1][0]);
+ lp_build_sample_texel_soa(bld, width, height, x1, y1, stride, data_array, neighbors[1][1]);
/* TODO: Don't interpolate missing channels */
for(chan = 0; chan < 4; ++chan) {
@@ -818,7 +840,7 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
LLVMValueRef width,
LLVMValueRef height,
LLVMValueRef stride,
- LLVMValueRef data_ptr,
+ LLVMValueRef data_array,
LLVMValueRef *texel)
{
LLVMBuilderRef builder = bld->builder;
@@ -958,10 +980,10 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
* The higher 8 bits of the resulting elements will be zero.
*/
- neighbors[0][0] = lp_build_sample_packed(bld, x0, y0, stride, data_ptr);
- neighbors[0][1] = lp_build_sample_packed(bld, x1, y0, stride, data_ptr);
- neighbors[1][0] = lp_build_sample_packed(bld, x0, y1, stride, data_ptr);
- neighbors[1][1] = lp_build_sample_packed(bld, x1, y1, stride, data_ptr);
+ neighbors[0][0] = lp_build_sample_packed(bld, x0, y0, stride, data_array);
+ neighbors[0][1] = lp_build_sample_packed(bld, x1, y0, stride, data_array);
+ neighbors[1][0] = lp_build_sample_packed(bld, x0, y1, stride, data_array);
+ neighbors[1][1] = lp_build_sample_packed(bld, x1, y1, stride, data_array);
neighbors[0][0] = LLVMBuildBitCast(builder, neighbors[0][0], u8n_vec_type, "");
neighbors[0][1] = LLVMBuildBitCast(builder, neighbors[0][1], u8n_vec_type, "");
@@ -1248,7 +1270,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
LLVMValueRef width;
LLVMValueRef height;
LLVMValueRef stride;
- LLVMValueRef data_ptr;
+ LLVMValueRef data_array;
LLVMValueRef s;
LLVMValueRef t;
LLVMValueRef r;
@@ -1276,7 +1298,8 @@ lp_build_sample_soa(LLVMBuilderRef builder,
width = dynamic_state->width(dynamic_state, builder, unit);
height = dynamic_state->height(dynamic_state, builder, unit);
stride = dynamic_state->stride(dynamic_state, builder, unit);
- data_ptr = dynamic_state->data_ptr(dynamic_state, builder, unit);
+ data_array = dynamic_state->data_ptr(dynamic_state, builder, unit);
+ /* Note that data_array is an array[level] of pointers to texture images */
s = coords[0];
t = coords[1];
@@ -1292,17 +1315,17 @@ lp_build_sample_soa(LLVMBuilderRef builder,
switch (static_state->min_img_filter) {
case PIPE_TEX_FILTER_NEAREST:
lp_build_sample_2d_nearest_soa(&bld, s, t, width, height,
- stride, data_ptr, texel);
+ stride, data_array, texel);
break;
case PIPE_TEX_FILTER_LINEAR:
if(lp_format_is_rgba8(bld.format_desc) &&
is_simple_wrap_mode(static_state->wrap_s) &&
is_simple_wrap_mode(static_state->wrap_t))
lp_build_sample_2d_linear_aos(&bld, s, t, width, height,
- stride, data_ptr, texel);
+ stride, data_array, texel);
else
lp_build_sample_2d_linear_soa(&bld, s, t, width, height,
- stride, data_ptr, texel);
+ stride, data_array, texel);
break;
default:
assert(0);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index bacff500d63..08c8f93794d 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -58,7 +58,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
elem_types[LP_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
- elem_types[LP_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0);
+ elem_types[LP_JIT_TEXTURE_DATA] =
+ LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
+ LP_MAX_TEXTURE_2D_LEVELS);
texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 0ebb2826fa2..5cc7a12c03b 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -39,6 +39,7 @@
#include "gallivm/lp_bld_struct.h"
#include "pipe/p_state.h"
+#include "lp_texture.h"
struct llvmpipe_screen;
@@ -51,7 +52,7 @@ struct lp_jit_texture
uint32_t depth;
uint32_t last_level;
uint32_t stride;
- const void *data;
+ const void *data[LP_MAX_TEXTURE_2D_LEVELS];
};
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index b0713c3b71d..cc7c18c8c0c 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -472,19 +472,25 @@ lp_setup_set_sampler_textures( struct setup_context *setup,
jit_tex->depth = tex->depth0;
jit_tex->last_level = tex->last_level;
jit_tex->stride = lp_tex->stride[0];
- if(!lp_tex->dt) {
- jit_tex->data = lp_tex->data;
+ if (!lp_tex->dt) {
+ /* regular texture - setup array of mipmap level pointers */
+ int j;
+ for (j = 0; j < LP_MAX_TEXTURE_2D_LEVELS; j++) {
+ jit_tex->data[j] =
+ (ubyte *) lp_tex->data + lp_tex->level_offset[j];
+ }
}
else {
+ /* display target texture/surface */
/*
* XXX: Where should this be unmapped?
*/
struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
struct llvmpipe_winsys *winsys = screen->winsys;
- jit_tex->data = winsys->displaytarget_map(winsys, lp_tex->dt,
- PIPE_BUFFER_USAGE_CPU_READ);
- assert(jit_tex->data);
+ jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ assert(jit_tex->data[0]);
}
/* the scene references this texture */
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index fde2d653eba..5a3cf37d6d8 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -80,6 +80,9 @@ struct lp_llvm_sampler_soa
/**
* Fetch the specified member of the lp_jit_texture 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
*/
@@ -88,7 +91,8 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
LLVMBuilderRef builder,
unsigned unit,
unsigned member_index,
- const char *member_name)
+ const char *member_name,
+ boolean emit_load)
{
struct llvmpipe_sampler_dynamic_state *state =
(struct llvmpipe_sampler_dynamic_state *)base;
@@ -109,7 +113,10 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
- res = LLVMBuildLoad(builder, ptr, "");
+ if (emit_load)
+ res = LLVMBuildLoad(builder, ptr, "");
+ else
+ res = ptr;
lp_build_name(res, "context.texture%u.%s", unit, member_name);
@@ -126,22 +133,22 @@ lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
* sampler code generator a reusable module without dependencies to
* llvmpipe internals.
*/
-#define LP_LLVM_TEXTURE_MEMBER(_name, _index) \
+#define LP_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load) \
static LLVMValueRef \
lp_llvm_texture_##_name( struct lp_sampler_dynamic_state *base, \
LLVMBuilderRef builder, \
unsigned unit) \
{ \
- return lp_llvm_texture_member(base, builder, unit, _index, #_name ); \
+ return lp_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
}
-LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH)
-LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT)
-LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH)
-LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL)
-LP_LLVM_TEXTURE_MEMBER(stride, LP_JIT_TEXTURE_STRIDE)
-LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA)
+LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT, TRUE)
+LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH, TRUE)
+LP_LLVM_TEXTURE_MEMBER(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
+LP_LLVM_TEXTURE_MEMBER(stride, LP_JIT_TEXTURE_STRIDE, TRUE)
+LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA, FALSE)
static void