summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorMichel Dänzer <daenzer@vmware.com>2009-02-05 19:41:18 +0100
committerMichel Dänzer <daenzer@vmware.com>2009-02-05 19:41:18 +0100
commit4617981ec72f7985941bee4b03c534d97ff96bc6 (patch)
treec3c8fb33499227cf4e3e905b3c04ff6599666663 /src/gallium
parente0c3b4970da052308bf7b4e5cbe9186a4b8321db (diff)
gallium: No longer allow CPU mapping surfaces directly.
Instead, a new pipe_transfer object has to be created and mapped for transferring data between the CPU and a texture. This gives the driver more flexibility for textures in address spaces that aren't CPU accessible. This is a first pass; softpipe/xlib builds and runs glxgears, but it only shows a black window. Looks like something's off related to the Z buffer, so the depth test always fails.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c17
-rw-r--r--src/gallium/auxiliary/util/p_debug.c59
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c125
-rw-r--r--src/gallium/auxiliary/util/u_rect.c110
-rw-r--r--src/gallium/auxiliary/util/u_tile.c127
-rw-r--r--src/gallium/auxiliary/util/u_tile.h18
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c12
-rw-r--r--src/gallium/drivers/softpipe/sp_draw_arrays.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c114
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h15
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c150
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h4
-rw-r--r--src/gallium/include/pipe/p_defines.h10
-rw-r--r--src/gallium/include/pipe/p_inlines.h23
-rw-r--r--src/gallium/include/pipe/p_screen.h24
-rw-r--r--src/gallium/include/pipe/p_state.h28
-rw-r--r--src/gallium/winsys/xlib/xlib_brw_aub.c10
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c9
21 files changed, 486 insertions, 391 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 20841bb5d6..80c9c918a9 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -410,7 +410,7 @@ aaline_create_texture(struct aaline_stage *aaline)
* texels which are zero. Special case the 1x1 and 2x2 levels.
*/
for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
- struct pipe_surface *surface;
+ struct pipe_transfer *transfer;
const uint size = aaline->texture->width[level];
ubyte *data;
uint i, j;
@@ -419,9 +419,9 @@ aaline_create_texture(struct aaline_stage *aaline)
/* This texture is new, no need to flush.
*/
- surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- data = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
+ transfer = screen->get_tex_transfer(screen, aaline->texture, 0, level, 0,
+ PIPE_TRANSFER_WRITE, 0, 0, size, size);
+ data = screen->transfer_map(screen, transfer);
if (data == NULL)
return FALSE;
@@ -440,13 +440,13 @@ aaline_create_texture(struct aaline_stage *aaline)
else {
d = 255;
}
- data[i * surface->stride + j] = d;
+ data[i * transfer->stride + j] = d;
}
}
/* unmap */
- screen->surface_unmap(screen, surface);
- screen->tex_surface_release(screen, &surface);
+ screen->transfer_unmap(screen, transfer);
+ screen->tex_transfer_release(screen, &transfer);
}
return TRUE;
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index b764d9c518..41910c6165 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -372,7 +372,7 @@ pstip_update_texture(struct pstip_stage *pstip)
static const uint bit31 = 1 << 31;
struct pipe_context *pipe = pstip->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *surface;
+ struct pipe_transfer *transfer;
const uint *stipple = pstip->state.stipple->stipple;
uint i, j;
ubyte *data;
@@ -381,10 +381,9 @@ pstip_update_texture(struct pstip_stage *pstip)
*/
pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL );
- surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- data = screen->surface_map(screen, surface,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ transfer = screen->get_tex_transfer(screen, pstip->texture, 0, 0, 0,
+ PIPE_TRANSFER_WRITE, 0, 0, 32, 32);
+ data = screen->transfer_map(screen, transfer);
/*
* Load alpha texture.
@@ -396,18 +395,18 @@ pstip_update_texture(struct pstip_stage *pstip)
for (j = 0; j < 32; j++) {
if (stipple[i] & (bit31 >> j)) {
/* fragment "on" */
- data[i * surface->stride + j] = 0;
+ data[i * transfer->stride + j] = 0;
}
else {
/* fragment "off" */
- data[i * surface->stride + j] = 255;
+ data[i * transfer->stride + j] = 255;
}
}
}
/* unmap */
- screen->surface_unmap(screen, surface);
- screen->tex_surface_release(screen, &surface);
+ screen->transfer_unmap(screen, transfer);
+ screen->tex_transfer_release(screen, &transfer);
}
diff --git a/src/gallium/auxiliary/util/p_debug.c b/src/gallium/auxiliary/util/p_debug.c
index f373f941dd..2a716c4e30 100644
--- a/src/gallium/auxiliary/util/p_debug.c
+++ b/src/gallium/auxiliary/util/p_debug.c
@@ -643,34 +643,37 @@ void debug_dump_image(const char *prefix,
void debug_dump_surface(const char *prefix,
struct pipe_surface *surface)
{
- unsigned surface_usage;
+ struct pipe_texture *texture;
+ struct pipe_screen *screen;
+ struct pipe_transfer *transfer;
void *data;
if (!surface)
- goto error1;
+ return;
+
+ texture = surface->texture;
+ screen = texture->screen;
- /* XXX: force mappable surface */
- surface_usage = surface->usage;
- surface->usage |= PIPE_BUFFER_USAGE_CPU_READ;
+ transfer = screen->get_tex_transfer(screen, texture, surface->face,
+ surface->level, surface->zslice,
+ PIPE_TRANSFER_READ, 0, 0, surface->width,
+ surface->height);
- data = pipe_surface_map(surface,
- PIPE_BUFFER_USAGE_CPU_READ);
+ data = screen->transfer_map(screen, transfer);
if(!data)
- goto error2;
+ goto error;
debug_dump_image(prefix,
- surface->format,
- surface->block.size,
- surface->nblocksx,
- surface->nblocksy,
- surface->stride,
+ transfer->format,
+ transfer->block.size,
+ transfer->nblocksx,
+ transfer->nblocksy,
+ transfer->stride,
data);
- pipe_surface_unmap(surface);
-error2:
- surface->usage = surface_usage;
-error1:
- ;
+ screen->transfer_unmap(screen, transfer);
+error:
+ screen->tex_transfer_release(screen, &transfer);
}
@@ -710,8 +713,10 @@ debug_dump_surface_bmp(const char *filename,
struct pipe_surface *surface)
{
#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
+ struct pipe_texture *texture;
+ struct pipe_screen *screen;
struct util_stream *stream;
- unsigned surface_usage;
+ struct pipe_transfer *transfer;
struct bmp_file_header bmfh;
struct bmp_info_header bmih;
float *rgba;
@@ -748,14 +753,18 @@ debug_dump_surface_bmp(const char *filename,
util_stream_write(stream, &bmfh, 14);
util_stream_write(stream, &bmih, 40);
+
+ texture = surface->texture;
+ screen = texture->screen;
- /* XXX: force mappable surface */
- surface_usage = surface->usage;
- surface->usage |= PIPE_BUFFER_USAGE_CPU_READ;
+ transfer = screen->get_tex_transfer(screen, texture, surface->face,
+ surface->level, surface->zslice,
+ PIPE_TRANSFER_READ, 0, 0, surface->width,
+ surface->height);
y = surface->height;
while(y--) {
- pipe_get_tile_rgba(surface,
+ pipe_get_tile_rgba(transfer,
0, y, surface->width, 1,
rgba);
for(x = 0; x < surface->width; ++x)
@@ -768,9 +777,9 @@ debug_dump_surface_bmp(const char *filename,
util_stream_write(stream, &pixel, 4);
}
}
-
- surface->usage = surface_usage;
+ screen->tex_transfer_release(screen, &transfer);
+
util_stream_close(stream);
error2:
FREE(rgba);
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 2b4cdab6cf..47dd3fc61f 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1116,31 +1116,30 @@ make_1d_mipmap(struct gen_mipmap_state *ctx,
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
- struct pipe_surface *srcSurf, *dstSurf;
+ struct pipe_transfer *srcTrans, *dstTrans;
void *srcMap, *dstMap;
- srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
- PIPE_BUFFER_USAGE_CPU_READ);
-
- dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
- PIPE_BUFFER_USAGE_CPU_WRITE);
-
- srcMap = ((ubyte *) pipe_surface_map(srcSurf,
- PIPE_BUFFER_USAGE_CPU_READ)
- + srcSurf->offset);
- dstMap = ((ubyte *) pipe_surface_map(dstSurf,
- PIPE_BUFFER_USAGE_CPU_WRITE)
- + dstSurf->offset);
+ srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
+ PIPE_TRANSFER_READ, 0, 0,
+ pt->width[srcLevel],
+ pt->height[srcLevel]);
+ dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ pt->width[dstLevel],
+ pt->height[dstLevel]);
+
+ srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
+ dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
reduce_1d(pt->format,
- srcSurf->width, srcMap,
- dstSurf->width, dstMap);
+ srcTrans->width, srcMap,
+ dstTrans->width, dstMap);
- pipe_surface_unmap(srcSurf);
- pipe_surface_unmap(dstSurf);
+ screen->transfer_unmap(screen, srcTrans);
+ screen->transfer_unmap(screen, dstTrans);
- pipe_surface_reference(&srcSurf, NULL);
- pipe_surface_reference(&dstSurf, NULL);
+ screen->tex_transfer_release(screen, &srcTrans);
+ screen->tex_transfer_release(screen, &dstTrans);
}
}
@@ -1160,32 +1159,32 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
- struct pipe_surface *srcSurf, *dstSurf;
+ struct pipe_transfer *srcTrans, *dstTrans;
ubyte *srcMap, *dstMap;
- srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
- PIPE_BUFFER_USAGE_CPU_READ);
- dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
- PIPE_BUFFER_USAGE_CPU_WRITE);
-
- srcMap = ((ubyte *) pipe_surface_map(srcSurf,
- PIPE_BUFFER_USAGE_CPU_READ)
- + srcSurf->offset);
- dstMap = ((ubyte *) pipe_surface_map(dstSurf,
- PIPE_BUFFER_USAGE_CPU_WRITE)
- + dstSurf->offset);
+ srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
+ PIPE_TRANSFER_READ, 0, 0,
+ pt->width[srcLevel],
+ pt->height[srcLevel]);
+ dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ pt->width[dstLevel],
+ pt->height[dstLevel]);
+
+ srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
+ dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
reduce_2d(pt->format,
- srcSurf->width, srcSurf->height,
- srcSurf->stride, srcMap,
- dstSurf->width, dstSurf->height,
- dstSurf->stride, dstMap);
+ srcTrans->width, srcTrans->height,
+ srcTrans->stride, srcMap,
+ dstTrans->width, dstTrans->height,
+ dstTrans->stride, dstMap);
- pipe_surface_unmap(srcSurf);
- pipe_surface_unmap(dstSurf);
+ screen->transfer_unmap(screen, srcTrans);
+ screen->transfer_unmap(screen, dstTrans);
- pipe_surface_reference(&srcSurf, NULL);
- pipe_surface_reference(&dstSurf, NULL);
+ screen->tex_transfer_release(screen, &srcTrans);
+ screen->tex_transfer_release(screen, &dstTrans);
}
}
@@ -1195,6 +1194,7 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_texture *pt,
uint face, uint baseLevel, uint lastLevel)
{
+#if 0
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
uint dstLevel, zslice = 0;
@@ -1204,37 +1204,36 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
- struct pipe_surface *srcSurf, *dstSurf;
+ struct pipe_transfer *srcTrans, *dstTrans;
ubyte *srcMap, *dstMap;
- srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice,
- PIPE_BUFFER_USAGE_CPU_READ);
- dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice,
- PIPE_BUFFER_USAGE_CPU_WRITE);
-
- srcMap = ((ubyte *) pipe_surface_map(srcSurf,
- PIPE_BUFFER_USAGE_CPU_READ)
- + srcSurf->offset);
- dstMap = ((ubyte *) pipe_surface_map(dstSurf,
- PIPE_BUFFER_USAGE_CPU_WRITE)
- + dstSurf->offset);
+ srcTrans = screen->get_tex_transfer(screen, pt, face, srcLevel, zslice,
+ PIPE_TRANSFER_READ, 0, 0,
+ pt->width[srcLevel],
+ pt->height[srcLevel]);
+ dstTrans = screen->get_tex_transfer(screen, pt, face, dstLevel, zslice,
+ PIPE_TRANSFER_WRITE, 0, 0,
+ pt->width[dstLevel],
+ pt->height[dstLevel]);
+
+ srcMap = (ubyte *) screen->transfer_map(screen, srcTrans);
+ dstMap = (ubyte *) screen->transfer_map(screen, dstTrans);
-#if 0
reduce_3d(pt->format,
- srcSurf->width, srcSurf->height,
- srcSurf->stride, srcMap,
- dstSurf->width, dstSurf->height,
- dstSurf->stride, dstMap);
-#else
- (void) reduce_3d;
-#endif
+ srcTrans->width, srcTrans->height,
+ srcTrans->stride, srcMap,
+ dstTrans->width, dstTrans->height,
+ dstTrans->stride, dstMap);
- pipe_surface_unmap(srcSurf);
- pipe_surface_unmap(dstSurf);
+ screen->transfer_unmap(screen, srcTrans);
+ screen->transfer_unmap(screen, dstTrans);
- pipe_surface_reference(&srcSurf, NULL);
- pipe_surface_reference(&dstSurf, NULL);
+ screen->tex_transfer_release(screen, &srcTrans);
+ screen->tex_transfer_release(screen, &dstTrans);
}
+#else
+ (void) reduce_3d;
+#endif
}
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index fe81a685be..2aceda12f8 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -169,46 +169,35 @@ util_surface_copy(struct pipe_context *pipe,
unsigned w, unsigned h)
{
struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *new_src = NULL, *new_dst = NULL;
+ struct pipe_transfer *src_trans, *dst_trans;
void *dst_map;
const void *src_map;
- assert(dst->block.size == src->block.size);
- assert(dst->block.width == src->block.width);
- assert(dst->block.height == src->block.height);
+ assert(dst_trans->block.size == src_trans->block.size);
+ assert(dst_trans->block.width == src_trans->block.width);
+ assert(dst_trans->block.height == src_trans->block.height);
- if ((src->usage & PIPE_BUFFER_USAGE_CPU_READ) == 0) {
- /* Need to create new src surface which is CPU readable */
- assert(src->texture);
- if (!src->texture)
- return;
- new_src = screen->get_tex_surface(screen,
+ assert(src->texture && dst->texture);
+ if (!src->texture || !dst->texture)
+ return;
+ src_trans = screen->get_tex_transfer(screen,
src->texture,
src->face,
src->level,
src->zslice,
- PIPE_BUFFER_USAGE_CPU_READ);
- src = new_src;
- }
+ PIPE_TRANSFER_READ,
+ src_x, src_y, w, h);
- if ((dst->usage & PIPE_BUFFER_USAGE_CPU_WRITE) == 0) {
- /* Need to create new dst surface which is CPU writable */
- assert(dst->texture);
- if (!dst->texture)
- return;
- new_dst = screen->get_tex_surface(screen,
+ dst_trans = screen->get_tex_transfer(screen,
dst->texture,
dst->face,
dst->level,
dst->zslice,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- dst = new_dst;
- }
+ PIPE_TRANSFER_WRITE,
+ dst_x, dst_y, w, h);
- src_map = pipe->screen->surface_map(screen,
- src, PIPE_BUFFER_USAGE_CPU_READ);
- dst_map = pipe->screen->surface_map(screen,
- dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+ src_map = pipe->screen->transfer_map(screen, src_trans);
+ dst_map = pipe->screen->transfer_map(screen, dst_trans);
assert(src_map);
assert(dst_map);
@@ -216,36 +205,25 @@ util_surface_copy(struct pipe_context *pipe,
if (src_map && dst_map) {
/* If do_flip, invert src_y position and pass negative src stride */
pipe_copy_rect(dst_map,
- &dst->block,
- dst->stride,
- dst_x, dst_y,
+ &dst_trans->block,
+ dst_trans->stride,
+ 0, 0,
w, h,
src_map,
- do_flip ? -(int) src->stride : src->stride,
- src_x,
- do_flip ? src_y + h - 1 : src_y);
+ do_flip ? -(int) src_trans->stride : src_trans->stride,
+ 0,
+ do_flip ? h - 1 : 0);
}
- pipe->screen->surface_unmap(pipe->screen, src);
- pipe->screen->surface_unmap(pipe->screen, dst);
+ pipe->screen->transfer_unmap(pipe->screen, src_trans);
+ pipe->screen->transfer_unmap(pipe->screen, dst_trans);
- if (new_src)
- screen->tex_surface_release(screen, &new_src);
- if (new_dst)
- screen->tex_surface_release(screen, &new_dst);
+ screen->tex_transfer_release(screen, &src_trans);
+ screen->tex_transfer_release(screen, &dst_trans);
}
-static void *
-get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
-{
- return (char *)dst_map
- + y / dst->block.height * dst->stride
- + x / dst->block.width * dst->block.size;
-}
-
-
#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
@@ -260,42 +238,38 @@ util_surface_fill(struct pipe_context *pipe,
unsigned width, unsigned height, unsigned value)
{
struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *new_dst = NULL;
+ struct pipe_transfer *dst_trans;
void *dst_map;
- if ((dst->usage & PIPE_BUFFER_USAGE_CPU_WRITE) == 0) {
- /* Need to create new dst surface which is CPU writable */
- assert(dst->texture);
- if (!dst->texture)
- return;
- new_dst = screen->get_tex_surface(screen,
+ assert(dst->texture);
+ if (!dst->texture)
+ return;
+ dst_trans = screen->get_tex_transfer(screen,
dst->texture,
dst->face,
dst->level,
dst->zslice,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- dst = new_dst;
- }
+ PIPE_TRANSFER_WRITE,
+ dstx, dsty, width, height);
- dst_map = pipe->screen->surface_map(screen,
- dst, PIPE_BUFFER_USAGE_CPU_WRITE);
+ dst_map = pipe->screen->transfer_map(screen, dst_trans);
assert(dst_map);
if (dst_map) {
- assert(dst->stride > 0);
+ assert(dst_trans->stride > 0);
- switch (dst->block.size) {
+ switch (dst_trans->block.size) {
case 1:
case 2:
case 4:
- pipe_fill_rect(dst_map, &dst->block, dst->stride,
- dstx, dsty, width, height, value);
+ pipe_fill_rect(dst_map, &dst_trans->block, dst_trans->stride,
+ 0, 0, width, height, value);
break;
case 8:
{
/* expand the 4-byte clear value to an 8-byte value */
- ushort *row = (ushort *) get_pointer(dst, dst_map, dstx, dsty);
+ ushort *row = (ushort *) dst_map;
ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
@@ -312,7 +286,7 @@ util_surface_fill(struct pipe_context *pipe,
row[j*4+2] = val2;
row[j*4+3] = val3;
}
- row += dst->stride/2;
+ row += dst_trans->stride/2;
}
}
break;
@@ -322,8 +296,6 @@ util_surface_fill(struct pipe_context *pipe,
}
}
- pipe->screen->surface_unmap(pipe->screen, dst);
-
- if (new_dst)
- screen->tex_surface_release(screen, &new_dst);
+ pipe->screen->transfer_unmap(pipe->screen, dst_trans);
+ screen->tex_transfer_release(screen, &dst_trans);
}
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index 32f6b072a0..56f2f577cc 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -28,7 +28,6 @@
/**
* RGBA/float tile get/put functions.
* Usable both by drivers and state trackers.
- * Surfaces should already be in a mapped state.
*/
@@ -42,58 +41,58 @@
/**
- * Move raw block of pixels from surface to user memory.
- * This should be usable by any hw driver that has mappable surfaces.
+ * Move raw block of pixels from transfer object to user memory.
*/
void
-pipe_get_tile_raw(struct pipe_surface *ps,
+pipe_get_tile_raw(struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
void *dst, int dst_stride)
{
+ struct pipe_screen *screen = pt->texture->screen;
const void *src;
if (dst_stride == 0)
- dst_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
+ dst_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
- if (pipe_clip_tile(x, y, &w, &h, ps))
+ if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- src = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ);
+ src = screen->transfer_map(screen, pt);
assert(src);
if(!src)
return;
- pipe_copy_rect(dst, &ps->block, dst_stride, 0, 0, w, h, src, ps->stride, x, y);
+ pipe_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
- pipe_surface_unmap(ps);
+ screen->transfer_unmap(screen, pt);
}
/**
- * Move raw block of pixels from user memory to surface.
- * This should be usable by any hw driver that has mappable surfaces.
+ * Move raw block of pixels from user memory to transfer object.
*/
void
-pipe_put_tile_raw(struct pipe_surface *ps,
+pipe_put_tile_raw(struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const void *src, int src_stride)
{
+ struct pipe_screen *screen = pt->texture->screen;
void *dst;
if (src_stride == 0)
- src_stride = pf_get_nblocksx(&ps->block, w) * ps->block.size;
+ src_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
- if (pipe_clip_tile(x, y, &w, &h, ps))
+ if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- dst = pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+ dst = screen->transfer_map(screen, pt);
assert(dst);
if(!dst)
return;
- pipe_copy_rect(dst, &ps->block, ps->stride, x, y, w, h, src, src_stride, 0, 0);
+ pipe_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
- pipe_surface_unmap(ps);
+ screen->transfer_unmap(screen, pt);
}
@@ -955,49 +954,49 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
void
-pipe_get_tile_rgba(struct pipe_surface *ps,
+pipe_get_tile_rgba(struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
float *p)
{
unsigned dst_stride = w * 4;
void *packed;
- if (pipe_clip_tile(x, y, &w, &h, ps))
+ if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
+ packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
if (!packed)
return;
- if(ps->format == PIPE_FORMAT_YCBCR || ps->format == PIPE_FORMAT_YCBCR_REV)
+ if(pt->format == PIPE_FORMAT_YCBCR || pt->format == PIPE_FORMAT_YCBCR_REV)
assert((x & 1) == 0);
- pipe_get_tile_raw(ps, x, y, w, h, packed, 0);
+ pipe_get_tile_raw(pt, x, y, w, h, packed, 0);
- pipe_tile_raw_to_rgba(ps->format, packed, w, h, p, dst_stride);
+ pipe_tile_raw_to_rgba(pt->format, packed, w, h, p, dst_stride);
FREE(packed);
}
void
-pipe_put_tile_rgba(struct pipe_surface *ps,
+pipe_put_tile_rgba(struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const float *p)
{
unsigned src_stride = w * 4;
void *packed;
- if (pipe_clip_tile(x, y, &w, &h, ps))
+ if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- packed = MALLOC(pf_get_nblocks(&ps->block, w, h) * ps->block.size);
+ packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
if (!packed)
return;
- switch (ps->format) {
+ switch (pt->format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
break;
@@ -1054,7 +1053,7 @@ pipe_put_tile_rgba(struct pipe_surface *ps,
assert(0);
}
- pipe_put_tile_raw(ps, x, y, w, h, packed, 0);
+ pipe_put_tile_raw(pt, x, y, w, h, packed, 0);
FREE(packed);
}
@@ -1064,62 +1063,63 @@ pipe_put_tile_rgba(struct pipe_surface *ps,
* Get a block of Z values, converted to 32-bit range.
*/
void
-pipe_get_tile_z(struct pipe_surface *ps,
+pipe_get_tile_z(struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
uint *z)
{
+ struct pipe_screen *screen = pt->texture->screen;
const uint dstStride = w;
ubyte *map;
uint *pDest = z;
uint i, j;
- if (pipe_clip_tile(x, y, &w, &h, ps))
+ if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_READ);
+ map = (ubyte *)screen->transfer_map(screen, pt);
if (!map) {
assert(0);
return;
}
- switch (ps->format) {
+ switch (pt->format) {
case PIPE_FORMAT_Z32_UNORM:
{
- const uint *pSrc
- = (const uint *)(map + y * ps->stride + x*4);
+ const uint *ptrc
+ = (const uint *)(map + y * pt->stride + x*4);
for (i = 0; i < h; i++) {
- memcpy(pDest, pSrc, 4 * w);
+ memcpy(pDest, ptrc, 4 * w);
pDest += dstStride;
- pSrc += ps->stride/4;
+ ptrc += pt->stride/4;
}
}
break;
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
{
- const uint *pSrc
- = (const uint *)(map + y * ps->stride + x*4);
+ const uint *ptrc
+ = (const uint *)(map + y * pt->stride + x*4);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 24-bit Z to 32-bit Z */
- pDest[j] = (pSrc[j] << 8) | (pSrc[j] & 0xff);
+ pDest[j] = (ptrc[j] << 8) | (ptrc[j] & 0xff);
}
pDest += dstStride;
- pSrc += ps->stride/4;
+ ptrc += pt->stride/4;
}
}
break;
case PIPE_FORMAT_Z16_UNORM:
{
- const ushort *pSrc
- = (const ushort *)(map + y * ps->stride + x*2);
+ const ushort *ptrc
+ = (const ushort *)(map + y * pt->stride + x*2);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 16-bit Z to 32-bit Z */
- pDest[j] = (pSrc[j] << 16) | pSrc[j];
+ pDest[j] = (ptrc[j] << 16) | ptrc[j];
}
pDest += dstStride;
- pSrc += ps->stride/2;
+ ptrc += pt->stride/2;
}
}
break;
@@ -1127,64 +1127,65 @@ pipe_get_tile_z(struct pipe_surface *ps,
assert(0);
}
- pipe_surface_unmap(ps);
+ screen->transfer_unmap(screen, pt);
}
void
-pipe_put_tile_z(struct pipe_surface *ps,
+pipe_put_tile_z(struct pipe_transfer *pt,
uint x, uint y, uint w, uint h,
const uint *zSrc)
{
+ struct pipe_screen *screen = pt->texture->screen;
const uint srcStride = w;
- const uint *pSrc = zSrc;
+ const uint *ptrc = zSrc;
ubyte *map;
uint i, j;
- if (pipe_clip_tile(x, y, &w, &h, ps))
+ if (pipe_clip_tile(x, y, &w, &h, pt))
return;
- map = (ubyte *)pipe_surface_map(ps, PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = (ubyte *)screen->transfer_map(screen, pt);
if (!map) {
assert(0);
return;
}
- switch (ps->format) {
+ switch (pt->format) {
case PIPE_FORMAT_Z32_UNORM:
{
- uint *pDest = (uint *) (map + y * ps->stride + x*4);
+ uint *pDest = (uint *) (map + y * pt->stride + x*4);
for (i = 0; i < h; i++) {
- memcpy(pDest, pSrc, 4 * w);
- pDest += ps->stride/4;
- pSrc += srcStride;
+ memcpy(pDest, ptrc, 4 * w);
+ pDest += pt->stride/4;
+ ptrc += srcStride;
}
}
break;
case PIPE_FORMAT_S8Z24_UNORM:
case PIPE_FORMAT_X8Z24_UNORM:
{
- uint *pDest = (uint *) (map + y * ps->stride + x*4);
+ uint *pDest = (uint *) (map + y * pt->stride + x*4);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 24-bit Z (0 stencil) */
- pDest[j] = pSrc[j] >> 8;
+ pDest[j] = ptrc[j] >> 8;
}
- pDest += ps->stride/4;
- pSrc += srcStride;
+ pDest += pt->stride/4;
+ ptrc += srcStride;
}
}
break;
case PIPE_FORMAT_Z16_UNORM:
{
- ushort *pDest = (ushort *) (map + y * ps->stride + x*2);
+ ushort *pDest = (ushort *) (map + y * pt->stride + x*2);
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 16-bit Z */
- pDest[j] = pSrc[j] >> 16;
+ pDest[j] = ptrc[j] >> 16;
}
- pDest += ps->stride/2;
- pSrc += srcStride;
+ pDest += pt->stride/2;
+ ptrc += srcStride;
}
}
break;
@@ -1192,7 +1193,7 @@ pipe_put_tile_z(struct pipe_surface *ps,
assert(0);
}
- pipe_surface_unmap(ps);
+ screen->transfer_unmap(screen, pt);
}
diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h
index a8ac805308..b6bd43d88e 100644
--- a/src/gallium/auxiliary/util/u_tile.h
+++ b/src/gallium/auxiliary/util/u_tile.h
@@ -30,15 +30,15 @@
#include "pipe/p_compiler.h"
-struct pipe_surface;
+struct pipe_transfer;
/**
- * Clip tile against surface dims.
+ * Clip tile against transfer dims.
* \return TRUE if tile is totally clipped, FALSE otherwise
*/
static INLINE boolean
-pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_surface *ps)
+pipe_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_transfer *ps)
{
if (x >= ps->width)
return TRUE;
@@ -56,34 +56,34 @@ extern "C" {
#endif
void
-pipe_get_tile_raw(struct pipe_surface *ps,
+pipe_get_tile_raw(struct pipe_transfer *ps,
uint x, uint y, uint w, uint h,
void *p, int dst_stride);
void
-pipe_put_tile_raw(struct pipe_surface *ps,
+pipe_put_tile_raw(struct pipe_transfer *ps,
uint x, uint y, uint w, uint h,
const void *p, int src_stride);
void
-pipe_get_tile_rgba(struct pipe_surface *ps,
+pipe_get_tile_rgba(struct pipe_transfer *ps,
uint x, uint y, uint w, uint h,
float *p);
void
-pipe_put_tile_rgba(struct pipe_surface *ps,
+pipe_put_tile_rgba(struct pipe_transfer *ps,
uint x, uint y, uint w, uint h,
const float *p);
void
-pipe_get_tile_z(struct pipe_surface *ps,
+pipe_get_tile_z(struct pipe_transfer *ps,
uint x, uint y, uint w, uint h,
uint *z);
void
-pipe_put_tile_z(struct pipe_surface *ps,
+pipe_put_tile_z(struct pipe_transfer *ps,
uint x, uint y, uint w, uint h,
const uint *z);
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index c2d882a819..ff5d1b54a4 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -53,15 +53,15 @@
* Map any drawing surfaces which aren't already mapped
*/
void
-softpipe_map_surfaces(struct softpipe_context *sp)
+softpipe_map_transfers(struct softpipe_context *sp)
{
unsigned i;
for (i = 0; i < sp->framebuffer.nr_cbufs; i++) {
- sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
+ sp_tile_cache_map_transfers(sp->cbuf_cache[i]);
}
- sp_tile_cache_map_surfaces(sp->zsbuf_cache);
+ sp_tile_cache_map_transfers(sp->zsbuf_cache);
}
@@ -69,7 +69,7 @@ softpipe_map_surfaces(struct softpipe_context *sp)
* Unmap any mapped drawing surfaces
*/
void
-softpipe_unmap_surfaces(struct softpipe_context *sp)
+softpipe_unmap_transfers(struct softpipe_context *sp)
{
uint i;
@@ -78,9 +78,9 @@ softpipe_unmap_surfaces(struct softpipe_context *sp)
sp_flush_tile_cache(sp, sp->zsbuf_cache);
for (i = 0; i < sp->framebuffer.nr_cbufs; i++) {
- sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
+ sp_tile_cache_unmap_transfers(sp->cbuf_cache[i]);
}
- sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
+ sp_tile_cache_unmap_transfers(sp->zsbuf_cache);
}
diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c
index ecc9d00319..f888e815b7 100644
--- a/src/gallium/drivers/softpipe/sp_draw_arrays.c
+++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c
@@ -128,7 +128,7 @@ softpipe_draw_range_elements(struct pipe_context *pipe,
if (sp->dirty)
softpipe_update_derived( sp );
- softpipe_map_surfaces(sp);
+ softpipe_map_transfers(sp);
softpipe_map_constant_buffers(sp);
/*
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index c21faf57f3..035f4b963e 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -70,7 +70,7 @@ softpipe_flush( struct pipe_context *pipe,
* that's called before swapbuffers because we don't always want
* to unmap surfaces when flushing.
*/
- softpipe_unmap_surfaces(softpipe);
+ softpipe_unmap_transfers(softpipe);
}
/* Enable to dump BMPs of the color/depth buffers each frame */
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 3eff41ffa5..6f558e6da5 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -184,10 +184,10 @@ softpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags);
void
-softpipe_map_surfaces(struct softpipe_context *sp);
+softpipe_map_transfers(struct softpipe_context *sp);
void
-softpipe_unmap_surfaces(struct softpipe_context *sp);
+softpipe_unmap_transfers(struct softpipe_context *sp);
void
softpipe_map_texture_surfaces(struct softpipe_context *sp);
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 7af8398193..f84b3fb9d4 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -215,12 +215,8 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
ps->refcount = 1;
pipe_texture_reference(&ps->texture, pt);
ps->format = pt->format;
- ps->block = pt->block;
ps->width = pt->width[level];
ps->height = pt->height[level];
- ps->nblocksx = pt->nblocksx[level];
- ps->nblocksy = pt->nblocksy[level];
- ps->stride = spt->stride[level];
ps->offset = spt->level_offset[level];
ps->usage = usage;
@@ -249,8 +245,7 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
- ps->nblocksy *
- ps->stride;
+ pt->nblocksy[level] * spt->stride[level];
}
else {
assert(face == 0);
@@ -279,21 +274,91 @@ softpipe_tex_surface_release(struct pipe_screen *screen,
}
+static struct pipe_transfer *
+softpipe_get_tex_transfer(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ struct softpipe_texture *sptex = softpipe_texture(texture);
+ struct softpipe_transfer *spt;
+ struct pipe_transfer *pt;
+
+ assert(texture);
+ assert(level <= texture->last_level);
+
+ spt = CALLOC_STRUCT(softpipe_transfer);
+ pt = &spt->base;
+ if (spt) {
+ pt->refcount = 1;
+ pipe_texture_reference(&pt->texture, texture);
+ pt->format = texture->format;
+ pt->block = texture->block;
+ pt->x = x;
+ pt->y = y;
+ pt->width = w;
+ pt->height = h;
+ pt->nblocksx = texture->nblocksx[level];
+ pt->nblocksy = texture->nblocksy[level];
+ pt->stride = sptex->stride[level];
+ spt->offset = sptex->level_offset[level];
+ pt->usage = usage;
+ pt->face = face;
+ pt->level = level;
+ pt->zslice = zslice;
+
+ if (texture->target == PIPE_TEXTURE_CUBE ||
+ texture->target == PIPE_TEXTURE_3D) {
+ spt->offset += ((texture->target == PIPE_TEXTURE_CUBE) ? face :
+ zslice) * pt->nblocksy * pt->stride;
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+ }
+ return pt;
+}
+
+
+static void
+softpipe_tex_transfer_release(struct pipe_screen *screen,
+ struct pipe_transfer **t)
+{
+ struct softpipe_transfer *transfer = softpipe_transfer(*t);
+ /* Effectively do the texture_update work here - if texture images
+ * needed post-processing to put them into hardware layout, this is
+ * where it would happen. For softpipe, nothing to do.
+ */
+ assert (transfer->base.texture);
+ if (--transfer->base.refcount == 0) {
+ pipe_texture_reference(&transfer->base.texture, NULL);
+ FREE(transfer);
+ }
+ *t = NULL;
+}
+
+
static void *
-softpipe_surface_map( struct pipe_screen *screen,
- struct pipe_surface *surface,
- unsigned flags )
+softpipe_transfer_map( struct pipe_screen *screen,
+ struct pipe_transfer *transfer )
{
ubyte *map;
struct softpipe_texture *spt;
+ unsigned flags = 0;
- if (flags & ~surface->usage) {
- assert(0);
- return NULL;
+ assert(transfer->texture);
+ spt = softpipe_texture(transfer->texture);
+
+ if (transfer->usage != PIPE_TRANSFER_READ) {
+ flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
+ }
+
+ if (transfer->usage != PIPE_TRANSFER_WRITE) {
+ flags |= PIPE_BUFFER_USAGE_CPU_READ;
}
- assert(surface->texture);
- spt = softpipe_texture(surface->texture);
map = pipe_buffer_map(screen, spt->buffer, flags);
if (map == NULL)
return NULL;
@@ -301,8 +366,7 @@ softpipe_surface_map( struct pipe_screen *screen,
/* May want to different things here depending on read/write nature
* of the map:
*/
- if (surface->texture &&
- (flags & PIPE_BUFFER_USAGE_CPU_WRITE))
+ if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ)
{
/* Do something to notify sharing contexts of a texture change.
* In softpipe, that would mean flushing the texture cache.
@@ -310,18 +374,20 @@ softpipe_surface_map( struct pipe_screen *screen,
softpipe_screen(screen)->timestamp++;
}
- return map + surface->offset;
+ return map + softpipe_transfer(transfer)->offset +
+ transfer->y / transfer->block.height * transfer->stride +
+ transfer->x / transfer->block.width * transfer->block.size;
}
static void
-softpipe_surface_unmap(struct pipe_screen *screen,
- struct pipe_surface *surface)
+softpipe_transfer_unmap(struct pipe_screen *screen,
+ struct pipe_transfer *transfer)
{
struct softpipe_texture *spt;
- assert(surface->texture);
- spt = softpipe_texture(surface->texture);
+ assert(transfer->texture);
+ spt = softpipe_texture(transfer->texture);
pipe_buffer_unmap( screen, spt->buffer );
}
@@ -343,6 +409,8 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
screen->get_tex_surface = softpipe_get_tex_surface;
screen->tex_surface_release = softpipe_tex_surface_release;
- screen->surface_map = softpipe_surface_map;
- screen->surface_unmap = softpipe_surface_unmap;
+ screen->get_tex_transfer = softpipe_get_tex_transfer;
+ screen->tex_transfer_release = softpipe_tex_transfer_release;
+ screen->transfer_map = softpipe_transfer_map;
+ screen->transfer_unmap = softpipe_transfer_unmap;
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index c1636920cd..893aa7d11d 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -51,14 +51,27 @@ struct softpipe_texture
boolean modified;
};
+struct softpipe_transfer
+{
+ struct pipe_transfer base;
+
+ unsigned long offset;
+};
+
-/** cast wrapper */
+/** cast wrappers */
static INLINE struct softpipe_texture *
softpipe_texture(struct pipe_texture *pt)
{
return (struct softpipe_texture *) pt;
}
+static INLINE struct softpipe_transfer *
+softpipe_transfer(struct pipe_transfer *pt)
+{
+ return (struct softpipe_transfer *) pt;
+}
+
extern void
softpipe_init_texture_funcs( struct softpipe_context *softpipe );
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index ab76009375..e6b6e6f02c 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -26,7 +26,7 @@
**************************************************************************/
/**
- * Framebuffer/surface tile caching.
+ * Texture tile caching.
*
* Author:
* Brian Paul
@@ -52,7 +52,8 @@ struct softpipe_tile_cache
{
struct pipe_screen *screen;
struct pipe_surface *surface; /**< the surface we're caching */
- void *surface_map;
+ struct pipe_transfer *transfer;
+ void *transfer_map;
struct pipe_texture *texture; /**< if caching a texture */
struct softpipe_cached_tile entries[NUM_ENTRIES];
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
@@ -60,8 +61,8 @@ struct softpipe_tile_cache
uint clear_val;
boolean depth_stencil; /** Is the surface a depth/stencil format? */
- struct pipe_surface *tex_surf;
- void *tex_surf_map;
+ struct pipe_transfer *tex_trans;
+ void *tex_trans_map;
int tex_face, tex_level, tex_z;
struct softpipe_cached_tile tile; /**< scratch tile for clears */
@@ -131,16 +132,19 @@ sp_create_tile_cache( struct pipe_screen *screen )
void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
{
+ struct pipe_screen *screen;
uint pos;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
/*assert(tc->entries[pos].x < 0);*/
}
- if (tc->surface) {
- pipe_surface_reference(&tc->surface, NULL);
+ if (tc->transfer) {
+ screen = tc->transfer->texture->screen;
+ screen->tex_transfer_release(screen, &tc->transfer);
}
- if (tc->tex_surf) {
- pipe_surface_reference(&tc->tex_surf, NULL);
+ if (tc->tex_trans) {
+ screen = tc->tex_trans->texture->screen;
+ screen->tex_transfer_release(screen, &tc->tex_trans);
}
FREE( tc );
@@ -154,34 +158,42 @@ void
sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
struct pipe_surface *ps)
{
+ struct pipe_screen *screen = ps->texture->screen;
+
assert(!tc->texture);
- if (tc->surface_map) {
- tc->screen->surface_unmap(tc->screen, tc->surface);
- tc->surface_map = NULL;
- }
+ if (tc->transfer) {
+ if (ps->texture == tc->transfer->texture &&
+ ps->face == tc->transfer->face &&
+ ps->level == tc->transfer->level &&
+ ps->zslice == tc->transfer->zslice)
+ return;
- pipe_surface_reference(&tc->surface, ps);
-
- if (tc->surface) {
- if (tc->surface_map) /* XXX: this is always NULL!? */
- tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
- PIPE_BUFFER_USAGE_CPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE);
-
- tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
- ps->format == PIPE_FORMAT_X8Z24_UNORM ||
- ps->format == PIPE_FORMAT_Z24S8_UNORM ||
- ps->format == PIPE_FORMAT_Z24X8_UNORM ||
- ps->format == PIPE_FORMAT_Z16_UNORM ||
- ps->format == PIPE_FORMAT_Z32_UNORM ||
- ps->format == PIPE_FORMAT_S8_UNORM);
+ if (tc->transfer_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->transfer);
+ tc->transfer_map = NULL;
+ }
+
+ screen->tex_transfer_release(screen, &tc->transfer);
}
+
+ tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face,
+ ps->level, ps->zslice,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, ps->width, ps->height);
+
+ tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
+ ps->format == PIPE_FORMAT_X8Z24_UNORM ||
+ ps->format == PIPE_FORMAT_Z24S8_UNORM ||
+ ps->format == PIPE_FORMAT_Z24X8_UNORM ||
+ ps->format == PIPE_FORMAT_Z16_UNORM ||
+ ps->format == PIPE_FORMAT_Z32_UNORM ||
+ ps->format == PIPE_FORMAT_S8_UNORM);
}
/**
- * Return the surface being cached.
+ * Return the transfer being cached.
*/
struct pipe_surface *
sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
@@ -191,30 +203,27 @@ sp_tile_cache_get_surface(struct softpipe_tile_cache *tc)
void
-sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc)
+sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc)
{
- if (tc->surface && !tc->surface_map)
- tc->surface_map = tc->screen->surface_map(tc->screen, tc->surface,
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ);
-
- if (tc->tex_surf && !tc->tex_surf_map)
- tc->tex_surf_map = tc->screen->surface_map(tc->screen, tc->tex_surf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ if (tc->transfer && !tc->transfer_map)
+ tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer);
+
+ if (tc->tex_trans && !tc->tex_trans_map)
+ tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans);
}
void
-sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc)
+sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc)
{
- if (tc->surface_map) {
- tc->screen->surface_unmap(tc->screen, tc->surface);
- tc->surface_map = NULL;
+ if (tc->transfer_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->transfer);
+ tc->transfer_map = NULL;
}
- if (tc->tex_surf_map) {
- tc->screen->surface_unmap(tc->screen, tc->tex_surf);
- tc->tex_surf_map = NULL;
+ if (tc->tex_trans_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->tex_trans_map = NULL;
}
}
@@ -227,17 +236,18 @@ sp_tile_cache_set_texture(struct pipe_context *pipe,
struct softpipe_tile_cache *tc,
struct pipe_texture *texture)
{
+ struct pipe_screen *screen = texture->screen;
uint i;
- assert(!tc->surface);
+ assert(!tc->transfer);
pipe_texture_reference(&tc->texture, texture);
- if (tc->tex_surf_map) {
- tc->screen->surface_unmap(tc->screen, tc->tex_surf);
- tc->tex_surf_map = NULL;
+ if (tc->tex_trans_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->tex_trans_map = NULL;
}
- pipe_surface_reference(&tc->tex_surf, NULL);
+ screen->tex_transfer_release(screen, &tc->tex_trans);
/* mark as entries as invalid/empty */
/* XXX we should try to avoid this when the teximage hasn't changed */
@@ -328,9 +338,9 @@ static void
sp_tile_cache_flush_clear(struct pipe_context *pipe,
struct softpipe_tile_cache *tc)
{
- struct pipe_surface *ps = tc->surface;
- const uint w = tc->surface->width;
- const uint h = tc->surface->height;
+ struct pipe_transfer *ps = tc->transfer;
+ const uint w = tc->transfer->width;
+ const uint h = tc->transfer->height;
uint x, y;
uint numCleared = 0;
@@ -359,18 +369,18 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe,
/**
- * Flush the tile cache: write all dirty tiles back to the surface.
+ * Flush the tile cache: write all dirty tiles back to the transfer.
* any tiles "flagged" as cleared will be "really" cleared.
*/
void
sp_flush_tile_cache(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc)
{
- struct pipe_surface *ps = tc->surface;
+ struct pipe_transfer *ps = tc->transfer;
int inuse = 0, pos;
if (ps) {
- /* caching a drawing surface */
+ /* caching a drawing transfer */
for (pos = 0; pos < NUM_ENTRIES; pos++) {
struct softpipe_cached_tile *tile = tc->entries + pos;
if (tile->x >= 0) {
@@ -415,7 +425,7 @@ struct softpipe_cached_tile *
sp_get_cached_tile(struct softpipe_context *softpipe,
struct softpipe_tile_cache *tc, int x, int y)
{
- struct pipe_surface *ps = tc->surface;
+ struct pipe_transfer *ps = tc->transfer;
/* tile pos in framebuffer: */
const int tile_x = x & ~(TILE_SIZE - 1);
@@ -456,7 +466,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
clear_clear_flag(tc->clear_flags, x, y);
}
else {
- /* get new tile data from surface */
+ /* get new tile data from transfer */
if (tc->depth_stencil) {
pipe_get_tile_raw(ps,
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
@@ -523,28 +533,30 @@ sp_get_cached_tile_tex(struct softpipe_context *sp,
level != tile->level) {
/* cache miss */
- /* check if we need to get a new surface */
- if (!tc->tex_surf ||
+ /* check if we need to get a new transfer */
+ if (!tc->tex_trans ||
tc->tex_face != face ||
tc->tex_level != level ||
tc->tex_z != z) {
- /* get new surface (view into texture) */
+ /* get new transfer (view into texture) */
- if (tc->tex_surf_map)
- tc->screen->surface_unmap(tc->screen, tc->tex_surf);
+ if (tc->tex_trans_map)
+ tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ screen->tex_transfer_release(screen, &tc->tex_trans);
- tc->tex_surf = screen->get_tex_surface(screen, tc->texture, face, level, z,
- PIPE_BUFFER_USAGE_CPU_READ);
- tc->tex_surf_map = screen->surface_map(screen, tc->tex_surf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ tc->tex_trans = screen->get_tex_transfer(screen, tc->texture, face, level, z,
+ PIPE_TRANSFER_READ, 0, 0,
+ tc->texture->width[level],
+ tc->texture->height[level]);
+ tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
tc->tex_face = face;
tc->tex_level = level;
tc->tex_z = z;
}
- /* get tile from the surface (view into texture) */
- pipe_get_tile_rgba(tc->tex_surf,
+ /* get tile from the transfer (view into texture) */
+ pipe_get_tile_rgba(tc->tex_trans,
tile_x, tile_y, TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
tile->x = tile_x;
@@ -571,7 +583,7 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, uint clearValue)
tc->clear_val = clearValue;
- switch (tc->surface->format) {
+ switch (tc->transfer->format) {
case PIPE_FORMAT_R8G8B8A8_UNORM:
r = (clearValue >> 24) & 0xff;
g = (clearValue >> 16) & 0xff;
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index a66bb50bcc..9ac3fdda94 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -74,10 +74,10 @@ extern struct pipe_surface *
sp_tile_cache_get_surface(struct softpipe_tile_cache *tc);
extern void
-sp_tile_cache_map_surfaces(struct softpipe_tile_cache *tc);
+sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc);
extern void
-sp_tile_cache_unmap_surfaces(struct softpipe_tile_cache *tc);
+sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc);
extern void
sp_tile_cache_set_texture(struct pipe_context *pipe,
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 4f0b301f31..0d70348c11 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -194,6 +194,16 @@ enum pipe_texture_target {
/**
+ * Transfer object usage flags
+ */
+enum pipe_transfer_usage {
+ PIPE_TRANSFER_READ,
+ PIPE_TRANSFER_WRITE,
+ PIPE_TRANSFER_READ_WRITE //< Read/modify/write
+};
+
+
+/**
* Buffer usage flags
*/
#define PIPE_BUFFER_USAGE_CPU_READ (1 << 0)
diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h
index 1219c817b4..76460d2724 100644
--- a/src/gallium/include/pipe/p_inlines.h
+++ b/src/gallium/include/pipe/p_inlines.h
@@ -38,29 +38,6 @@ extern "C" {
#endif
-/* XXX: these are a kludge. will fix when all surfaces are views into
- * textures, and free-floating winsys surfaces go away.
- */
-static INLINE void *
-pipe_surface_map( struct pipe_surface *surf, unsigned flags )
-{
- struct pipe_screen *screen;
- assert(surf->texture);
- screen = surf->texture->screen;
- return screen->surface_map( screen, surf, flags );
-}
-
-static INLINE void
-pipe_surface_unmap( struct pipe_surface *surf )
-{
- struct pipe_screen *screen;
- assert(surf->texture);
- screen = surf->texture->screen;
- screen->surface_unmap( screen, surf );
-}
-
-
-
/**
* Set 'ptr' to point to 'surf' and update reference counting.
* The old thing pointed to, if any, will be unreferenced first.
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 0bd7d12e22..8714a2ed7d 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -51,6 +51,7 @@ extern "C" {
/** Opaque type */
struct pipe_fence_handle;
+
/**
* Gallium screen/adapter context. Basically everything
* hardware-specific that doesn't actually require a rendering
@@ -124,12 +125,25 @@ struct pipe_screen {
struct pipe_surface ** );
- void *(*surface_map)( struct pipe_screen *,
- struct pipe_surface *surface,
- unsigned flags );
+ /** Get a transfer object for transferring data to/from a texture */
+ struct pipe_transfer *(*get_tex_transfer)(struct pipe_screen *,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level,
+ unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y,
+ unsigned w, unsigned h);
+
+ /* Transfer objects allocated by the above must be released here:
+ */
+ void (*tex_transfer_release)( struct pipe_screen *,
+ struct pipe_transfer ** );
+
+ void *(*transfer_map)( struct pipe_screen *,
+ struct pipe_transfer *transfer );
- void (*surface_unmap)( struct pipe_screen *,
- struct pipe_surface *surface );
+ void (*transfer_unmap)( struct pipe_screen *,
+ struct pipe_transfer *transfer );
/**
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index dd0dfac238..34141ff242 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -281,10 +281,6 @@ struct pipe_surface
unsigned clear_value; /**< XXX may be temporary */
unsigned width; /**< logical width in pixels */
unsigned height; /**< logical height in pixels */
- struct pipe_format_block block;
- unsigned nblocksx; /**< allocated width in blocks */
- unsigned nblocksy; /**< allocated height in blocks */
- unsigned stride; /**< stride in bytes between rows of blocks */
unsigned layout; /**< PIPE_SURFACE_LAYOUT_x */
unsigned offset; /**< offset from start of buffer, in bytes */
unsigned refcount;
@@ -298,6 +294,30 @@ struct pipe_surface
/**
+ * Transfer object. For data transfer to/from a texture.
+ */
+struct pipe_transfer
+{
+ enum pipe_format format; /**< PIPE_FORMAT_x */
+ unsigned x; /**< x offset from start of texture image */
+ unsigned y; /**< y offset from start of texture image */
+ unsigned width; /**< logical width in pixels */
+ unsigned height; /**< logical height in pixels */
+ struct pipe_format_block block;
+ unsigned nblocksx; /**< allocated width in blocks */
+ unsigned nblocksy; /**< allocated height in blocks */
+ unsigned stride; /**< stride in bytes between rows of blocks */
+ unsigned refcount;
+ unsigned usage; /**< PIPE_TRANSFER_* */
+
+ struct pipe_texture *texture; /**< texture to transfer to/from */
+ unsigned face;
+ unsigned level;
+ unsigned zslice;
+};
+
+
+/**
* Texture object.
*/
struct pipe_texture
diff --git a/src/gallium/winsys/xlib/xlib_brw_aub.c b/src/gallium/winsys/xlib/xlib_brw_aub.c
index 2956e1b960..c63cd51d32 100644
--- a/src/gallium/winsys/xlib/xlib_brw_aub.c
+++ b/src/gallium/winsys/xlib/xlib_brw_aub.c
@@ -322,10 +322,10 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile,
struct aub_dump_bmp db;
unsigned format;
- assert(surface->block.width == 1);
- assert(surface->block.height == 1);
+ assert(surface->texture->block.width == 1);
+ assert(surface->texture->block.height == 1);
- if (surface->block.size == 4)
+ if (surface->texture->block.size == 4)
format = 0x7;
else
format = 0x3;
@@ -334,8 +334,8 @@ void brw_aub_dump_bmp( struct brw_aubfile *aubfile,
db.xmin = 0;
db.ymin = 0;
db.format = format;
- db.bpp = surface->block.size * 8;
- db.pitch = surface->stride/surface->block.size;
+ db.bpp = surface->texture->block.size * 8;
+ db.pitch = surface->texture->nblocksx[surface->level];
db.xsize = surface->width;
db.ysize = surface->height;
db.addr = gtt_offset;
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index 586e1dfca5..52fd7455a5 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -244,9 +244,10 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b,
return;
if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) {
- assert(surf->block.width == 1);
- assert(surf->block.height == 1);
- alloc_shm_ximage(xm_buf, b, surf->stride/surf->block.size, surf->height);
+ assert(surf->texture->block.width == 1);
+ assert(surf->texture->block.height == 1);
+ alloc_shm_ximage(xm_buf, b, surf->texture->nblocksx[surf->level],
+ surf->height);
}
ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage;
@@ -264,7 +265,7 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b,
/* update XImage's fields */
ximage->width = surf->width;
ximage->height = surf->height;
- ximage->bytes_per_line = surf->stride;
+ ximage->bytes_per_line = surf->texture->nblocksx[surf->level];
XPutImage(b->xm_visual->display, b->drawable, b->gc,
ximage, 0, 0, 0, 0, surf->width, surf->height);