summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-04-02 16:15:16 -0600
committerBrian Paul <brianp@vmware.com>2010-04-02 16:15:16 -0600
commitfaa684645e64d6024b3a11e4e08da825e8220b2e (patch)
treefb76e3fe15e31b881e5a53d7058d13fa50ce5a8c
parent926a60033fc02b6e62a2ce7ae08575cd326561f2 (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.
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c101
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h14
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_image.c52
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_image.h2
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);