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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user