diff options
author | Michel Dänzer <daenzer@vmware.com> | 2009-02-05 19:41:18 +0100 |
---|---|---|
committer | Michel Dänzer <daenzer@vmware.com> | 2009-02-05 19:41:18 +0100 |
commit | 4617981ec72f7985941bee4b03c534d97ff96bc6 (patch) | |
tree | c3c8fb33499227cf4e3e905b3c04ff6599666663 /src | |
parent | e0c3b4970da052308bf7b4e5cbe9186a4b8321db (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')
31 files changed, 797 insertions, 682 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); diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index a357b71677..ce872458e3 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -140,7 +140,7 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) { struct pipe_context *pipe = ctx->st->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_surface *surface; + struct pipe_transfer *transfer; const GLuint rSize = ctx->PixelMaps.RtoR.Size; const GLuint gSize = ctx->PixelMaps.GtoG.Size; const GLuint bSize = ctx->PixelMaps.BtoB.Size; @@ -149,10 +149,9 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) uint *dest; uint i, j; - surface = screen->get_tex_surface(screen, pt, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); - dest = (uint *) screen->surface_map(screen, surface, - PIPE_BUFFER_USAGE_CPU_WRITE); + transfer = screen->get_tex_transfer(screen, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, + 0, 0, texSize, texSize); + dest = (uint *) screen->transfer_map(screen, transfer); /* Pack four 1D maps into a 2D texture: * R map is placed horizontally, indexed by S, in channel 0 @@ -171,8 +170,8 @@ load_color_map_texture(GLcontext *ctx, struct pipe_texture *pt) } } - screen->surface_unmap(screen, surface); - pipe_surface_reference(&surface, NULL); + screen->transfer_unmap(screen, transfer); + screen->tex_transfer_release(screen, &transfer); } diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c index a4e72b48ed..36e2f4d460 100644 --- a/src/mesa/state_tracker/st_cb_accum.c +++ b/src/mesa/state_tracker/st_cb_accum.c @@ -63,21 +63,21 @@ * See also: st_renderbuffer_alloc_storage() */ static void -acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, +acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *acc_pt, uint x, uint y, uint w, uint h, float *p) { - const enum pipe_format f = acc_ps->format; - const struct pipe_format_block b = acc_ps->block; + const enum pipe_format f = acc_pt->format; + const struct pipe_format_block b = acc_pt->block; - acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT; - acc_ps->block.size = 8; - acc_ps->block.width = 1; - acc_ps->block.height = 1; + acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT; + acc_pt->block.size = 8; + acc_pt->block.width = 1; + acc_pt->block.height = 1; - pipe_get_tile_rgba(acc_ps, x, y, w, h, p); + pipe_get_tile_rgba(acc_pt, x, y, w, h, p); - acc_ps->format = f; - acc_ps->block = b; + acc_pt->format = f; + acc_pt->block = b; } @@ -87,21 +87,21 @@ acc_get_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, * See also: st_renderbuffer_alloc_storage() */ static void -acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_surface *acc_ps, +acc_put_tile_rgba(struct pipe_context *pipe, struct pipe_transfer *acc_pt, uint x, uint y, uint w, uint h, const float *p) { - enum pipe_format f = acc_ps->format; - const struct pipe_format_block b = acc_ps->block; + enum pipe_format f = acc_pt->format; + const struct pipe_format_block b = acc_pt->block; - acc_ps->format = DEFAULT_ACCUM_PIPE_FORMAT; - acc_ps->block.size = 8; - acc_ps->block.width = 1; - acc_ps->block.height = 1; + acc_pt->format = DEFAULT_ACCUM_PIPE_FORMAT; + acc_pt->block.size = 8; + acc_pt->block.width = 1; + acc_pt->block.height = 1; - pipe_put_tile_rgba(acc_ps, x, y, w, h, p); + pipe_put_tile_rgba(acc_pt, x, y, w, h, p); - acc_ps->format = f; - acc_ps->block = b; + acc_pt->format = f; + acc_pt->block = b; } @@ -110,7 +110,7 @@ void st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) { struct st_renderbuffer *acc_strb = st_renderbuffer(rb); - struct pipe_surface *acc_ps; + struct pipe_transfer *acc_pt; struct pipe_screen *screen = ctx->st->pipe->screen; const GLint xpos = ctx->DrawBuffer->_Xmin; const GLint ypos = ctx->DrawBuffer->_Ymin; @@ -118,12 +118,12 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) const GLint height = ctx->DrawBuffer->_Ymax - ypos; GLubyte *map; - acc_ps = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); - map = screen->surface_map(screen, acc_ps, - PIPE_BUFFER_USAGE_CPU_WRITE); + acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, xpos, ypos, + width, height); + map = screen->transfer_map(screen, acc_pt); - /* note acc_strb->format might not equal acc_ps->format */ + /* note acc_strb->format might not equal acc_pt->format */ switch (acc_strb->format) { case PIPE_FORMAT_R16G16B16A16_SNORM: { @@ -133,7 +133,7 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) GLshort a = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]); int i, j; for (i = 0; i < height; i++) { - GLshort *dst = (GLshort *) (map + (ypos + i) * acc_ps->stride + xpos * 8); + GLshort *dst = (GLshort *) (map + i * acc_pt->stride + xpos * 8); for (j = 0; j < width; j++) { dst[0] = r; dst[1] = g; @@ -148,8 +148,8 @@ st_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) _mesa_problem(ctx, "unexpected format in st_clear_accum_buffer()"); } - screen->surface_unmap(screen, acc_ps); - pipe_surface_reference(&acc_ps, NULL); + screen->transfer_unmap(screen, acc_pt); + screen->tex_transfer_release(screen, &acc_pt); } @@ -160,19 +160,21 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, struct st_renderbuffer *acc_strb) { struct pipe_screen *screen = ctx->st->pipe->screen; - struct pipe_surface *acc_ps = acc_strb->surface; + struct pipe_transfer *acc_pt; GLubyte *map; - map = screen->surface_map(screen, acc_ps, - PIPE_BUFFER_USAGE_CPU_WRITE); + acc_pt = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ_WRITE, xpos, ypos, + width, height); + map = screen->transfer_map(screen, acc_pt); - /* note acc_strb->format might not equal acc_ps->format */ + /* note acc_strb->format might not equal acc_pt->format */ switch (acc_strb->format) { case PIPE_FORMAT_R16G16B16A16_SNORM: { int i, j; for (i = 0; i < height; i++) { - GLshort *acc = (GLshort *) (map + (ypos + i) * acc_ps->stride + xpos * 8); + GLshort *acc = (GLshort *) (map + (ypos + i) * acc_pt->stride + xpos * 8); for (j = 0; j < width * 4; j++) { float val = SHORT_TO_FLOAT(acc[j]) * scale + bias; acc[j] = FLOAT_TO_SHORT(val); @@ -184,7 +186,8 @@ accum_mad(GLcontext *ctx, GLfloat scale, GLfloat bias, _mesa_problem(NULL, "unexpected format in st_clear_accum_buffer()"); } - screen->surface_unmap(screen, acc_ps); + screen->transfer_unmap(screen, acc_pt); + screen->tex_transfer_release(screen, &acc_pt); } @@ -195,33 +198,39 @@ accum_accum(struct pipe_context *pipe, GLfloat value, struct st_renderbuffer *color_strb) { struct pipe_screen *screen = pipe->screen; - struct pipe_surface *acc_surf, *color_surf; + struct pipe_transfer *acc_trans, *color_trans; GLfloat *colorBuf, *accBuf; GLint i; - acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, - (PIPE_BUFFER_USAGE_CPU_WRITE | - PIPE_BUFFER_USAGE_CPU_READ)); + acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, xpos, ypos, + width, height); - color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_READ); + color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, xpos, ypos, + width, height); colorBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); accBuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, colorBuf); - acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf); + pipe_get_tile_rgba(color_trans, 0, 0, width, height, colorBuf); + acc_get_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf); for (i = 0; i < 4 * width * height; i++) { accBuf[i] = accBuf[i] + colorBuf[i] * value; } - acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, accBuf); + screen->tex_transfer_release(screen, &acc_trans); + acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, xpos, ypos, + width, height); + + acc_put_tile_rgba(pipe, acc_trans, 0, 0, width, height, accBuf); free(colorBuf); free(accBuf); - pipe_surface_reference(&acc_surf, NULL); - pipe_surface_reference(&color_surf, NULL); + screen->tex_transfer_release(screen, &acc_trans); + screen->tex_transfer_release(screen, &color_trans); } @@ -232,29 +241,31 @@ accum_load(struct pipe_context *pipe, GLfloat value, struct st_renderbuffer *color_strb) { struct pipe_screen *screen = pipe->screen; - struct pipe_surface *acc_surf, *color_surf; + struct pipe_transfer *acc_trans, *color_trans; GLfloat *buf; GLint i; - acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); + acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, xpos, ypos, + width, height); - color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_READ); + color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, xpos, ypos, + width, height); buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, buf); + pipe_get_tile_rgba(color_trans, xpos, ypos, width, height, buf); for (i = 0; i < 4 * width * height; i++) { buf[i] = buf[i] * value; } - acc_put_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, buf); + acc_put_tile_rgba(pipe, acc_trans, xpos, ypos, width, height, buf); free(buf); - pipe_surface_reference(&acc_surf, NULL); - pipe_surface_reference(&color_surf, NULL); + screen->tex_transfer_release(screen, &acc_trans); + screen->tex_transfer_release(screen, &color_trans); } @@ -267,24 +278,25 @@ accum_return(GLcontext *ctx, GLfloat value, struct pipe_context *pipe = ctx->st->pipe; struct pipe_screen *screen = pipe->screen; const GLubyte *colormask = ctx->Color.ColorMask; - struct pipe_surface *acc_surf, *color_surf; + struct pipe_transfer *acc_trans, *color_trans; GLfloat *abuf, *cbuf = NULL; GLint i, ch; abuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - acc_surf = screen->get_tex_surface(screen, acc_strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_READ); + acc_trans = screen->get_tex_transfer(screen, acc_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, xpos, ypos, + width, height); - color_surf = screen->get_tex_surface(screen, color_strb->texture, 0, 0, 0, - (PIPE_BUFFER_USAGE_CPU_READ | - PIPE_BUFFER_USAGE_CPU_WRITE)); + color_trans = screen->get_tex_transfer(screen, color_strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ_WRITE, xpos, ypos, + width, height); - acc_get_tile_rgba(pipe, acc_surf, xpos, ypos, width, height, abuf); + acc_get_tile_rgba(pipe, acc_trans, xpos, ypos, width, height, abuf); if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) { cbuf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, cbuf); + pipe_get_tile_rgba(color_trans, xpos, ypos, width, height, cbuf); } for (i = 0; i < width * height; i++) { @@ -299,13 +311,13 @@ accum_return(GLcontext *ctx, GLfloat value, } } - pipe_put_tile_rgba(color_surf, xpos, ypos, width, height, abuf); + pipe_put_tile_rgba(color_trans, xpos, ypos, width, height, abuf); free(abuf); if (cbuf) free(cbuf); - pipe_surface_reference(&acc_surf, NULL); - pipe_surface_reference(&color_surf, NULL); + screen->tex_transfer_release(screen, &acc_trans); + screen->tex_transfer_release(screen, &color_trans); } diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index f14e562400..93f1f0baac 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -93,7 +93,7 @@ struct bitmap_cache GLfloat color[4]; struct pipe_texture *texture; - struct pipe_surface *surf; + struct pipe_transfer *trans; GLboolean empty; @@ -308,7 +308,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, { struct pipe_context *pipe = ctx->st->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_surface *surface; + struct pipe_transfer *transfer; ubyte *dest; struct pipe_texture *pt; @@ -329,22 +329,21 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height, return NULL; } - surface = screen->get_tex_surface(screen, pt, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); + transfer = screen->get_tex_transfer(screen, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, + 0, 0, width, height); - /* map texture surface */ - dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE); + dest = screen->transfer_map(screen, transfer); - /* Put image into texture surface */ - memset(dest, 0xff, height * surface->stride); + /* Put image into texture transfer */ + memset(dest, 0xff, height * transfer->stride); unpack_bitmap(ctx->st, 0, 0, width, height, unpack, bitmap, - dest, surface->stride); + dest, transfer->stride); _mesa_unmap_bitmap_pbo(ctx, unpack); - /* Release surface */ - screen->surface_unmap(screen, surface); - pipe_surface_reference(&surface, NULL); + /* Release transfer */ + screen->transfer_unmap(screen, transfer); + screen->tex_transfer_release(screen, &transfer); return pt; } @@ -569,8 +568,8 @@ reset_cache(struct st_context *st) cache->ymin = 1000000; cache->ymax = -1000000; - if (cache->surf) - screen->tex_surface_release(screen, &cache->surf); + if (cache->trans) + screen->tex_transfer_release(screen, &cache->trans); assert(!cache->texture); @@ -581,16 +580,17 @@ reset_cache(struct st_context *st) 1, 0, PIPE_TEXTURE_USAGE_SAMPLER); - /* Map the texture surface. + /* Map the texture transfer. * Subsequent glBitmap calls will write into the texture image. */ - cache->surf = screen->get_tex_surface(screen, cache->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); - cache->buffer = screen->surface_map(screen, cache->surf, - PIPE_BUFFER_USAGE_CPU_WRITE); + cache->trans = screen->get_tex_transfer(screen, cache->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, 0, 0, + BITMAP_CACHE_WIDTH, + BITMAP_CACHE_HEIGHT); + cache->buffer = screen->transfer_map(screen, cache->trans); /* init image to all 0xff */ - memset(cache->buffer, 0xff, BITMAP_CACHE_WIDTH * BITMAP_CACHE_HEIGHT); + memset(cache->buffer, 0xff, cache->trans->stride * BITMAP_CACHE_HEIGHT); } @@ -615,13 +615,13 @@ st_flush_bitmap_cache(struct st_context *st) cache->xpos, cache->ypos); */ - /* The texture surface has been mapped until now. - * So unmap and release the texture surface before drawing. + /* The texture transfer has been mapped until now. + * So unmap and release the texture transfer before drawing. */ - screen->surface_unmap(screen, cache->surf); + screen->transfer_unmap(screen, cache->trans); cache->buffer = NULL; - screen->tex_surface_release(screen, &cache->surf); + screen->tex_transfer_release(screen, &cache->trans); draw_bitmap_quad(st->ctx, cache->xpos, @@ -812,8 +812,8 @@ st_destroy_bitmap(struct st_context *st) struct pipe_screen *screen = pipe->screen; struct bitmap_cache *cache = st->bitmap.cache; - screen->surface_unmap(screen, cache->surf); - screen->tex_surface_release(screen, &cache->surf); + screen->transfer_unmap(screen, cache->trans); + screen->tex_transfer_release(screen, &cache->trans); if (st->bitmap.vs) { cso_delete_vertex_shader(st->cso_context, st->bitmap.vs); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 32bf21411d..9e30e638e4 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -358,7 +358,7 @@ make_texture(struct st_context *st, } { - struct pipe_surface *surface; + struct pipe_transfer *transfer; static const GLuint dstImageOffsets = 0; GLboolean success; GLubyte *dest; @@ -367,14 +367,14 @@ make_texture(struct st_context *st, /* we'll do pixel transfer in a fragment shader */ ctx->_ImageTransferState = 0x0; - surface = screen->get_tex_surface(screen, pt, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); + transfer = screen->get_tex_transfer(screen, pt, 0, 0, 0, + PIPE_TRANSFER_WRITE, 0, 0, + width, height); - /* map texture surface */ - dest = screen->surface_map(screen, surface, - PIPE_BUFFER_USAGE_CPU_WRITE); + /* map texture transfer */ + dest = screen->transfer_map(screen, transfer); - /* Put image into texture surface. + /* Put image into texture transfer. * Note that the image is actually going to be upside down in * the texture. We deal with that with texcoords. */ @@ -383,7 +383,7 @@ make_texture(struct st_context *st, mformat, /* gl_texture_format */ dest, /* dest */ 0, 0, 0, /* dstX/Y/Zoffset */ - surface->stride, /* dstRowStride, bytes */ + transfer->stride, /* dstRowStride, bytes */ &dstImageOffsets, /* dstImageOffsets */ width, height, 1, /* size */ format, type, /* src format/type */ @@ -391,8 +391,8 @@ make_texture(struct st_context *st, unpack); /* unmap */ - screen->surface_unmap(screen, surface); - pipe_surface_reference(&surface, NULL); + screen->transfer_unmap(screen, transfer); + screen->tex_transfer_release(screen, &transfer); assert(success); @@ -740,7 +740,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct st_renderbuffer *strb; - struct pipe_surface *ps; + struct pipe_transfer *pt; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; GLint skipPixels; ubyte *stmap; @@ -749,21 +749,20 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, strb = st_renderbuffer(ctx->DrawBuffer-> Attachment[BUFFER_STENCIL].Renderbuffer); - ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); + pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, x, y, + width, height); - /* map the stencil buffer */ - stmap = screen->surface_map(screen, ps, - PIPE_BUFFER_USAGE_CPU_WRITE); + stmap = screen->transfer_map(screen, pt); /* if width > MAX_WIDTH, have to process image in chunks */ skipPixels = 0; while (skipPixels < width) { - const GLint spanX = x + skipPixels; + const GLint spanX = skipPixels; const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); GLint row; for (row = 0; row < height; row++) { - GLint spanY = y + row; + GLint spanY = row; GLubyte values[MAX_WIDTH]; GLenum destType = GL_UNSIGNED_BYTE; const GLvoid *source = _mesa_image_address2d(unpack, pixels, @@ -775,7 +774,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, ctx->_ImageTransferState); if (zoom) { /* - _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth, + _swrast_write_zoomed_stencil_span(ctx, 0, 0, spanWidth, spanX, spanY, values); */ } @@ -784,16 +783,16 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, spanY = ctx->DrawBuffer->Height - spanY - 1; } - switch (ps->format) { + switch (pt->format) { case PIPE_FORMAT_S8_UNORM: { - ubyte *dest = stmap + spanY * ps->stride + spanX; + ubyte *dest = stmap + spanY * pt->stride + spanX; memcpy(dest, values, spanWidth); } break; case PIPE_FORMAT_S8Z24_UNORM: { - uint *dest = (uint *) (stmap + spanY * ps->stride + spanX*4); + uint *dest = (uint *) (stmap + spanY * pt->stride + spanX*4); GLint k; for (k = 0; k < spanWidth; k++) { uint p = dest[k]; @@ -811,8 +810,8 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y, } /* unmap the stencil buffer */ - screen->surface_unmap(screen, ps); - pipe_surface_reference(&ps, NULL); + screen->transfer_unmap(screen, pt); + screen->tex_transfer_release(screen, &pt); } @@ -891,7 +890,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, { struct st_renderbuffer *rbDraw = st_renderbuffer(ctx->DrawBuffer->_StencilBuffer); struct pipe_screen *screen = ctx->st->pipe->screen; - struct pipe_surface *psDraw; + struct pipe_transfer *ptDraw; ubyte *drawMap; ubyte *buffer; int i; @@ -906,14 +905,15 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, st_read_stencil_pixels(ctx, srcx, srcy, width, height, GL_UNSIGNED_BYTE, &ctx->DefaultPacking, buffer); - psDraw = screen->get_tex_surface(screen, rbDraw->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); + ptDraw = screen->get_tex_transfer(screen, rbDraw->texture, 0, 0, 0, + PIPE_TRANSFER_WRITE, dstx, dsty, + width, height); - assert(psDraw->block.width == 1); - assert(psDraw->block.height == 1); + assert(ptDraw->block.width == 1); + assert(ptDraw->block.height == 1); /* map the stencil buffer */ - drawMap = screen->surface_map(screen, psDraw, PIPE_BUFFER_USAGE_CPU_WRITE); + drawMap = screen->transfer_map(screen, ptDraw); /* draw */ /* XXX PixelZoom not handled yet */ @@ -922,16 +922,16 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, const ubyte *src; int y; - y = dsty + i; + y = i; if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { y = ctx->DrawBuffer->Height - y - 1; } - dst = drawMap + y * psDraw->stride + dstx * psDraw->block.size; + dst = drawMap + y * ptDraw->stride; src = buffer + i * width; - switch (psDraw->format) { + switch (ptDraw->format) { case PIPE_FORMAT_S8Z24_UNORM: { uint *dst4 = (uint *) dst; @@ -953,8 +953,8 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy, free(buffer); /* unmap the stencil buffer */ - screen->surface_unmap(screen, psDraw); - pipe_surface_reference(&psDraw, NULL); + screen->transfer_unmap(screen, ptDraw); + screen->tex_transfer_release(screen, &ptDraw); } @@ -969,7 +969,6 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct st_renderbuffer *rbRead; struct st_vertex_program *stvp; struct st_fragment_program *stfp; - struct pipe_surface *psTex; struct pipe_texture *pt; GLfloat *color; enum pipe_format srcFormat, texFormat; @@ -1035,7 +1034,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct pipe_surface *psRead = screen->get_tex_surface(screen, rbRead->texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ); - psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, + struct pipe_surface *psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE ); pipe->surface_copy(pipe, FALSE, @@ -1043,37 +1042,40 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, 0, 0, /* destx/y */ psRead, srcx, srcy, width, height); - pipe_surface_reference(&psRead, NULL); + pipe_surface_reference(&psRead, NULL); + pipe_surface_reference(&psTex, NULL); } else { /* CPU-based fallback/conversion */ - struct pipe_surface *psRead = screen->get_tex_surface(screen, - rbRead->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_READ); + struct pipe_transfer *ptRead = + screen->get_tex_transfer(screen, rbRead->texture, 0, 0, 0, + PIPE_TRANSFER_READ, srcx, srcy, width, + height); - psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_WRITE ); + struct pipe_transfer *ptTex = + screen->get_tex_transfer(screen, pt, 0, 0, 0, PIPE_TRANSFER_WRITE, + 0, 0, width, height); if (type == GL_COLOR) { /* alternate path using get/put_tile() */ GLfloat *buf = (GLfloat *) malloc(width * height * 4 * sizeof(GLfloat)); - pipe_get_tile_rgba(psRead, srcx, srcy, width, height, buf); - pipe_put_tile_rgba(psTex, 0, 0, width, height, buf); + pipe_get_tile_rgba(ptRead, 0, 0, width, height, buf); + pipe_put_tile_rgba(ptTex, 0, 0, width, height, buf); free(buf); } else { /* GL_DEPTH */ GLuint *buf = (GLuint *) malloc(width * height * sizeof(GLuint)); - pipe_get_tile_z(psRead, srcx, srcy, width, height, buf); - pipe_put_tile_z(psTex, 0, 0, width, height, buf); + pipe_get_tile_z(ptRead, srcx, srcy, width, height, buf); + pipe_put_tile_z(ptTex, 0, 0, width, height, buf); free(buf); } - pipe_surface_reference(&psRead, NULL); - } - pipe_surface_reference(&psTex, NULL); + screen->tex_transfer_release(screen, &ptRead); + screen->tex_transfer_release(screen, &ptTex); + } /* draw textured quad */ draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index 963ac902d2..7787cc93f3 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -172,12 +172,8 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, assert(strb->surface->texture); assert(strb->surface->format); - assert(strb->surface->block.size); - assert(strb->surface->block.width); - assert(strb->surface->block.height); assert(strb->surface->width == width); assert(strb->surface->height == height); - assert(strb->surface->stride); return strb->surface != NULL; diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 646eaff190..e763827c3c 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -63,44 +63,48 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, struct gl_framebuffer *fb = ctx->ReadBuffer; struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb = st_renderbuffer(fb->_StencilBuffer); - struct pipe_surface *ps; + struct pipe_transfer *pt; ubyte *stmap; GLint j; - /* Create a CPU-READ surface/view into the renderbuffer's texture */ - ps = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_READ); + if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { + y = ctx->DrawBuffer->Height - y - 1; + } + + /* Create a read transfer from the renderbuffer's texture */ + pt = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, x, y, width, height); /* map the stencil buffer */ - stmap = screen->surface_map(screen, ps, PIPE_BUFFER_USAGE_CPU_READ); + stmap = screen->transfer_map(screen, pt); /* width should never be > MAX_WIDTH since we did clipping earlier */ ASSERT(width <= MAX_WIDTH); /* process image row by row */ - for (j = 0; j < height; j++, y++) { + for (j = 0; j < height; j++) { GLvoid *dest; GLstencil values[MAX_WIDTH]; GLint srcY; if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { - srcY = ctx->DrawBuffer->Height - y - 1; + srcY = height - j - 1; } else { - srcY = y; + srcY = j; } /* get stencil values */ - switch (ps->format) { + switch (pt->format) { case PIPE_FORMAT_S8_UNORM: { - const ubyte *src = stmap + srcY * ps->stride + x; + const ubyte *src = stmap + srcY * pt->stride; memcpy(values, src, width); } break; case PIPE_FORMAT_S8Z24_UNORM: { - const uint *src = (uint *) (stmap + srcY * ps->stride + x*4); + const uint *src = (uint *) (stmap + srcY * pt->stride); GLint k; for (k = 0; k < width; k++) { values[k] = src[k] >> 24; @@ -109,7 +113,7 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, break; case PIPE_FORMAT_Z24S8_UNORM: { - const uint *src = (uint *) (stmap + srcY * ps->stride + x*4); + const uint *src = (uint *) (stmap + srcY * pt->stride); GLint k; for (k = 0; k < width; k++) { values[k] = src[k] & 0xff; @@ -129,8 +133,8 @@ st_read_stencil_pixels(GLcontext *ctx, GLint x, GLint y, /* unmap the stencil buffer */ - screen->surface_unmap(screen, ps); - pipe_surface_reference(&ps, NULL); + screen->transfer_unmap(screen, pt); + screen->tex_transfer_release(screen, &pt); } @@ -203,28 +207,33 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, { struct pipe_context *pipe = ctx->st->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_surface *surf; + struct pipe_transfer *trans; const GLubyte *map; GLubyte *dst; GLint row, col, dy, dstStride; - surf = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_READ); - if (!surf) { + if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { + y = strb->texture->height[0] - y - 1; + } + + trans = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, x, y, width, height); + if (!trans) { return GL_FALSE; } - map = screen->surface_map(screen, surf, PIPE_BUFFER_USAGE_CPU_READ); + map = screen->transfer_map(screen, trans); if (!map) { - pipe_surface_reference(&surf, NULL); + screen->tex_transfer_release(screen, &trans); return GL_FALSE; } if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { - y = surf->height - y - 1; + y = height - y - 1; dy = -1; } else { + y = 0; dy = 1; } @@ -235,7 +244,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, switch (combo) { case A8R8G8B8_UNORM_TO_RGBA_UBYTE: for (row = 0; row < height; row++) { - const GLubyte *src = map + y * surf->stride + x * 4; + const GLubyte *src = map + y * trans->stride; for (col = 0; col < width; col++) { GLuint pixel = ((GLuint *) src)[col]; dst[col*4+0] = (pixel >> 16) & 0xff; @@ -249,7 +258,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, break; case A8R8G8B8_UNORM_TO_RGB_UBYTE: for (row = 0; row < height; row++) { - const GLubyte *src = map + y * surf->stride + x * 4; + const GLubyte *src = map + y * trans->stride; for (col = 0; col < width; col++) { GLuint pixel = ((GLuint *) src)[col]; dst[col*3+0] = (pixel >> 16) & 0xff; @@ -262,7 +271,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, break; case A8R8G8B8_UNORM_TO_BGRA_UINT: for (row = 0; row < height; row++) { - const GLubyte *src = map + y * surf->stride + x * 4; + const GLubyte *src = map + y * trans->stride; memcpy(dst, src, 4 * width); dst += dstStride; y += dy; @@ -272,8 +281,8 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, ; /* nothing */ } - screen->surface_unmap(screen, surf); - pipe_surface_reference(&surf, NULL); + screen->transfer_unmap(screen, trans); + screen->tex_transfer_release(screen, &trans); } return GL_TRUE; @@ -281,7 +290,7 @@ st_fast_readpixels(GLcontext *ctx, struct st_renderbuffer *strb, /** - * Do glReadPixels by getting rows from the framebuffer surface with + * Do glReadPixels by getting rows from the framebuffer transfer with * get_tile(). Convert to requested format/type with Mesa image routines. * Image transfer ops are done in software too. */ @@ -300,7 +309,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLfloat *df; struct st_renderbuffer *strb; struct gl_pixelstore_attrib clippedPacking = *pack; - struct pipe_surface *surf; + struct pipe_transfer *trans; assert(ctx->ReadBuffer->Width > 0); @@ -309,7 +318,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* Do all needed clipping here, so that we can forget about it later */ if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) { - /* The ReadPixels surface is totally outside the window bounds */ + /* The ReadPixels transfer is totally outside the window bounds */ return; } @@ -355,21 +364,26 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, dfStride = 0; } - /* determine bottom-to-top vs. top-to-bottom order */ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { y = strb->Base.Height - 1 - y; + } + + /* Create a read transfer from the renderbuffer's texture */ + trans = screen->get_tex_transfer(screen, strb->texture, 0, 0, 0, + PIPE_TRANSFER_READ, x, y, width, height); + + /* determine bottom-to-top vs. top-to-bottom order */ + if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { + y = trans->height - 1 - y; yStep = -1; } else { + y = 0; yStep = 1; } - /* Create a CPU-READ surface/view into the renderbuffer's texture */ - surf = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_READ); - /* - * Copy pixels from pipe_surface to user memory + * Copy pixels from pipe_transfer to user memory */ { /* dest of first pixel in client memory */ @@ -379,14 +393,14 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, const GLint dstStride = _mesa_image_row_stride(&clippedPacking, width, format, type); - if (surf->format == PIPE_FORMAT_S8Z24_UNORM || - surf->format == PIPE_FORMAT_X8Z24_UNORM) { + if (trans->format == PIPE_FORMAT_S8Z24_UNORM || + trans->format == PIPE_FORMAT_X8Z24_UNORM) { if (format == GL_DEPTH_COMPONENT) { for (i = 0; i < height; i++) { GLuint ztemp[MAX_WIDTH]; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / ((1 << 24) - 1); - pipe_get_tile_raw(surf, x, y, width, 1, ztemp, 0); + pipe_get_tile_raw(trans, 0, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * (ztemp[j] & 0xffffff)); @@ -400,18 +414,18 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* untested, but simple: */ assert(format == GL_DEPTH_STENCIL_EXT); for (i = 0; i < height; i++) { - pipe_get_tile_raw(surf, x, y, width, 1, dst, 0); + pipe_get_tile_raw(trans, 0, y, width, 1, dst, 0); y += yStep; dst += dstStride; } } } - else if (surf->format == PIPE_FORMAT_Z16_UNORM) { + else if (trans->format == PIPE_FORMAT_Z16_UNORM) { for (i = 0; i < height; i++) { GLushort ztemp[MAX_WIDTH]; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / 0xffff; - pipe_get_tile_raw(surf, x, y, width, 1, ztemp, 0); + pipe_get_tile_raw(trans, 0, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * ztemp[j]); @@ -421,12 +435,12 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, dst += dstStride; } } - else if (surf->format == PIPE_FORMAT_Z32_UNORM) { + else if (trans->format == PIPE_FORMAT_Z32_UNORM) { for (i = 0; i < height; i++) { GLuint ztemp[MAX_WIDTH]; GLfloat zfloat[MAX_WIDTH]; const double scale = 1.0 / 0xffffffff; - pipe_get_tile_raw(surf, x, y, width, 1, ztemp, 0); + pipe_get_tile_raw(trans, 0, y, width, 1, ztemp, 0); y += yStep; for (j = 0; j < width; j++) { zfloat[j] = (float) (scale * ztemp[j]); @@ -440,7 +454,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, /* RGBA format */ /* Do a row at a time to flip image data vertically */ for (i = 0; i < height; i++) { - pipe_get_tile_rgba(surf, x, y, width, 1, df); + pipe_get_tile_rgba(trans, 0, y, width, 1, df); y += yStep; df += dfStride; if (!dfStride) { @@ -452,7 +466,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, } } - pipe_surface_reference(&surf, NULL); + screen->tex_transfer_release(screen, &trans); _mesa_unmap_readpix_pbo(ctx, &clippedPacking); } diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index d08229b57a..ec981e8e46 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -524,9 +524,10 @@ st_TexImage(GLcontext * ctx, if (stImage->pt) { texImage->Data = st_texture_image_map(ctx->st, stImage, 0, - PIPE_BUFFER_USAGE_CPU_WRITE); - if (stImage->surface) - dstRowStride = stImage->surface->stride; + PIPE_TRANSFER_WRITE, 0, 0, + stImage->base.Width, + stImage->base.Height); + dstRowStride = stImage->transfer->stride; } else { /* Allocate regular memory and store the image there temporarily. */ @@ -581,7 +582,9 @@ st_TexImage(GLcontext * ctx, if (stImage->pt && i < depth) { st_texture_image_unmap(ctx->st, stImage); texImage->Data = st_texture_image_map(ctx->st, stImage, i, - PIPE_BUFFER_USAGE_CPU_WRITE); + PIPE_TRANSFER_WRITE, 0, 0, + stImage->base.Width, + stImage->base.Height); src += srcImageStride; } } @@ -688,8 +691,10 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, * kernel. Need to explicitly map and unmap it. */ texImage->Data = st_texture_image_map(ctx->st, stImage, 0, - PIPE_BUFFER_USAGE_CPU_READ); - texImage->RowStride = stImage->surface->stride / stImage->pt->block.size; + PIPE_TRANSFER_READ, 0, 0, + stImage->base.Width, + stImage->base.Height); + texImage->RowStride = stImage->transfer->stride / stImage->pt->block.size; } else { /* Otherwise, the image should actually be stored in @@ -720,7 +725,9 @@ st_get_tex_image(GLcontext * ctx, GLenum target, GLint level, if (stImage->pt && i < depth) { st_texture_image_unmap(ctx->st, stImage); texImage->Data = st_texture_image_map(ctx->st, stImage, i, - PIPE_BUFFER_USAGE_CPU_READ); + PIPE_TRANSFER_READ, 0, 0, + stImage->base.Width, + stImage->base.Height); dest += dstImageStride; } } @@ -792,9 +799,11 @@ st_TexSubimage(GLcontext * ctx, */ if (stImage->pt) { texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset, - PIPE_BUFFER_USAGE_CPU_WRITE); - if (stImage->surface) - dstRowStride = stImage->surface->stride; + PIPE_TRANSFER_WRITE, + xoffset, yoffset, + stImage->base.Width, + stImage->base.Height); + dstRowStride = stImage->transfer->stride; } if (!texImage->Data) { @@ -820,7 +829,10 @@ st_TexSubimage(GLcontext * ctx, /* map next slice of 3D texture */ st_texture_image_unmap(ctx->st, stImage); texImage->Data = st_texture_image_map(ctx->st, stImage, zoffset + i, - PIPE_BUFFER_USAGE_CPU_WRITE); + PIPE_TRANSFER_WRITE, + xoffset, yoffset, + stImage->base.Width, + stImage->base.Height); src += srcImageStride; } } @@ -898,26 +910,8 @@ st_TexSubImage1D(GLcontext * ctx, /** - * Return 0 for GL_TEXTURE_CUBE_MAP_POSITIVE_X, - * 1 for GL_TEXTURE_CUBE_MAP_NEGATIVE_X, - * etc. - * XXX duplicated from main/teximage.c - */ -static uint -texture_face(GLenum target) -{ - if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && - target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) - return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X; - else - return 0; -} - - - -/** - * Do a CopyTexSubImage operation by mapping the source surface and - * dest surface and using get_tile()/put_tile() to access the pixels/texels. + * Do a CopyTexSubImage operation using a read transfer from the source, a write + * transfer to the destination and get_tile()/put_tile() to access the pixels/texels. * * Note: srcY=0=TOP of renderbuffer */ @@ -934,20 +928,24 @@ fallback_copy_texsubimage(GLcontext *ctx, { struct pipe_context *pipe = ctx->st->pipe; struct pipe_screen *screen = pipe->screen; - const uint face = texture_face(target); - struct pipe_texture *pt = stImage->pt; - struct pipe_surface *src_surf, *dest_surf; + struct pipe_transfer *src_trans; + GLvoid *texDest; + + assert(width <= MAX_WIDTH); - /* We'd use strb->surface, here but it's created for GPU read/write only */ - src_surf = pipe->screen->get_tex_surface( pipe->screen, - strb->texture, - 0, 0, 0, - PIPE_BUFFER_USAGE_CPU_READ); + if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { + srcY = strb->Base.Height - 1 - srcY; + } - dest_surf = screen->get_tex_surface(screen, pt, face, level, destZ, - PIPE_BUFFER_USAGE_CPU_WRITE); + src_trans = pipe->screen->get_tex_transfer( pipe->screen, + strb->texture, + 0, 0, 0, + PIPE_TRANSFER_READ, + srcX, srcY, + width, height); - assert(width <= MAX_WIDTH); + texDest = st_texture_image_map(ctx->st, stImage, 0, PIPE_TRANSFER_WRITE, + destX, destY, width, height); if (baseFormat == GL_DEPTH_COMPONENT) { const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F || @@ -956,39 +954,36 @@ fallback_copy_texsubimage(GLcontext *ctx, /* determine bottom-to-top vs. top-to-bottom order for src buffer */ if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { - srcY = strb->Base.Height - 1 - srcY; + srcY = height - 1 - srcY; yStep = -1; } else { + srcY = 0; yStep = 1; } /* To avoid a large temp memory allocation, do copy row by row */ - for (row = 0; row < height; row++, srcY += yStep, destY++) { + for (row = 0; row < height; row++, srcY += yStep) { uint data[MAX_WIDTH]; - pipe_get_tile_z(src_surf, srcX, srcY, width, 1, data); + pipe_get_tile_z(src_trans, 0, srcY, width, 1, data); if (scaleOrBias) { _mesa_scale_and_bias_depth_uint(ctx, width, data); } - pipe_put_tile_z(dest_surf, destX, destY, width, 1, data); + pipe_put_tile_z(stImage->transfer, 0, row, width, 1, data); } } else { /* RGBA format */ GLfloat *tempSrc = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); - GLvoid *texDest = - st_texture_image_map(ctx->st, stImage, 0,PIPE_BUFFER_USAGE_CPU_WRITE); if (tempSrc && texDest) { const GLint dims = 2; struct gl_texture_image *texImage = &stImage->base; - GLint dstRowStride = stImage->surface->stride; + GLint dstRowStride = stImage->transfer->stride; struct gl_pixelstore_attrib unpack = ctx->DefaultPacking; if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { - /* need to invert src */ - srcY = strb->Base.Height - srcY - height; unpack.Invert = GL_TRUE; } @@ -996,7 +991,7 @@ fallback_copy_texsubimage(GLcontext *ctx, /* XXX this usually involves a lot of int/float conversion. * try to avoid that someday. */ - pipe_get_tile_rgba(src_surf, srcX, srcY, width, height, tempSrc); + pipe_get_tile_rgba(src_trans, 0, 0, width, height, tempSrc); /* Store into texture memory. * Note that this does some special things such as pixel transfer @@ -1008,7 +1003,7 @@ fallback_copy_texsubimage(GLcontext *ctx, texImage->_BaseFormat, texImage->TexFormat, texDest, - destX, destY, destZ, + 0, 0, 0, dstRowStride, texImage->ImageOffsets, width, height, 1, @@ -1021,12 +1016,10 @@ fallback_copy_texsubimage(GLcontext *ctx, if (tempSrc) _mesa_free(tempSrc); - if (texDest) - st_texture_image_unmap(ctx->st, stImage); } - screen->tex_surface_release(screen, &dest_surf); - screen->tex_surface_release(screen, &src_surf); + st_texture_image_unmap(ctx->st, stImage); + screen->tex_transfer_release(screen, &src_trans); } diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index 6a3455aaba..08e4803068 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -119,36 +119,36 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { const uint srcLevel = dstLevel - 1; - struct pipe_surface *srcSurf, *dstSurf; + struct pipe_transfer *srcTrans, *dstTrans; const ubyte *srcData; ubyte *dstData; - 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); + 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]); - srcData = (ubyte *) pipe_surface_map(srcSurf, - PIPE_BUFFER_USAGE_CPU_READ) - + srcSurf->offset; - dstData = (ubyte *) pipe_surface_map(dstSurf, - PIPE_BUFFER_USAGE_CPU_WRITE) - + dstSurf->offset; + srcData = (ubyte *) screen->transfer_map(screen, srcTrans); + dstData = (ubyte *) screen->transfer_map(screen, dstTrans); _mesa_generate_mipmap_level(target, datatype, comps, 0 /*border*/, pt->width[srcLevel], pt->height[srcLevel], pt->depth[srcLevel], srcData, - srcSurf->stride, /* stride in bytes */ + srcTrans->stride, /* stride in bytes */ pt->width[dstLevel], pt->height[dstLevel], pt->depth[dstLevel], dstData, - dstSurf->stride); /* stride in bytes */ + dstTrans->stride); /* stride in bytes */ - 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); } } diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 63cfe5fc16..63a36324d4 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -191,19 +191,19 @@ st_texture_image_offset(const struct pipe_texture * pt, */ GLubyte * st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, - GLuint zoffset, - GLuint flags ) + GLuint zoffset, enum pipe_transfer_usage usage, + GLuint x, GLuint y, GLuint w, GLuint h) { struct pipe_screen *screen = st->pipe->screen; struct pipe_texture *pt = stImage->pt; DBG("%s \n", __FUNCTION__); - stImage->surface = screen->get_tex_surface(screen, pt, stImage->face, - stImage->level, zoffset, - flags); + stImage->transfer = screen->get_tex_transfer(screen, pt, stImage->face, + stImage->level, zoffset, + usage, x, y, w, h); - if (stImage->surface) - return screen->surface_map(screen, stImage->surface, flags); + if (stImage->transfer) + return screen->transfer_map(screen, stImage->transfer); else return NULL; } @@ -217,9 +217,9 @@ st_texture_image_unmap(struct st_context *st, DBG("%s\n", __FUNCTION__); - screen->surface_unmap(screen, stImage->surface); + screen->transfer_unmap(screen, stImage->transfer); - pipe_surface_reference(&stImage->surface, NULL); + screen->tex_transfer_release(screen, &stImage->transfer); } @@ -234,13 +234,13 @@ st_texture_image_unmap(struct st_context *st, */ static void st_surface_data(struct pipe_context *pipe, - struct pipe_surface *dst, + struct pipe_transfer *dst, unsigned dstx, unsigned dsty, const void *src, unsigned src_stride, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { struct pipe_screen *screen = pipe->screen; - void *map = screen->surface_map(screen, dst, PIPE_BUFFER_USAGE_CPU_WRITE); + void *map = screen->transfer_map(screen, dst); pipe_copy_rect(map, &dst->block, @@ -250,7 +250,7 @@ st_surface_data(struct pipe_context *pipe, src, src_stride, srcx, srcy); - screen->surface_unmap(screen, dst); + screen->transfer_unmap(screen, dst); } @@ -268,21 +268,23 @@ st_texture_image_data(struct pipe_context *pipe, GLuint depth = dst->depth[level]; GLuint i; const GLubyte *srcUB = src; - struct pipe_surface *dst_surface; + struct pipe_transfer *dst_transfer; DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { - dst_surface = screen->get_tex_surface(screen, dst, face, level, i, - PIPE_BUFFER_USAGE_CPU_WRITE); + dst_transfer = screen->get_tex_transfer(screen, dst, face, level, i, + PIPE_TRANSFER_WRITE, 0, 0, + dst->width[level], + dst->height[level]); - st_surface_data(pipe, dst_surface, + st_surface_data(pipe, dst_transfer, 0, 0, /* dstx, dsty */ srcUB, src_row_stride, 0, 0, /* source x, y */ dst->width[level], dst->height[level]); /* width, height */ - screen->tex_surface_release(screen, &dst_surface); + screen->tex_transfer_release(screen, &dst_transfer); srcUB += src_image_stride; } diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 31f66ad52c..840b7e27cc 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -50,7 +50,7 @@ struct st_texture_image */ struct pipe_texture *pt; - struct pipe_surface *surface; + struct pipe_transfer *transfer; }; @@ -132,7 +132,9 @@ extern GLubyte * st_texture_image_map(struct st_context *st, struct st_texture_image *stImage, GLuint zoffset, - GLuint flags); + enum pipe_transfer_usage usage, + unsigned x, unsigned y, + unsigned w, unsigned h); extern void st_texture_image_unmap(struct st_context *st, |