llvmpipe: get 3D texture image stride from an array rather than computing it

This fixes broken 3D texture indexing when the height of the 3D texture
was less than 64 (the tile size).  It's simpler to pass this as an array
(as we do with the row stride) than to compute it on the fly.
This commit is contained in:
Brian Paul
2010-04-19 17:05:05 -06:00
parent 2cad62475b
commit f4071e55db
7 changed files with 34 additions and 17 deletions

View File

@@ -51,7 +51,7 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
/* struct lp_jit_texture */ /* struct lp_jit_texture */
{ {
LLVMTypeRef elem_types[6]; LLVMTypeRef elem_types[LP_JIT_TEXTURE_NUM_FIELDS];
elem_types[LP_JIT_TEXTURE_WIDTH] = LLVMInt32Type(); elem_types[LP_JIT_TEXTURE_WIDTH] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type(); elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
@@ -59,6 +59,8 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type(); elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
elem_types[LP_JIT_TEXTURE_ROW_STRIDE] = elem_types[LP_JIT_TEXTURE_ROW_STRIDE] =
LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS); LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS);
elem_types[LP_JIT_TEXTURE_IMG_STRIDE] =
LLVMArrayType(LLVMInt32Type(), LP_MAX_TEXTURE_LEVELS);
elem_types[LP_JIT_TEXTURE_DATA] = elem_types[LP_JIT_TEXTURE_DATA] =
LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0), LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
LP_MAX_TEXTURE_LEVELS); LP_MAX_TEXTURE_LEVELS);
@@ -80,6 +82,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride, LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride,
screen->target, texture_type, screen->target, texture_type,
LP_JIT_TEXTURE_ROW_STRIDE); LP_JIT_TEXTURE_ROW_STRIDE);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, img_stride,
screen->target, texture_type,
LP_JIT_TEXTURE_IMG_STRIDE);
LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data, LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
screen->target, texture_type, screen->target, texture_type,
LP_JIT_TEXTURE_DATA); LP_JIT_TEXTURE_DATA);

View File

@@ -52,6 +52,7 @@ struct lp_jit_texture
uint32_t depth; uint32_t depth;
uint32_t last_level; uint32_t last_level;
uint32_t row_stride[LP_MAX_TEXTURE_LEVELS]; uint32_t row_stride[LP_MAX_TEXTURE_LEVELS];
uint32_t img_stride[LP_MAX_TEXTURE_LEVELS];
const void *data[LP_MAX_TEXTURE_LEVELS]; const void *data[LP_MAX_TEXTURE_LEVELS];
}; };
@@ -62,7 +63,9 @@ enum {
LP_JIT_TEXTURE_DEPTH, LP_JIT_TEXTURE_DEPTH,
LP_JIT_TEXTURE_LAST_LEVEL, LP_JIT_TEXTURE_LAST_LEVEL,
LP_JIT_TEXTURE_ROW_STRIDE, LP_JIT_TEXTURE_ROW_STRIDE,
LP_JIT_TEXTURE_DATA LP_JIT_TEXTURE_IMG_STRIDE,
LP_JIT_TEXTURE_DATA,
LP_JIT_TEXTURE_NUM_FIELDS /* number of fields above */
}; };

View File

@@ -534,7 +534,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ, llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
LP_TEX_LAYOUT_LINEAR); LP_TEX_LAYOUT_LINEAR);
#endif #endif
jit_tex->row_stride[j] = lp_tex->stride[j]; jit_tex->row_stride[j] = lp_tex->row_stride[j];
jit_tex->img_stride[j] = lp_tex->img_stride[j];
} }
} }
else { else {
@@ -547,7 +548,8 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
struct sw_winsys *winsys = screen->winsys; struct sw_winsys *winsys = screen->winsys;
jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt, jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
PIPE_TRANSFER_READ); PIPE_TRANSFER_READ);
jit_tex->row_stride[0] = lp_tex->stride[0]; jit_tex->row_stride[0] = lp_tex->row_stride[0];
jit_tex->img_stride[0] = lp_tex->img_stride[0];
assert(jit_tex->data[0]); assert(jit_tex->data[0]);
} }
} }

View File

@@ -135,10 +135,10 @@ lp_surface_copy(struct pipe_context *pipe,
LP_TEX_LAYOUT_LINEAR); LP_TEX_LAYOUT_LINEAR);
util_copy_rect(dst_linear_ptr, format, util_copy_rect(dst_linear_ptr, format,
dst_tex->stride[dst->level], dst_tex->row_stride[dst->level],
dstx, dsty, dstx, dsty,
width, height, width, height,
src_linear_ptr, src_tex->stride[src->level], src_linear_ptr, src_tex->row_stride[src->level],
srcx, srcy); srcx, srcy);
} }
} }

View File

@@ -148,6 +148,7 @@ LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT, TRUE)
LP_LLVM_TEXTURE_MEMBER(depth, LP_JIT_TEXTURE_DEPTH, 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(last_level, LP_JIT_TEXTURE_LAST_LEVEL, TRUE)
LP_LLVM_TEXTURE_MEMBER(row_stride, LP_JIT_TEXTURE_ROW_STRIDE, FALSE) 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(data_ptr, LP_JIT_TEXTURE_DATA, FALSE) LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA, FALSE)
@@ -205,6 +206,7 @@ lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
sampler->dynamic_state.base.depth = lp_llvm_texture_depth; sampler->dynamic_state.base.depth = lp_llvm_texture_depth;
sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level; sampler->dynamic_state.base.last_level = lp_llvm_texture_last_level;
sampler->dynamic_state.base.row_stride = lp_llvm_texture_row_stride; 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.data_ptr = lp_llvm_texture_data_ptr; sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
sampler->dynamic_state.static_state = static_state; sampler->dynamic_state.static_state = static_state;
sampler->dynamic_state.context_ptr = context_ptr; sampler->dynamic_state.context_ptr = context_ptr;

View File

@@ -120,9 +120,11 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
*/ */
nblocksx = util_format_get_nblocksx(pt->format, align(width, TILE_SIZE)); nblocksx = util_format_get_nblocksx(pt->format, align(width, TILE_SIZE));
lpr->stride[level] = lpr->row_stride[level] =
align(nblocksx * util_format_get_blocksize(pt->format), 16); align(nblocksx * util_format_get_blocksize(pt->format), 16);
lpr->img_stride[level] = lpr->row_stride[level] * align(height, TILE_SIZE);
lpr->tiles_per_row[level] = width_t; lpr->tiles_per_row[level] = width_t;
lpr->tiles_per_image[level] = width_t * height_t; lpr->tiles_per_image[level] = width_t * height_t;
lpr->num_slices_faces[level] = num_slices; lpr->num_slices_faces[level] = num_slices;
@@ -155,6 +157,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
lpr->tiles_per_row[0] = width_t; lpr->tiles_per_row[0] = width_t;
lpr->tiles_per_image[0] = width_t * height_t; lpr->tiles_per_image[0] = width_t * height_t;
lpr->num_slices_faces[0] = 1; lpr->num_slices_faces[0] = 1;
lpr->img_stride[0] = 0;
lpr->layout[0] = alloc_layout_array(1, width, height); lpr->layout[0] = alloc_layout_array(1, width, height);
@@ -163,7 +166,7 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
lpr->base.format, lpr->base.format,
width, height, width, height,
16, 16,
&lpr->stride[0] ); &lpr->row_stride[0] );
return lpr->dt != NULL; return lpr->dt != NULL;
} }
@@ -409,7 +412,7 @@ llvmpipe_resource_from_handle(struct pipe_screen *screen,
lpr->dt = winsys->displaytarget_from_handle(winsys, lpr->dt = winsys->displaytarget_from_handle(winsys,
template, template,
whandle, whandle,
&lpr->stride[0]); &lpr->row_stride[0]);
if (!lpr->dt) if (!lpr->dt)
goto fail; goto fail;
@@ -496,7 +499,7 @@ llvmpipe_get_transfer(struct pipe_context *pipe,
pipe_resource_reference(&pt->resource, resource); pipe_resource_reference(&pt->resource, resource);
pt->box = *box; pt->box = *box;
pt->sr = sr; pt->sr = sr;
pt->stride = lprex->stride[sr.level]; pt->stride = lprex->row_stride[sr.level];
pt->usage = usage; pt->usage = usage;
return pt; return pt;
@@ -684,7 +687,7 @@ tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level,
const enum pipe_format format = lpr->base.format; const enum pipe_format format = lpr->base.format;
const unsigned nblocksy = const unsigned nblocksy =
util_format_get_nblocksy(format, align(height, TILE_SIZE)); util_format_get_nblocksy(format, align(height, TILE_SIZE));
const unsigned buffer_size = nblocksy * lpr->stride[level]; const unsigned buffer_size = nblocksy * lpr->row_stride[level];
return buffer_size; return buffer_size;
} }
} }
@@ -954,14 +957,14 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
x * TILE_SIZE, y * TILE_SIZE, x * TILE_SIZE, y * TILE_SIZE,
TILE_SIZE, TILE_SIZE, TILE_SIZE, TILE_SIZE,
lpr->base.format, lpr->base.format,
lpr->stride[level]); lpr->row_stride[level]);
} }
else { else {
lp_tiled_to_linear(other_data, target_data, lp_tiled_to_linear(other_data, target_data,
x * TILE_SIZE, y * TILE_SIZE, x * TILE_SIZE, y * TILE_SIZE,
TILE_SIZE, TILE_SIZE, TILE_SIZE, TILE_SIZE,
lpr->base.format, lpr->base.format,
lpr->stride[level]); lpr->row_stride[level]);
} }
} }
@@ -1045,7 +1048,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
if (convert) { if (convert) {
lp_tiled_to_linear(tiled_img->data, linear_img->data, lp_tiled_to_linear(tiled_img->data, linear_img->data,
x, y, TILE_SIZE, TILE_SIZE, lpr->base.format, x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
lpr->stride[level]); lpr->row_stride[level]);
} }
if (new_layout != cur_layout) if (new_layout != cur_layout)
@@ -1094,7 +1097,7 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
if (convert) { if (convert) {
lp_linear_to_tiled(linear_img->data, tiled_img->data, lp_linear_to_tiled(linear_img->data, tiled_img->data,
x, y, TILE_SIZE, TILE_SIZE, lpr->base.format, x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
lpr->stride[level]); lpr->row_stride[level]);
} }
if (new_layout != cur_layout) if (new_layout != cur_layout)

View File

@@ -92,7 +92,9 @@ struct llvmpipe_resource
struct pipe_resource base; struct pipe_resource base;
/** Row stride in bytes */ /** Row stride in bytes */
unsigned stride[LP_MAX_TEXTURE_LEVELS]; unsigned row_stride[LP_MAX_TEXTURE_LEVELS];
/** Image stride (for cube maps or 3D textures) in bytes */
unsigned img_stride[LP_MAX_TEXTURE_LEVELS];
unsigned tiles_per_row[LP_MAX_TEXTURE_LEVELS]; unsigned tiles_per_row[LP_MAX_TEXTURE_LEVELS];
unsigned tiles_per_image[LP_MAX_TEXTURE_LEVELS]; unsigned tiles_per_image[LP_MAX_TEXTURE_LEVELS];
/** Number of 3D slices or cube faces per level */ /** Number of 3D slices or cube faces per level */
@@ -164,7 +166,7 @@ llvmpipe_resource_stride(struct pipe_resource *resource,
{ {
struct llvmpipe_resource *lpr = llvmpipe_resource(resource); struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
assert(level < LP_MAX_TEXTURE_2D_LEVELS); assert(level < LP_MAX_TEXTURE_2D_LEVELS);
return lpr->stride[level]; return lpr->row_stride[level];
} }