From f3ad716e8f36fa1360703b73eafed1824c29db6e Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 16 May 2013 22:58:33 +0200 Subject: [PATCH] llvmpipe: get rid of unused tiled/linear logic We do rendering to linear color buffers for quite some time, and since switching to linear depth buffers all the tiled/linear logic was unused. So get rid of (most) of it - there's still some LAYOUT_NONE things and late allocation of resources which probably could be simplified. Reviewed-by: Jose Fonseca --- src/gallium/drivers/llvmpipe/Makefile.am | 3 +- src/gallium/drivers/llvmpipe/SConscript | 3 +- src/gallium/drivers/llvmpipe/lp_rast_priv.h | 4 +- src/gallium/drivers/llvmpipe/lp_texture.c | 388 ++++----------------------- src/gallium/drivers/llvmpipe/lp_texture.h | 10 - src/gallium/drivers/llvmpipe/lp_tile_image.c | 294 -------------------- src/gallium/drivers/llvmpipe/lp_tile_image.h | 61 ----- 7 files changed, 50 insertions(+), 713 deletions(-) delete mode 100644 src/gallium/drivers/llvmpipe/lp_tile_image.c delete mode 100644 src/gallium/drivers/llvmpipe/lp_tile_image.h diff --git a/src/gallium/drivers/llvmpipe/Makefile.am b/src/gallium/drivers/llvmpipe/Makefile.am index f1ba5d1..9059053 100644 --- a/src/gallium/drivers/llvmpipe/Makefile.am +++ b/src/gallium/drivers/llvmpipe/Makefile.am @@ -72,8 +72,7 @@ libllvmpipe_la_SOURCES = \ lp_state_vs.c \ lp_surface.c \ lp_tex_sample.c \ - lp_texture.c \ - lp_tile_image.c + lp_texture.c libllvmpipe_la_LDFLAGS = $(LLVM_LDFLAGS) diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index a81cf23..22314c2 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -52,8 +52,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_state_vs.c', 'lp_surface.c', 'lp_tex_sample.c', - 'lp_texture.c', - 'lp_tile_image.c', + 'lp_texture.c' ]) env.Alias('llvmpipe', llvmpipe) diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index 7d01da1..85febff 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -36,10 +36,12 @@ #include "lp_scene.h" #include "lp_state.h" #include "lp_texture.h" -#include "lp_tile_image.h" #include "lp_limits.h" +#define TILE_VECTOR_HEIGHT 4 +#define TILE_VECTOR_WIDTH 4 + /* If we crash in a jitted function, we can examine jit_line and jit_state * to get some info. This is not thread-safe, however. */ diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 0804619..d10a4ce 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -46,7 +46,6 @@ #include "lp_context.h" #include "lp_flush.h" #include "lp_screen.h" -#include "lp_tile_image.h" #include "lp_texture.h" #include "lp_setup.h" #include "lp_state.h" @@ -334,11 +333,6 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen, struct sw_winsys *winsys = screen->winsys; winsys->displaytarget_destroy(winsys, lpr->dt); - if (lpr->tiled_img.data) { - align_free(lpr->tiled_img.data); - lpr->tiled_img.data = NULL; - } - FREE(lpr->layout[0]); } else if (llvmpipe_resource_is_texture(pt)) { @@ -351,12 +345,6 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen, lpr->linear_img.data = NULL; } - /* free tiled image data */ - if (lpr->tiled_img.data) { - align_free(lpr->tiled_img.data); - lpr->tiled_img.data = NULL; - } - /* free layout flag arrays */ for (level = 0; level < Elements(lpr->layout); level++) { FREE(lpr->layout[level]); @@ -398,7 +386,6 @@ llvmpipe_resource_map(struct pipe_resource *resource, tex_usage == LP_TEX_USAGE_WRITE_ALL); assert(layout == LP_TEX_LAYOUT_NONE || - layout == LP_TEX_LAYOUT_TILED || layout == LP_TEX_LAYOUT_LINEAR); if (lpr->dt) { @@ -850,27 +837,10 @@ static unsigned tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level, enum lp_texture_layout layout) { - const unsigned width = u_minify(lpr->base.width0, level); - const unsigned height = u_minify(lpr->base.height0, level); - - assert(layout == LP_TEX_LAYOUT_TILED || - layout == LP_TEX_LAYOUT_LINEAR); + assert(layout == LP_TEX_LAYOUT_LINEAR); - if (layout == LP_TEX_LAYOUT_TILED) { - /* for tiled layout, force a 32bpp format */ - const enum pipe_format format = PIPE_FORMAT_B8G8R8A8_UNORM; - const unsigned block_size = util_format_get_blocksize(format); - const unsigned nblocksy = - util_format_get_nblocksy(format, align(height, TILE_SIZE)); - const unsigned nblocksx = - util_format_get_nblocksx(format, align(width, TILE_SIZE)); - const unsigned buffer_size = block_size * nblocksy * nblocksx; - return buffer_size; - } - else { - /* we already computed this */ - return lpr->img_stride[level]; - } + /* we already computed this */ + return lpr->img_stride[level]; } @@ -888,65 +858,6 @@ tex_image_size(const struct llvmpipe_resource *lpr, unsigned level, /** - * 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. - * \param cur_layout the current tile layout - * \param target_layout the desired tile layout - * \param usage how the tile will be accessed (R/W vs. read-only, etc) - * \param new_layout_return returns the new layout mode - * \param convert_return returns TRUE if image conversion is needed - */ -static void -layout_logic(enum lp_texture_layout cur_layout, - enum lp_texture_layout target_layout, - enum lp_texture_usage usage, - enum lp_texture_layout *new_layout_return, - boolean *convert) -{ - enum lp_texture_layout other_layout, new_layout; - - *convert = FALSE; - - new_layout = 99; /* debug check */ - - if (target_layout == LP_TEX_LAYOUT_LINEAR) { - other_layout = LP_TEX_LAYOUT_TILED; - } - else { - assert(target_layout == LP_TEX_LAYOUT_TILED); - other_layout = LP_TEX_LAYOUT_LINEAR; - } - - new_layout = target_layout; /* may get changed below */ - - if (cur_layout == LP_TEX_LAYOUT_BOTH) { - if (usage == LP_TEX_USAGE_READ) { - new_layout = LP_TEX_LAYOUT_BOTH; - } - } - else if (cur_layout == other_layout) { - if (usage != LP_TEX_USAGE_WRITE_ALL) { - /* need to convert tiled data to linear or vice versa */ - *convert = TRUE; - - if (usage == LP_TEX_USAGE_READ) - new_layout = LP_TEX_LAYOUT_BOTH; - } - } - else { - assert(cur_layout == LP_TEX_LAYOUT_NONE || - cur_layout == target_layout); - } - - assert(new_layout == LP_TEX_LAYOUT_BOTH || - new_layout == target_layout); - - *new_layout_return = new_layout; -} - - -/** * Return pointer to a 2D texture image/face/slice. * No tiled/linear conversion is done. */ @@ -958,15 +869,10 @@ llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr, struct llvmpipe_texture_image *img; unsigned offset; - if (layout == LP_TEX_LAYOUT_LINEAR) { - img = &lpr->linear_img; - offset = lpr->linear_mip_offsets[level]; - } - else { - assert (layout == LP_TEX_LAYOUT_TILED); - img = &lpr->tiled_img; - offset = lpr->tiled_mip_offsets[level]; - } + assert (layout == LP_TEX_LAYOUT_LINEAR); + + img = &lpr->linear_img; + offset = lpr->linear_mip_offsets[level]; if (face_slice > 0) offset += face_slice * tex_image_face_size(lpr, level, layout); @@ -975,35 +881,6 @@ llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr, } -static INLINE enum lp_texture_layout -llvmpipe_get_texture_tile_layout(const struct llvmpipe_resource *lpr, - unsigned face_slice, unsigned level, - unsigned x, unsigned y) -{ - uint i; - assert(llvmpipe_resource_is_texture(&lpr->base)); - assert(x < lpr->tiles_per_row[level]); - i = face_slice * lpr->tiles_per_image[level] - + y * lpr->tiles_per_row[level] + x; - return lpr->layout[level][i]; -} - - -static INLINE void -llvmpipe_set_texture_tile_layout(struct llvmpipe_resource *lpr, - unsigned face_slice, unsigned level, - unsigned x, unsigned y, - enum lp_texture_layout layout) -{ - uint i; - assert(llvmpipe_resource_is_texture(&lpr->base)); - assert(x < lpr->tiles_per_row[level]); - i = face_slice * lpr->tiles_per_image[level] - + y * lpr->tiles_per_row[level] + x; - lpr->layout[level][i] = layout; -} - - /** * Set the layout mode for all tiles in a particular image. */ @@ -1034,49 +911,36 @@ alloc_image_data(struct llvmpipe_resource *lpr, uint level; uint offset = 0; - if (lpr->dt) + assert(layout == LP_TEX_LAYOUT_LINEAR); + + + if (lpr->dt) { + /* we get the linear memory from the winsys, and it has + * already been zeroed + */ + struct llvmpipe_screen *screen = llvmpipe_screen(lpr->base.screen); + struct sw_winsys *winsys = screen->winsys; + assert(lpr->base.last_level == 0); - if (layout == LP_TEX_LAYOUT_TILED) { - /* tiled data is stored in regular memory */ - for (level = 0; level <= lpr->base.last_level; level++) { - uint buffer_size = tex_image_size(lpr, level, layout); - lpr->tiled_mip_offsets[level] = offset; - offset += align(buffer_size, alignment); - } - lpr->tiled_img.data = align_malloc(offset, alignment); - if (lpr->tiled_img.data) { - memset(lpr->tiled_img.data, 0, offset); - } + lpr->linear_img.data = + winsys->displaytarget_map(winsys, lpr->dt, + PIPE_TRANSFER_READ_WRITE); } else { - assert(layout == LP_TEX_LAYOUT_LINEAR); - if (lpr->dt) { - /* we get the linear memory from the winsys, and it has - * already been zeroed - */ - struct llvmpipe_screen *screen = llvmpipe_screen(lpr->base.screen); - struct sw_winsys *winsys = screen->winsys; - - lpr->linear_img.data = - winsys->displaytarget_map(winsys, lpr->dt, - PIPE_TRANSFER_READ_WRITE); + /* not a display target - allocate regular memory */ + /* + * Offset calculation for start of a specific mip/layer is always + * offset = lpr->linear_mip_offsets[level] + lpr->img_stride[level] * layer + */ + for (level = 0; level <= lpr->base.last_level; level++) { + uint buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_LINEAR); + lpr->linear_mip_offsets[level] = offset; + offset += align(buffer_size, alignment); } - else { - /* not a display target - allocate regular memory */ - /* - * Offset calculation for start of a specific mip/layer is always - * offset = lpr->linear_mip_offsets[level] + lpr->img_stride[level] * layer - */ - for (level = 0; level <= lpr->base.last_level; level++) { - uint buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_LINEAR); - lpr->linear_mip_offsets[level] = offset; - offset += align(buffer_size, alignment); - } - lpr->linear_img.data = align_malloc(offset, alignment); - if (lpr->linear_img.data) { - memset(lpr->linear_img.data, 0, offset); - } + lpr->linear_img.data = align_malloc(offset, alignment); + if (lpr->linear_img.data) { + memset(lpr->linear_img.data, 0, offset); } } } @@ -1084,12 +948,12 @@ alloc_image_data(struct llvmpipe_resource *lpr, /** - * Return pointer to texture image data (either linear or tiled layout) + * Return pointer to texture image data * for a particular cube face or 3D texture slice. * * \param face_slice the cube face or 3D slice of interest * \param usage one of LP_TEX_USAGE_READ/WRITE_ALL/READ_WRITE - * \param layout either LP_TEX_LAYOUT_LINEAR or _TILED or _NONE + * \param layout should be LP_TEX_LAYOUT_LINEAR */ void * llvmpipe_get_texture_image(struct llvmpipe_resource *lpr, @@ -1097,27 +961,16 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr, enum lp_texture_usage usage, enum lp_texture_layout layout) { - /* - * 'target' refers to the image which we're retrieving (either in - * tiled or linear layout). - * 'other' refers to the same image but in the other layout. (it may - * or may not exist. - */ struct llvmpipe_texture_image *target_img; - struct llvmpipe_texture_image *other_img; void *target_data; - void *other_data; const unsigned width = u_minify(lpr->base.width0, level); const unsigned height = u_minify(lpr->base.height0, level); const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE; const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE; - unsigned target_offset, other_offset; - unsigned *target_off_ptr, *other_off_ptr; - enum lp_texture_layout other_layout; - boolean only_allocate; + unsigned target_offset; + unsigned *target_off_ptr; assert(layout == LP_TEX_LAYOUT_NONE || - layout == LP_TEX_LAYOUT_TILED || layout == LP_TEX_LAYOUT_LINEAR); assert(usage == LP_TEX_USAGE_READ || @@ -1126,35 +979,17 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr, /* check for the special case of layout == LP_TEX_LAYOUT_NONE */ if (layout == LP_TEX_LAYOUT_NONE) { - only_allocate = TRUE; - layout = LP_TEX_LAYOUT_TILED; - } - else { - only_allocate = FALSE; + /* XXX can still get LAYOUT_NONE ? */ + layout = LP_TEX_LAYOUT_LINEAR; } if (lpr->dt) { assert(lpr->linear_img.data); } - /* which is target? which is other? */ - if (layout == LP_TEX_LAYOUT_LINEAR) { - target_img = &lpr->linear_img; - target_off_ptr = lpr->linear_mip_offsets; - other_img = &lpr->tiled_img; - other_off_ptr = lpr->tiled_mip_offsets; - other_layout = LP_TEX_LAYOUT_TILED; - } - else { - target_img = &lpr->tiled_img; - target_off_ptr = lpr->tiled_mip_offsets; - other_img = &lpr->linear_img; - other_off_ptr = lpr->linear_mip_offsets; - other_layout = LP_TEX_LAYOUT_LINEAR; - } - + target_img = &lpr->linear_img; + target_off_ptr = lpr->linear_mip_offsets; target_data = target_img->data; - other_data = other_img->data; if (!target_data) { /* allocate memory for the target image now */ @@ -1163,72 +998,17 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr, } target_offset = target_off_ptr[level]; - other_offset = other_off_ptr[level]; if (face_slice > 0) { target_offset += face_slice * tex_image_face_size(lpr, level, layout); - other_offset += face_slice * tex_image_face_size(lpr, level, other_layout); } if (target_data) { target_data = (uint8_t *) target_data + target_offset; } - if (other_data) { - other_data = (uint8_t *) other_data + other_offset; - } - if (only_allocate) { - /* Just allocating tiled memory. Don't initialize it from the - * linear data if it exists. - */ - return target_data; - } - - if (other_data) { - /* may need to convert other data to the requested layout */ - enum lp_texture_layout new_layout; - unsigned x, y; - - /* loop over all image tiles, doing layout conversion where needed */ - for (y = 0; y < height_t; y++) { - for (x = 0; x < width_t; x++) { - enum lp_texture_layout cur_layout = - llvmpipe_get_texture_tile_layout(lpr, face_slice, level, x, y); - boolean convert; - - layout_logic(cur_layout, layout, usage, &new_layout, &convert); - - if (convert && other_data && target_data) { - if (layout == LP_TEX_LAYOUT_TILED) { - lp_linear_to_tiled(other_data, target_data, - x * TILE_SIZE, y * TILE_SIZE, - TILE_SIZE, TILE_SIZE, - lpr->base.format, - lpr->row_stride[level], - lpr->tiles_per_row[level]); - } - else { - assert(layout == LP_TEX_LAYOUT_LINEAR); - lp_tiled_to_linear(other_data, target_data, - x * TILE_SIZE, y * TILE_SIZE, - TILE_SIZE, TILE_SIZE, - lpr->base.format, - lpr->row_stride[level], - lpr->tiles_per_row[level]); - } - } - - if (new_layout != cur_layout) - llvmpipe_set_texture_tile_layout(lpr, face_slice, level, x, y, - new_layout); - } - } - } - else { - /* no other data */ - llvmpipe_set_texture_image_layout(lpr, face_slice, level, - width_t, height_t, layout); - } + llvmpipe_set_texture_image_layout(lpr, face_slice, level, + width_t, height_t, layout); return target_data; } @@ -1273,10 +1053,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr, unsigned x, unsigned y) { struct llvmpipe_texture_image *linear_img = &lpr->linear_img; - enum lp_texture_layout cur_layout, new_layout; - const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE; - boolean convert; - uint8_t *tiled_image, *linear_image; + uint8_t *linear_image; assert(llvmpipe_resource_is_texture(&lpr->base)); assert(x % TILE_SIZE == 0); @@ -1284,92 +1061,20 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr, if (!linear_img->data) { /* allocate memory for the linear image now */ + /* XXX should probably not do that here? */ alloc_image_data(lpr, LP_TEX_LAYOUT_LINEAR); } + assert(linear_img->data); /* compute address of the slice/face of the image that contains the tile */ - tiled_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, - LP_TEX_LAYOUT_TILED); linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, LP_TEX_LAYOUT_LINEAR); - /* get current tile layout and determine if data conversion is needed */ - cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty); - - layout_logic(cur_layout, LP_TEX_LAYOUT_LINEAR, usage, - &new_layout, &convert); - - if (convert && tiled_image && linear_image) { - lp_tiled_to_linear(tiled_image, linear_image, - x, y, TILE_SIZE, TILE_SIZE, lpr->base.format, - lpr->row_stride[level], - lpr->tiles_per_row[level]); - } - - if (new_layout != cur_layout) - llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout); - return linear_image; } /** - * Get pointer to tiled data for rendering. - * \return pointer to the tiled data at the given tile position - */ -ubyte * -llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr, - unsigned face_slice, unsigned level, - enum lp_texture_usage usage, - unsigned x, unsigned y) -{ - struct llvmpipe_texture_image *tiled_img = &lpr->tiled_img; - enum lp_texture_layout cur_layout, new_layout; - const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE; - boolean convert; - uint8_t *tiled_image, *linear_image; - unsigned tile_offset; - - assert(x % TILE_SIZE == 0); - assert(y % TILE_SIZE == 0); - - if (!tiled_img->data) { - /* allocate memory for the tiled image now */ - alloc_image_data(lpr, LP_TEX_LAYOUT_TILED); - } - - /* compute address of the slice/face of the image that contains the tile */ - tiled_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, - LP_TEX_LAYOUT_TILED); - linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level, - LP_TEX_LAYOUT_LINEAR); - - /* get current tile layout and see if we need to convert the data */ - cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty); - - layout_logic(cur_layout, LP_TEX_LAYOUT_TILED, usage, &new_layout, &convert); - if (convert && linear_image && tiled_image) { - lp_linear_to_tiled(linear_image, tiled_image, - x, y, TILE_SIZE, TILE_SIZE, lpr->base.format, - lpr->row_stride[level], - lpr->tiles_per_row[level]); - } - - if (!tiled_image) - return NULL; - - if (new_layout != cur_layout) - llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout); - - /* compute, return address of the 64x64 tile */ - tile_offset = (ty * lpr->tiles_per_row[level] + tx) - * TILE_SIZE * TILE_SIZE * 4; - - return (ubyte *) tiled_image + tile_offset; -} - - -/** * Return size of resource in bytes */ unsigned @@ -1382,9 +1087,6 @@ llvmpipe_resource_size(const struct pipe_resource *resource) for (lvl = 0; lvl <= lpr->base.last_level; lvl++) { if (lpr->linear_img.data) size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_LINEAR); - - if (lpr->tiled_img.data) - size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_TILED); } } else { diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index c046902..4ab6903 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -46,9 +46,7 @@ enum lp_texture_usage enum lp_texture_layout { LP_TEX_LAYOUT_NONE = 0, /**< no layout for the tile data yet */ - LP_TEX_LAYOUT_TILED, /**< the tile data is in tiled layout */ LP_TEX_LAYOUT_LINEAR, /**< the tile data is in linear layout */ - LP_TEX_LAYOUT_BOTH /**< the tile data is in both modes */ }; @@ -95,7 +93,6 @@ struct llvmpipe_resource /** Number of 3D slices or cube faces per level */ unsigned num_slices_faces[LP_MAX_TEXTURE_LEVELS]; /** Offset to start of mipmap level, in bytes */ - unsigned tiled_mip_offsets[LP_MAX_TEXTURE_LEVELS]; unsigned linear_mip_offsets[LP_MAX_TEXTURE_LEVELS]; /** @@ -107,7 +104,6 @@ struct llvmpipe_resource /** * Malloc'ed data for regular textures, or a mapping to dt above. */ - struct llvmpipe_texture_image tiled_img; struct llvmpipe_texture_image linear_img; /** @@ -239,12 +235,6 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr, enum lp_texture_usage usage, unsigned x, unsigned y); -ubyte * -llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr, - unsigned face_slice, unsigned level, - enum lp_texture_usage usage, - unsigned x, unsigned y); - extern void llvmpipe_print_resources(void); diff --git a/src/gallium/drivers/llvmpipe/lp_tile_image.c b/src/gallium/drivers/llvmpipe/lp_tile_image.c deleted file mode 100644 index 3faf018..0000000 --- a/src/gallium/drivers/llvmpipe/lp_tile_image.c +++ /dev/null @@ -1,294 +0,0 @@ -/************************************************************************** - * - * Copyright 2010 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -/** - * Code to convert images from tiled to linear and back. - * XXX there are quite a few assumptions about color and z/stencil being - * 32bpp. - */ - - -#include "util/u_format.h" -#include "util/u_memory.h" -#include "lp_limits.h" -#include "lp_tile_image.h" - - -#define BYTES_PER_TILE (TILE_SIZE * TILE_SIZE * 4) - - -/** - * Untile a 4x4 block of 32-bit words (all contiguous) to linear layout - * at dst, with dst_stride words between rows. - */ -static void -untile_4_4_uint32(const uint32_t *src, uint32_t *dst, unsigned dst_stride) -{ - uint32_t *d0 = dst; - uint32_t *d1 = d0 + dst_stride; - uint32_t *d2 = d1 + dst_stride; - uint32_t *d3 = d2 + dst_stride; - - d0[0] = src[0]; d0[1] = src[1]; d0[2] = src[4]; d0[3] = src[5]; - d1[0] = src[2]; d1[1] = src[3]; d1[2] = src[6]; d1[3] = src[7]; - d2[0] = src[8]; d2[1] = src[9]; d2[2] = src[12]; d2[3] = src[13]; - d3[0] = src[10]; d3[1] = src[11]; d3[2] = src[14]; d3[3] = src[15]; -} - - - -/** - * Untile a 4x4 block of 16-bit words (all contiguous) to linear layout - * at dst, with dst_stride words between rows. - */ -static void -untile_4_4_uint16(const uint16_t *src, uint16_t *dst, unsigned dst_stride) -{ - uint16_t *d0 = dst; - uint16_t *d1 = d0 + dst_stride; - uint16_t *d2 = d1 + dst_stride; - uint16_t *d3 = d2 + dst_stride; - - d0[0] = src[0]; d0[1] = src[1]; d0[2] = src[4]; d0[3] = src[5]; - d1[0] = src[2]; d1[1] = src[3]; d1[2] = src[6]; d1[3] = src[7]; - d2[0] = src[8]; d2[1] = src[9]; d2[2] = src[12]; d2[3] = src[13]; - d3[0] = src[10]; d3[1] = src[11]; d3[2] = src[14]; d3[3] = src[15]; -} - - - -/** - * Convert a 4x4 rect of 32-bit words from a linear layout into tiled - * layout (in which all 16 words are contiguous). - */ -static void -tile_4_4_uint32(const uint32_t *src, uint32_t *dst, unsigned src_stride) -{ - const uint32_t *s0 = src; - const uint32_t *s1 = s0 + src_stride; - const uint32_t *s2 = s1 + src_stride; - const uint32_t *s3 = s2 + src_stride; - - dst[0] = s0[0]; dst[1] = s0[1]; dst[4] = s0[2]; dst[5] = s0[3]; - dst[2] = s1[0]; dst[3] = s1[1]; dst[6] = s1[2]; dst[7] = s1[3]; - dst[8] = s2[0]; dst[9] = s2[1]; dst[12] = s2[2]; dst[13] = s2[3]; - dst[10] = s3[0]; dst[11] = s3[1]; dst[14] = s3[2]; dst[15] = s3[3]; -} - - - -/** - * Convert a 4x4 rect of 16-bit words from a linear layout into tiled - * layout (in which all 16 words are contiguous). - */ -static void -tile_4_4_uint16(const uint16_t *src, uint16_t *dst, unsigned src_stride) -{ - const uint16_t *s0 = src; - const uint16_t *s1 = s0 + src_stride; - const uint16_t *s2 = s1 + src_stride; - const uint16_t *s3 = s2 + src_stride; - - dst[0] = s0[0]; dst[1] = s0[1]; dst[4] = s0[2]; dst[5] = s0[3]; - dst[2] = s1[0]; dst[3] = s1[1]; dst[6] = s1[2]; dst[7] = s1[3]; - dst[8] = s2[0]; dst[9] = s2[1]; dst[12] = s2[2]; dst[13] = s2[3]; - dst[10] = s3[0]; dst[11] = s3[1]; dst[14] = s3[2]; dst[15] = s3[3]; -} - - - -/** - * Convert a tiled image into a linear image. - * \param dst_stride dest row stride in bytes - */ -void -lp_tiled_to_linear(const void *src, void *dst, - unsigned x, unsigned y, - unsigned width, unsigned height, - enum pipe_format format, - unsigned dst_stride, - unsigned tiles_per_row) -{ - assert(x % TILE_SIZE == 0); - assert(y % TILE_SIZE == 0); - /*assert(width % TILE_SIZE == 0); - assert(height % TILE_SIZE == 0);*/ - - /* Note that Z/stencil surfaces use a different tiling size than - * color surfaces. - */ - if (util_format_is_depth_or_stencil(format)) { - const uint bpp = util_format_get_blocksize(format); - const uint src_stride = dst_stride * TILE_VECTOR_WIDTH; - const uint tile_w = TILE_VECTOR_WIDTH, tile_h = TILE_VECTOR_HEIGHT; - const uint tiles_per_row = src_stride / (tile_w * tile_h * bpp); - - dst_stride /= bpp; /* convert from bytes to words */ - - if (bpp == 4) { - const uint32_t *src32 = (const uint32_t *) src; - uint32_t *dst32 = (uint32_t *) dst; - uint i, j; - - for (j = 0; j < height; j += tile_h) { - for (i = 0; i < width; i += tile_w) { - /* compute offsets in 32-bit words */ - uint ii = i + x, jj = j + y; - uint src_offset = (jj / tile_h * tiles_per_row + ii / tile_w) - * (tile_w * tile_h); - uint dst_offset = jj * dst_stride + ii; - untile_4_4_uint32(src32 + src_offset, - dst32 + dst_offset, - dst_stride); - } - } - } - else { - const uint16_t *src16 = (const uint16_t *) src; - uint16_t *dst16 = (uint16_t *) dst; - uint i, j; - - assert(bpp == 2); - - for (j = 0; j < height; j += tile_h) { - for (i = 0; i < width; i += tile_w) { - /* compute offsets in 16-bit words */ - uint ii = i + x, jj = j + y; - uint src_offset = (jj / tile_h * tiles_per_row + ii / tile_w) - * (tile_w * tile_h); - uint dst_offset = jj * dst_stride + ii; - untile_4_4_uint16(src16 + src_offset, - dst16 + dst_offset, - dst_stride); - } - } - } - } - else { - assert(0); - } -} - - -/** - * Convert a linear image into a tiled image. - * \param src_stride source row stride in bytes - */ -void -lp_linear_to_tiled(const void *src, void *dst, - unsigned x, unsigned y, - unsigned width, unsigned height, - enum pipe_format format, - unsigned src_stride, - unsigned tiles_per_row) -{ - assert(x % TILE_SIZE == 0); - assert(y % TILE_SIZE == 0); - /* - assert(width % TILE_SIZE == 0); - assert(height % TILE_SIZE == 0); - */ - - if (util_format_is_depth_or_stencil(format)) { - const uint bpp = util_format_get_blocksize(format); - const uint dst_stride = src_stride * TILE_VECTOR_WIDTH; - const uint tile_w = TILE_VECTOR_WIDTH, tile_h = TILE_VECTOR_HEIGHT; - const uint tiles_per_row = dst_stride / (tile_w * tile_h * bpp); - - src_stride /= bpp; /* convert from bytes to words */ - - if (bpp == 4) { - const uint32_t *src32 = (const uint32_t *) src; - uint32_t *dst32 = (uint32_t *) dst; - uint i, j; - - for (j = 0; j < height; j += tile_h) { - for (i = 0; i < width; i += tile_w) { - /* compute offsets in 32-bit words */ - uint ii = i + x, jj = j + y; - uint src_offset = jj * src_stride + ii; - uint dst_offset = (jj / tile_h * tiles_per_row + ii / tile_w) - * (tile_w * tile_h); - tile_4_4_uint32(src32 + src_offset, - dst32 + dst_offset, - src_stride); - } - } - } - else { - const uint16_t *src16 = (const uint16_t *) src; - uint16_t *dst16 = (uint16_t *) dst; - uint i, j; - - assert(bpp == 2); - - for (j = 0; j < height; j += tile_h) { - for (i = 0; i < width; i += tile_w) { - /* compute offsets in 16-bit words */ - uint ii = i + x, jj = j + y; - uint src_offset = jj * src_stride + ii; - uint dst_offset = (jj / tile_h * tiles_per_row + ii / tile_w) - * (tile_w * tile_h); - tile_4_4_uint16(src16 + src_offset, - dst16 + dst_offset, - src_stride); - } - } - } - } - else { - assert(0); - } -} - - -/** - * For testing only. - */ -void -test_tiled_linear_conversion(void *data, - enum pipe_format format, - unsigned width, unsigned height, - unsigned stride) -{ - /* size in tiles */ - unsigned wt = (width + TILE_SIZE - 1) / TILE_SIZE; - unsigned ht = (height + TILE_SIZE - 1) / TILE_SIZE; - - uint8_t *tiled = MALLOC(wt * ht * TILE_SIZE * TILE_SIZE * 4); - - /*unsigned tiled_stride = wt * TILE_SIZE * TILE_SIZE * 4;*/ - - lp_linear_to_tiled(data, tiled, 0, 0, width, height, format, - stride, wt); - - lp_tiled_to_linear(tiled, data, 0, 0, width, height, format, - stride, wt); - - FREE(tiled); -} - diff --git a/src/gallium/drivers/llvmpipe/lp_tile_image.h b/src/gallium/drivers/llvmpipe/lp_tile_image.h deleted file mode 100644 index 07d367c..0000000 --- a/src/gallium/drivers/llvmpipe/lp_tile_image.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************** - * - * Copyright 2010 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifndef LP_TILE_IMAGE_H -#define LP_TILE_IMAGE_H - - -#define TILE_VECTOR_HEIGHT 4 -#define TILE_VECTOR_WIDTH 4 - - -void -lp_tiled_to_linear(const void *src, void *dst, - unsigned x, unsigned y, - unsigned width, unsigned height, - enum pipe_format format, - unsigned dst_stride, - unsigned tiles_per_row); - - -void -lp_linear_to_tiled(const void *src, void *dst, - unsigned x, unsigned y, - unsigned width, unsigned height, - enum pipe_format format, - unsigned src_stride, - unsigned tiles_per_row); - - -void -test_tiled_linear_conversion(void *data, - enum pipe_format format, - unsigned width, unsigned height, - unsigned stride); - - -#endif /* LP_TILE_IMAGE_H */ -- 2.7.4