Module: Mesa Branch: lp-surface-tiling Commit: 792c93171ec075664f55720ffed397ac2834a4fc URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=792c93171ec075664f55720ffed397ac2834a4fc
Author: Brian Paul <[email protected]> Date: Thu Apr 8 10:49:01 2010 -0600 llvmpipe: fix cube mapping --- src/gallium/drivers/llvmpipe/lp_surface.c | 10 ++- src/gallium/drivers/llvmpipe/lp_texture.c | 133 ++++++++++++++++++++++------- src/gallium/drivers/llvmpipe/lp_texture.h | 9 ++- 3 files changed, 115 insertions(+), 37 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 038fe30..0c4c649 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -130,8 +130,14 @@ lp_surface_copy(struct pipe_context *pipe, /* copy */ { - ubyte *src_linear_ptr = src_tex->linear[src->face][src->level].data; - ubyte *dst_linear_ptr = dst_tex->linear[dst->face][dst->level].data; + const ubyte *src_linear_ptr + = llvmpipe_get_texture_image_address(src_tex, src->face, + src->level, + LP_TEX_LAYOUT_LINEAR); + ubyte *dst_linear_ptr + = llvmpipe_get_texture_image_address(dst_tex, dst->face, + dst->level, + LP_TEX_LAYOUT_LINEAR); util_copy_rect(dst_linear_ptr, format, dst_tex->stride[dst->level], diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index b40372f..8e8b81b 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -189,23 +189,21 @@ llvmpipe_texture_destroy(struct pipe_texture *pt) } else { /* regular texture */ - uint face, level; + uint level; - for (face = 0; face < Elements(lpt->linear); face++) { - for (level = 0; level < Elements(lpt->linear[0]); level++) { - if (lpt->linear[face][level].data) { - align_free(lpt->linear[face][level].data); - lpt->linear[face][level].data = NULL; - } + /* free linear image data */ + for (level = 0; level < Elements(lpt->linear); level++) { + if (lpt->linear[level].data) { + align_free(lpt->linear[level].data); + lpt->linear[level].data = NULL; } } - for (face = 0; face < Elements(lpt->tiled); face++) { - for (level = 0; level < Elements(lpt->tiled[0]); level++) { - if (lpt->tiled[face][level].data) { - align_free(lpt->tiled[face][level].data); - lpt->tiled[face][level].data = NULL; - } + /* free tiled image data */ + for (level = 0; level < Elements(lpt->tiled); level++) { + if (lpt->tiled[level].data) { + align_free(lpt->tiled[level].data); + lpt->tiled[level].data = NULL; } } } @@ -261,7 +259,7 @@ llvmpipe_texture_map(struct pipe_texture *texture, map = winsys->displaytarget_map(winsys, lpt->dt, dt_usage); /* install this linear image in texture data structure */ - lpt->linear[face][level].data = map; + lpt->linear[level].data = map; } else { /* regular texture */ @@ -563,14 +561,16 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe, /** - * Compute size (in bytes) need to store a texture image / mipmap level. + * Compute size (in bytes) need to store a texture image / mipmap level, + * for just one cube face. */ static unsigned -tex_image_size(const struct llvmpipe_texture *lpt, unsigned level, - enum lp_texture_layout layout) +tex_image_face_size(const struct llvmpipe_texture *lpt, unsigned level, + enum lp_texture_layout layout) { - enum pipe_format format = layout == LP_TEX_LAYOUT_LINEAR - ? lpt->base.format : PIPE_FORMAT_A8R8G8B8_UNORM; + /* for tiled layout, force a 32bpp format */ + enum pipe_format format = layout == LP_TEX_LAYOUT_TILED + ? PIPE_FORMAT_B8G8R8A8_UNORM : lpt->base.format; const unsigned height = u_minify(lpt->base.height0, level); const unsigned depth = u_minify(lpt->base.depth0, level); const unsigned nblocksy = @@ -578,12 +578,25 @@ tex_image_size(const struct llvmpipe_texture *lpt, unsigned level, const unsigned buffer_size = nblocksy * lpt->stride[level] * (lpt->base.target == PIPE_TEXTURE_3D ? depth : 1); - return buffer_size; } /** + * Compute size (in bytes) need to store a texture image / mipmap level, + * including all cube faces. + */ +static unsigned +tex_image_size(const struct llvmpipe_texture *lpt, unsigned level, + enum lp_texture_layout layout) +{ + const unsigned buf_size = tex_image_face_size(lpt, level, layout); + const unsigned num_faces = lpt->base.target == PIPE_TEXTURE_CUBE ? 6 : 1; + return buf_size * num_faces; +} + + +/** * This function encapsulates some complicated logic for determining * how to convert a tile of image data from linear layout to tiled * layout, or vice versa. @@ -642,6 +655,34 @@ layout_logic(enum lp_texture_layout cur_layout, } +/** + * Return pointer to a texture image. No tiled/linear conversion is done. + */ +void * +llvmpipe_get_texture_image_address(struct llvmpipe_texture *lpt, + unsigned face, unsigned level, + enum lp_texture_layout layout) +{ + struct llvmpipe_texture_image *img; + unsigned face_offset; + + if (layout == LP_TEX_LAYOUT_LINEAR) { + img = &lpt->linear[level]; + } + else { + assert (layout == LP_TEX_LAYOUT_TILED); + img = &lpt->tiled[level]; + } + + if (face > 0) + face_offset = face * tex_image_face_size(lpt, level, layout); + else + face_offset = 0; + + return (ubyte *) img->data + face_offset; +} + + /** * Return pointer to texture image data (either linear or tiled layout). @@ -668,6 +709,7 @@ llvmpipe_get_texture_image(struct llvmpipe_texture *lpt, const unsigned height = u_minify(lpt->base.height0, level); const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE; const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE; + enum lp_texture_layout other_layout; assert(layout == LP_TEX_LAYOUT_NONE || layout == LP_TEX_LAYOUT_TILED || @@ -678,17 +720,19 @@ llvmpipe_get_texture_image(struct llvmpipe_texture *lpt, usage == LP_TEX_USAGE_WRITE_ALL); if (lpt->dt) { - assert(lpt->linear[face][level].data); + assert(lpt->linear[level].data); } /* which is target? which is other? */ if (layout == LP_TEX_LAYOUT_LINEAR) { - target_img = &lpt->linear[face][level]; - other_img = &lpt->tiled[face][level]; + target_img = &lpt->linear[level]; + other_img = &lpt->tiled[level]; + other_layout = LP_TEX_LAYOUT_TILED; } else { - target_img = &lpt->tiled[face][level]; - other_img = &lpt->linear[face][level]; + target_img = &lpt->tiled[level]; + other_img = &lpt->linear[level]; + other_layout = LP_TEX_LAYOUT_LINEAR; } target_data = target_img->data; @@ -701,6 +745,16 @@ llvmpipe_get_texture_image(struct llvmpipe_texture *lpt, target_data = target_img->data; } + if (face > 0) { + unsigned offset = face * tex_image_face_size(lpt, level, layout); + if (target_data) { + target_data = (uint8_t *) target_data + offset; + } + if (other_data) { + other_data = (uint8_t *) other_data + offset; + } + } + if (layout == LP_TEX_LAYOUT_NONE) { /* just allocating memory */ return target_data; @@ -783,7 +837,8 @@ llvmpipe_set_texture_tile_layout(struct llvmpipe_texture *lpt, /** * Get pointer to a linear image where the tile at (x,y) is known to be * in linear layout. - * \return pointer to start of image (not the tile) + * Conversion from tiled to linear will be done if necessary. + * \return pointer to start of image/face (not the tile) */ ubyte * llvmpipe_get_texture_tile_linear(struct llvmpipe_texture *lpt, @@ -791,8 +846,8 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_texture *lpt, enum lp_texture_usage usage, unsigned x, unsigned y) { - struct llvmpipe_texture_image *tiled_img = &lpt->tiled[face][level]; - struct llvmpipe_texture_image *linear_img = &lpt->linear[face][level]; + struct llvmpipe_texture_image *tiled_img = &lpt->tiled[level]; + struct llvmpipe_texture_image *linear_img = &lpt->linear[level]; enum lp_texture_layout cur_layout, new_layout; const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE; boolean convert; @@ -820,7 +875,14 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_texture *lpt, if (new_layout != cur_layout) llvmpipe_set_texture_tile_layout(lpt, face, level, tx, ty, new_layout); - return linear_img->data; + if (face > 0) { + unsigned offset + = face * tex_image_face_size(lpt, level, LP_TEX_LAYOUT_LINEAR); + return (ubyte *) linear_img->data + offset; + } + else { + return linear_img->data; + } } @@ -835,8 +897,8 @@ llvmpipe_get_texture_tile(struct llvmpipe_texture *lpt, unsigned x, unsigned y) { const unsigned width = u_minify(lpt->base.width0, level); - struct llvmpipe_texture_image *tiled_img = &lpt->tiled[face][level]; - struct llvmpipe_texture_image *linear_img = &lpt->linear[face][level]; + struct llvmpipe_texture_image *tiled_img = &lpt->tiled[level]; + struct llvmpipe_texture_image *linear_img = &lpt->linear[level]; enum lp_texture_layout cur_layout, new_layout; const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE; boolean convert; @@ -864,7 +926,7 @@ llvmpipe_get_texture_tile(struct llvmpipe_texture *lpt, /* compute, return address of the 64x64 tile */ { - unsigned tiles_per_row, tile_offset; + unsigned tiles_per_row, tile_offset, face_offset; tiles_per_row = align(width, TILE_SIZE) / TILE_SIZE; @@ -874,7 +936,12 @@ llvmpipe_get_texture_tile(struct llvmpipe_texture *lpt, tile_offset *= TILE_SIZE * TILE_SIZE * 4; assert(tiled_img->data); - return (ubyte *) tiled_img->data + tile_offset; + + face_offset = (face > 0) + ? (face * tex_image_face_size(lpt, level, LP_TEX_LAYOUT_TILED)) + : 0; + + return (ubyte *) tiled_img->data + face_offset + tile_offset; } } diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index 47c9212..bac4ff6 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -95,8 +95,8 @@ struct llvmpipe_texture /** * Malloc'ed data for regular textures, or a mapping to dt above. */ - struct llvmpipe_texture_image tiled[PIPE_TEX_FACE_MAX][LP_MAX_TEXTURE_LEVELS]; - struct llvmpipe_texture_image linear[PIPE_TEX_FACE_MAX][LP_MAX_TEXTURE_LEVELS]; + struct llvmpipe_texture_image tiled[LP_MAX_TEXTURE_LEVELS]; + struct llvmpipe_texture_image linear[LP_MAX_TEXTURE_LEVELS]; /** per-tile layout info */ enum lp_texture_layout *layout[PIPE_TEX_FACE_MAX][LP_MAX_TEXTURE_LEVELS]; @@ -162,6 +162,11 @@ llvmpipe_texture_unmap(struct pipe_texture *texture, unsigned zslice); void * +llvmpipe_get_texture_image_address(struct llvmpipe_texture *lpt, + unsigned face, unsigned level, + enum lp_texture_layout layout); + +void * llvmpipe_get_texture_image(struct llvmpipe_texture *texture, unsigned face, unsigned level, enum lp_texture_usage usage, _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
