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.
This commit is contained in:
Brian Paul
2010-03-08 15:19:13 -07:00
parent 891f7f4d52
commit f027d56129
7 changed files with 81 additions and 44 deletions
@@ -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;
@@ -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
@@ -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);
+3 -1
View File
@@ -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);
+2 -1
View File
@@ -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];
};
+11 -5
View File
@@ -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 */
@@ -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