diff options
author | Brian Paul <brianp@vmware.com> | 2010-04-02 16:15:16 -0600 |
---|---|---|
committer | Brian Paul <brianp@vmware.com> | 2010-04-02 16:15:16 -0600 |
commit | faa684645e64d6024b3a11e4e08da825e8220b2e (patch) | |
tree | fb76e3fe15e31b881e5a53d7058d13fa50ce5a8c /src | |
parent | 926a60033fc02b6e62a2ce7ae08575cd326561f2 (diff) |
llvmpipe: assorted texture and tile/line conversion code change s
The tiled/linear conversion functions take x/y positions now to
allow converting only sub-regions.
More texture-related helper functions.
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_texture.c | 101 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_texture.h | 14 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_tile_image.c | 52 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_tile_image.h | 2 |
4 files changed, 147 insertions, 22 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 613d6c8f06..b32b59d5b4 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -30,6 +30,8 @@ * Michel Dänzer <michel@tungstengraphics.com> */ +#include <stdio.h> + #include "pipe/p_context.h" #include "pipe/p_defines.h" @@ -110,6 +112,7 @@ static struct pipe_texture * llvmpipe_texture_create(struct pipe_screen *_screen, const struct pipe_texture *templat) { + static unsigned id_counter = 0; struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture); if (!lpt) @@ -130,6 +133,8 @@ llvmpipe_texture_create(struct pipe_screen *_screen, goto fail; } + lpt->id = id_counter++; + return &lpt->base; fail: @@ -442,14 +447,23 @@ llvmpipe_transfer_map( struct pipe_context *pipe, ubyte *map; enum pipe_format format; enum lp_texture_usage tex_usage; + const char *mode; if (transfer->usage == PIPE_TRANSFER_READ) { tex_usage = LP_TEXTURE_READ; + mode = "read"; } else { tex_usage = LP_TEXTURE_READ_WRITE; + mode = "read/write"; } + if(0){ + struct llvmpipe_texture *lpt = llvmpipe_texture(transfer->texture); + printf("transfer map tex %u mode %s\n", lpt->id, mode); + } + + assert(transfer->texture); format = transfer->texture->format; @@ -576,14 +590,24 @@ llvmpipe_get_texture_image(struct llvmpipe_texture *lpt, const unsigned width = u_minify(lpt->base.width0, level); const unsigned height = u_minify(lpt->base.height0, level); - if (layout == LP_TEXTURE_LINEAR) + if (layout == LP_TEXTURE_LINEAR) { + /* + printf(" tex %u tiled to linear (%d x %d)\n", + lpt->id, width, height); + */ lp_tiled_to_linear(other_data, target_data, - width, height, lpt->base.format, + 0, 0, width, height, lpt->base.format, lpt->stride[level]); - else + } + else { + /* + printf(" tex %u linear to tiled (%d x %d)\n", + lpt->id, width, height); + */ lp_linear_to_tiled(other_data, target_data, - width, height, lpt->base.format, + 0, 0, width, height, lpt->base.format, lpt->stride[level]); + } /* target image is now equal to the other image */ target_img->timestamp = other_img->timestamp; @@ -605,6 +629,75 @@ llvmpipe_get_texture_image(struct llvmpipe_texture *lpt, } +/** + * Get pointer to tiled data for rendering. + */ +ubyte * +llvmpipe_get_texture_tile(struct llvmpipe_texture *lpt, + unsigned face, unsigned level, + enum lp_texture_usage usage, + unsigned x, unsigned y) +{ + const unsigned width = u_minify(lpt->base.width0, level); + const unsigned height = u_minify(lpt->base.height0, level); + struct llvmpipe_texture_image *tiled_img; + struct llvmpipe_texture_image *linear_img; + + assert(x % TILE_SIZE == 0); + assert(y % TILE_SIZE == 0); + + linear_img = &lpt->linear[face][level]; + tiled_img = &lpt->tiled[face][level]; + + if (linear_img->timestamp > tiled_img->timestamp) { + /* need to convert the linear data to tiled */ + + if (!tiled_img->data) { + /* allocate memory for the target image now */ + unsigned buffer_size = tex_image_size(lpt, level); + tiled_img->data = align_malloc(buffer_size, 16); + } + + if (usage != LP_TEXTURE_WRITE_ALL) + lp_linear_to_tiled(linear_img->data, tiled_img->data, + 0, 0, width, height, lpt->base.format, + lpt->stride[level]); + } + + /* compute, return address of the 64x64 tile */ + { + unsigned tiles_per_row, tx, ty, tile_offset; + + tiles_per_row = align(width, TILE_SIZE) / TILE_SIZE; + + tx = x / TILE_SIZE; + ty = y / TILE_SIZE; + tile_offset = ty * tiles_per_row + tx; + tile_offset *= TILE_SIZE * TILE_SIZE * 4; + + return (ubyte *) tiled_img->data + tile_offset; + } +} + + +enum lp_texture_layout +llvmpipe_get_texture_image_layout(const struct llvmpipe_texture *lpt, + unsigned face, unsigned level) +{ + const struct llvmpipe_texture_image *tiled_img; + const struct llvmpipe_texture_image *linear_img; + + linear_img = &lpt->linear[face][level]; + tiled_img = &lpt->tiled[face][level]; + + if (linear_img->data && linear_img->timestamp >= tiled_img->timestamp) + return LP_TEXTURE_LINEAR; + else + return LP_TEXTURE_TILED; +} + + + void llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen) { diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index e6e4146041..115bf96dbb 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -101,6 +101,8 @@ struct llvmpipe_texture struct llvmpipe_texture_image linear[PIPE_TEX_FACE_MAX][LP_MAX_TEXTURE_LEVELS]; unsigned timestamp; + + unsigned id; /**< temporary, for debugging */ }; @@ -165,6 +167,18 @@ llvmpipe_get_texture_image(struct llvmpipe_texture *texture, enum lp_texture_layout layout); +ubyte * +llvmpipe_get_texture_tile(struct llvmpipe_texture *lpt, + unsigned face, unsigned level, + enum lp_texture_usage usage, + unsigned x, unsigned y); + + +enum lp_texture_layout +llvmpipe_get_texture_image_layout(const struct llvmpipe_texture *lpt, + unsigned face, unsigned level); + + extern void llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen); diff --git a/src/gallium/drivers/llvmpipe/lp_tile_image.c b/src/gallium/drivers/llvmpipe/lp_tile_image.c index b5a32364a6..5f69aac5ef 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_image.c +++ b/src/gallium/drivers/llvmpipe/lp_tile_image.c @@ -127,9 +127,15 @@ tile_4_4_uint16(const uint16_t *src, uint16_t *dst, unsigned src_stride) */ 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) { + 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. */ @@ -149,9 +155,10 @@ lp_tiled_to_linear(const void *src, void *dst, for (j = 0; j < height; j += tile_h) { for (i = 0; i < width; i += tile_w) { /* compute offsets in 32-bit words */ - uint src_offset = - (j / tile_h * tiles_per_row + i / tile_w) * (tile_w * tile_h); - uint dst_offset = j * dst_stride + i; + 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); @@ -168,9 +175,10 @@ lp_tiled_to_linear(const void *src, void *dst, for (j = 0; j < height; j += tile_h) { for (i = 0; i < width; i += tile_w) { /* compute offsets in 16-bit words */ - uint src_offset = - (j / tile_h * tiles_per_row + i / tile_w) * (tile_w * tile_h); - uint dst_offset = j * dst_stride + i; + 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); @@ -189,15 +197,15 @@ lp_tiled_to_linear(const void *src, void *dst, for (j = 0; j < height; j += tile_h) { for (i = 0; i < width; i += tile_w) { - uint tile_offset = - ((j / tile_h) * tiles_per_row + i / tile_w); + uint ii = i + x, jj = j + y; + uint tile_offset = ((jj / tile_h) * tiles_per_row + ii / tile_w); uint byte_offset = tile_offset * bytes_per_tile; const uint8_t *src_tile = (uint8_t *) src + byte_offset; lp_tile_write_4ub(format, src_tile, dst, dst_stride, - i, j, tile_w, tile_h); + ii, jj, tile_w, tile_h); } } } @@ -211,9 +219,15 @@ lp_tiled_to_linear(const void *src, void *dst, */ 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) { + 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; @@ -230,8 +244,9 @@ lp_linear_to_tiled(const void *src, void *dst, for (j = 0; j < height; j += tile_h) { for (i = 0; i < width; i += tile_w) { /* compute offsets in 32-bit words */ - uint src_offset = j * src_stride + i; - uint dst_offset = (j / tile_h * tiles_per_row + i / tile_w) + 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, @@ -249,8 +264,9 @@ lp_linear_to_tiled(const void *src, void *dst, for (j = 0; j < height; j += tile_h) { for (i = 0; i < width; i += tile_w) { /* compute offsets in 16-bit words */ - uint src_offset = j * src_stride + i; - uint dst_offset = (j / tile_h * tiles_per_row + i / tile_w) + 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, @@ -269,15 +285,15 @@ lp_linear_to_tiled(const void *src, void *dst, for (j = 0; j < height; j += TILE_SIZE) { for (i = 0; i < width; i += TILE_SIZE) { - uint tile_offset = - ((j / tile_h) * tiles_per_row + i / tile_w); + uint ii = i + x, jj = j + y; + uint tile_offset = ((jj / tile_h) * tiles_per_row + ii / tile_w); uint byte_offset = tile_offset * bytes_per_tile; uint8_t *dst_tile = (uint8_t *) dst + byte_offset; lp_tile_read_4ub(format, dst_tile, src, src_stride, - i, j, tile_w, tile_h); + ii, jj, tile_w, tile_h); } } } @@ -301,10 +317,10 @@ test_tiled_linear_conversion(void *data, /*unsigned tiled_stride = wt * TILE_SIZE * TILE_SIZE * 4;*/ - lp_linear_to_tiled(data, tiled, width, height, format, + lp_linear_to_tiled(data, tiled, 0, 0, width, height, format, stride); - lp_tiled_to_linear(tiled, data, width, height, format, + lp_tiled_to_linear(tiled, data, 0, 0, width, height, format, stride); free(tiled); diff --git a/src/gallium/drivers/llvmpipe/lp_tile_image.h b/src/gallium/drivers/llvmpipe/lp_tile_image.h index ea50c5541f..d74621925d 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_image.h +++ b/src/gallium/drivers/llvmpipe/lp_tile_image.h @@ -31,12 +31,14 @@ 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); 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); |