Conflicts: src/gallium/drivers/softpipe/sp_tile_cache.cundefined
@@ -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; | |||
} |
@@ -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); | |||
} | |||
@@ -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); |
@@ -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 | |||
} | |||
@@ -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); | |||
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); | |||
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); | |||
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); | |||
} |
@@ -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); | |||
} | |||
@@ -30,24 +30,24 @@ | |||
#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 *pt) | |||
{ | |||
if (x >= ps->width) | |||
if (x >= pt->width) | |||
return TRUE; | |||
if (y >= ps->height) | |||
if (y >= pt->height) | |||
return TRUE; | |||
if (x + *w > ps->width) | |||
*w = ps->width - x; | |||
if (y + *h > ps->height) | |||
*h = ps->height - y; | |||
if (x + *w > pt->width) | |||
*w = pt->width - x; | |||
if (y + *h > pt->height) | |||
*h = pt->height - y; | |||
return FALSE; | |||
} | |||
@@ -56,34 +56,34 @@ extern "C" { | |||
#endif | |||
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 *p, int dst_stride); | |||
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 *p, int src_stride); | |||
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); | |||
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); | |||
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); | |||
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 *z); | |||
@@ -204,17 +204,79 @@ i915_destroy_screen( struct pipe_screen *screen ) | |||
} | |||
static struct pipe_transfer* | |||
i915_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 i915_texture *tex = (struct i915_texture *)texture; | |||
struct i915_transfer *trans; | |||
unsigned offset; /* in bytes */ | |||
if (texture->target == PIPE_TEXTURE_CUBE) { | |||
offset = tex->image_offset[level][face]; | |||
} | |||
else if (texture->target == PIPE_TEXTURE_3D) { | |||
offset = tex->image_offset[level][zslice]; | |||
} | |||
else { | |||
offset = tex->image_offset[level][0]; | |||
assert(face == 0); | |||
assert(zslice == 0); | |||
} | |||
trans = CALLOC_STRUCT(i915_transfer); | |||
if (trans) { | |||
trans->base.refcount = 1; | |||
pipe_texture_reference(&trans->base.texture, texture); | |||
trans->base.format = trans->base.format; | |||
trans->base.width = w; | |||
trans->base.height = h; | |||
trans->base.block = texture->block; | |||
trans->base.nblocksx = texture->nblocksx[level]; | |||
trans->base.nblocksy = texture->nblocksy[level]; | |||
trans->base.stride = tex->stride; | |||
trans->offset = offset; | |||
trans->base.usage = usage; | |||
} | |||
return &trans->base; | |||
} | |||
static void | |||
i915_tex_transfer_release(struct pipe_screen *screen, | |||
struct pipe_transfer **transfer) | |||
{ | |||
struct pipe_transfer *trans = *transfer; | |||
if (--trans->refcount == 0) { | |||
pipe_texture_reference(&trans->texture, NULL); | |||
FREE(trans); | |||
} | |||
*transfer = NULL; | |||
} | |||
static void * | |||
i915_surface_map( struct pipe_screen *screen, | |||
struct pipe_surface *surface, | |||
unsigned flags ) | |||
i915_transfer_map( struct pipe_screen *screen, | |||
struct pipe_transfer *transfer ) | |||
{ | |||
struct i915_texture *tex = (struct i915_texture *)surface->texture; | |||
char *map = pipe_buffer_map( screen, tex->buffer, flags ); | |||
struct i915_texture *tex = (struct i915_texture *)transfer->texture; | |||
char *map; | |||
unsigned flags = 0; | |||
if (transfer->usage != PIPE_TRANSFER_WRITE) | |||
flags |= PIPE_BUFFER_USAGE_CPU_READ; | |||
if (transfer->usage != PIPE_TRANSFER_READ) | |||
flags |= PIPE_BUFFER_USAGE_CPU_WRITE; | |||
map = pipe_buffer_map( screen, tex->buffer, flags ); | |||
if (map == NULL) | |||
return NULL; | |||
if (surface->texture && | |||
if (transfer->texture && | |||
(flags & PIPE_BUFFER_USAGE_CPU_WRITE)) | |||
{ | |||
/* Do something to notify contexts of a texture change. | |||
@@ -222,14 +284,16 @@ i915_surface_map( struct pipe_screen *screen, | |||
/* i915_screen(screen)->timestamp++; */ | |||
} | |||
return map + surface->offset; | |||
return map + i915_transfer(transfer)->offset + | |||
transfer->y / transfer->block.height * transfer->stride + | |||
transfer->x / transfer->block.width * transfer->block.size; | |||
} | |||
static void | |||
i915_surface_unmap(struct pipe_screen *screen, | |||
struct pipe_surface *surface) | |||
i915_transfer_unmap(struct pipe_screen *screen, | |||
struct pipe_transfer *transfer) | |||
{ | |||
struct i915_texture *tex = (struct i915_texture *)surface->texture; | |||
struct i915_texture *tex = (struct i915_texture *)transfer->texture; | |||
pipe_buffer_unmap( screen, tex->buffer ); | |||
} | |||
@@ -278,8 +342,10 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id) | |||
i915screen->screen.get_param = i915_get_param; | |||
i915screen->screen.get_paramf = i915_get_paramf; | |||
i915screen->screen.is_format_supported = i915_is_format_supported; | |||
i915screen->screen.surface_map = i915_surface_map; | |||
i915screen->screen.surface_unmap = i915_surface_unmap; | |||
i915screen->screen.get_tex_transfer = i915_get_tex_transfer; | |||
i915screen->screen.tex_transfer_release = i915_tex_transfer_release; | |||
i915screen->screen.transfer_map = i915_transfer_map; | |||
i915screen->screen.transfer_unmap = i915_transfer_unmap; | |||
i915_init_screen_texture_functions(&i915screen->screen); | |||
u_simple_screen_init(&i915screen->screen); |
@@ -50,13 +50,30 @@ struct i915_screen | |||
}; | |||
/** cast wrapper */ | |||
/** | |||
* Subclass of pipe_transfer | |||
*/ | |||
struct i915_transfer | |||
{ | |||
struct pipe_transfer base; | |||
unsigned offset; | |||
}; | |||
/** cast wrappers */ | |||
static INLINE struct i915_screen * | |||
i915_screen(struct pipe_screen *pscreen) | |||
{ | |||
return (struct i915_screen *) pscreen; | |||
} | |||
static INLINE struct i915_transfer * | |||
i915_transfer( struct pipe_transfer *transfer ) | |||
{ | |||
return (struct i915_transfer *)transfer; | |||
} | |||
extern struct pipe_screen * | |||
i915_create_screen(struct pipe_winsys *winsys, uint pci_id); |
@@ -211,7 +211,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) | |||
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; | |||
if (cbuf_surface) { | |||
unsigned cpitch = cbuf_surface->stride; | |||
unsigned ctile = BUF_3D_USE_FENCE; | |||
struct i915_texture *tex = (struct i915_texture *) | |||
cbuf_surface->texture; | |||
@@ -225,7 +224,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) | |||
OUT_BATCH(_3DSTATE_BUF_INFO_CMD); | |||
OUT_BATCH(BUF_3D_ID_COLOR_BACK | | |||
BUF_3D_PITCH(cpitch) | /* pitch in bytes */ | |||
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ | |||
ctile); | |||
OUT_RELOC(tex->buffer, | |||
@@ -236,7 +235,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) | |||
/* What happens if no zbuf?? | |||
*/ | |||
if (depth_surface) { | |||
unsigned zpitch = depth_surface->stride; | |||
unsigned ztile = BUF_3D_USE_FENCE; | |||
struct i915_texture *tex = (struct i915_texture *) | |||
depth_surface->texture; | |||
@@ -250,7 +248,7 @@ i915_emit_hardware_state(struct i915_context *i915 ) | |||
OUT_BATCH(_3DSTATE_BUF_INFO_CMD); | |||
OUT_BATCH(BUF_3D_ID_DEPTH | | |||
BUF_3D_PITCH(zpitch) | /* pitch in bytes */ | |||
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ | |||
ztile); | |||
OUT_RELOC(tex->buffer, |
@@ -47,44 +47,22 @@ i915_surface_copy(struct pipe_context *pipe, | |||
struct pipe_surface *src, | |||
unsigned srcx, unsigned srcy, unsigned width, unsigned height) | |||
{ | |||
assert( dst != src ); | |||
assert( dst->block.size == src->block.size ); | |||
assert( dst->block.width == src->block.height ); | |||
assert( dst->block.height == src->block.height ); | |||
struct i915_texture *dst_tex = (struct i915_texture *)dst->texture; | |||
struct i915_texture *src_tex = (struct i915_texture *)src->texture; | |||
if (0) { | |||
void *dst_map = pipe->screen->surface_map( pipe->screen, | |||
dst, | |||
PIPE_BUFFER_USAGE_CPU_WRITE ); | |||
const void *src_map = pipe->screen->surface_map( pipe->screen, | |||
src, | |||
PIPE_BUFFER_USAGE_CPU_READ ); | |||
pipe_copy_rect(dst_map, | |||
&dst->block, | |||
dst->stride, | |||
dstx, dsty, | |||
width, height, | |||
src_map, | |||
do_flip ? -(int) src->stride : src->stride, | |||
srcx, do_flip ? height - 1 - srcy : srcy); | |||
assert( dst != src ); | |||
assert( dst_tex->base.block.size == src_tex->base.block.size ); | |||
assert( dst_tex->base.block.width == src_tex->base.block.height ); | |||
assert( dst_tex->base.block.height == src_tex->base.block.height ); | |||
assert( dst_tex->base.block.width == 1 ); | |||
assert( dst_tex->base.block.height == 1 ); | |||
pipe->screen->surface_unmap(pipe->screen, src); | |||
pipe->screen->surface_unmap(pipe->screen, dst); | |||
} | |||
else { | |||
struct i915_texture *dst_tex = (struct i915_texture *)dst->texture; | |||
struct i915_texture *src_tex = (struct i915_texture *)src->texture; | |||
assert(dst->block.width == 1); | |||
assert(dst->block.height == 1); | |||
i915_copy_blit( i915_context(pipe), | |||
do_flip, | |||
dst->block.size, | |||
(unsigned short) src->stride, src_tex->buffer, src->offset, | |||
(unsigned short) dst->stride, dst_tex->buffer, dst->offset, | |||
(short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height ); | |||
} | |||
i915_copy_blit( i915_context(pipe), | |||
do_flip, | |||
dst_tex->base.block.size, | |||
(unsigned short) src_tex->stride, src_tex->buffer, src->offset, | |||
(unsigned short) dst_tex->stride, dst_tex->buffer, dst->offset, | |||
(short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height ); | |||
} | |||
@@ -94,27 +72,18 @@ i915_surface_fill(struct pipe_context *pipe, | |||
unsigned dstx, unsigned dsty, | |||
unsigned width, unsigned height, unsigned value) | |||
{ | |||
if (0) { | |||
void *dst_map = pipe->screen->surface_map( pipe->screen, | |||
dst, | |||
PIPE_BUFFER_USAGE_CPU_WRITE ); | |||
struct i915_texture *tex = (struct i915_texture *)dst->texture; | |||
pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value); | |||
assert(tex->base.block.width == 1); | |||
assert(tex->base.block.height == 1); | |||
pipe->screen->surface_unmap(pipe->screen, dst); | |||
} | |||
else { | |||
struct i915_texture *tex = (struct i915_texture *)dst->texture; | |||
assert(dst->block.width == 1); | |||
assert(dst->block.height == 1); | |||
i915_fill_blit( i915_context(pipe), | |||
dst->block.size, | |||
(unsigned short) dst->stride, | |||
tex->buffer, dst->offset, | |||
(short) dstx, (short) dsty, | |||
(short) width, (short) height, | |||
value ); | |||
} | |||
i915_fill_blit( i915_context(pipe), | |||
tex->base.block.size, | |||
(unsigned short) tex->stride, | |||
tex->buffer, dst->offset, | |||
(short) dstx, (short) dsty, | |||
(short) width, (short) height, | |||
value ); | |||
} | |||
@@ -686,10 +686,6 @@ i915_get_tex_surface(struct pipe_screen *screen, | |||
ps->format = pt->format; | |||
ps->width = pt->width[level]; | |||
ps->height = pt->height[level]; | |||
ps->block = pt->block; | |||
ps->nblocksx = pt->nblocksx[level]; | |||
ps->nblocksy = pt->nblocksy[level]; | |||
ps->stride = tex->stride; | |||
ps->offset = offset; | |||
ps->usage = flags; | |||
ps->status = PIPE_SURFACE_STATUS_DEFINED; |
@@ -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); | |||
} | |||
@@ -134,7 +134,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); | |||
/* |
@@ -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 */ |
@@ -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); |
@@ -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; | |||
} |
@@ -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 ); |
@@ -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 ); | |||
@@ -156,18 +160,29 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, | |||
{ | |||
assert(!tc->texture); | |||
if (tc->surface_map) { | |||
tc->screen->surface_unmap(tc->screen, tc->surface); | |||
tc->surface_map = NULL; | |||
if (tc->transfer) { | |||
struct pipe_screen *screen = tc->transfer->texture->screen; | |||
if (ps == tc->surface) | |||
return; | |||
if (tc->transfer_map) { | |||
tc->screen->transfer_unmap(tc->screen, tc->transfer); | |||
tc->transfer_map = NULL; | |||
} | |||
screen->tex_transfer_release(screen, &tc->transfer); | |||
} | |||
pipe_surface_reference(&tc->surface, ps); | |||
tc->surface = ps; | |||
if (ps) { | |||
struct pipe_screen *screen = ps->texture->screen; | |||
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->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 || | |||
@@ -181,7 +196,7 @@ sp_tile_cache_set_surface(struct softpipe_tile_cache *tc, | |||
/** | |||
* 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 +206,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; | |||
} | |||
} | |||
@@ -229,15 +241,20 @@ sp_tile_cache_set_texture(struct pipe_context *pipe, | |||
{ | |||
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->transfer) { | |||
struct pipe_screen *screen = tc->transfer->texture->screen; | |||
if (tc->tex_trans_map) { | |||
tc->screen->transfer_unmap(tc->screen, tc->tex_trans); | |||
tc->tex_trans_map = NULL; | |||
} | |||
screen->tex_transfer_release(screen, &tc->tex_trans); | |||
} | |||
pipe_surface_reference(&tc->tex_surf, NULL); | |||
/* mark as entries as invalid/empty */ | |||
/* XXX we should try to avoid this when the teximage hasn't changed */ | |||
@@ -328,20 +345,20 @@ 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 *pt = tc->transfer; | |||
const uint w = tc->transfer->width; | |||
const uint h = tc->transfer->height; | |||
uint x, y; | |||
uint numCleared = 0; | |||
/* clear the scratch tile to the clear value */ | |||
clear_tile(&tc->tile, ps->format, tc->clear_val); | |||
clear_tile(&tc->tile, pt->format, tc->clear_val); | |||
/* push the tile to all positions marked as clear */ | |||
for (y = 0; y < h; y += TILE_SIZE) { | |||
for (x = 0; x < w; x += TILE_SIZE) { | |||
if (is_clear_flag_set(tc->clear_flags, x, y)) { | |||
pipe_put_tile_raw(ps, | |||
pipe_put_tile_raw(pt, | |||
x, y, TILE_SIZE, TILE_SIZE, | |||
tc->tile.data.color32, 0/*STRIDE*/); | |||
@@ -359,28 +376,28 @@ 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 *pt = tc->transfer; | |||
int inuse = 0, pos; | |||
if (ps) { | |||
/* caching a drawing surface */ | |||
if (pt) { | |||
/* caching a drawing transfer */ | |||
for (pos = 0; pos < NUM_ENTRIES; pos++) { | |||
struct softpipe_cached_tile *tile = tc->entries + pos; | |||
if (tile->x >= 0) { | |||
if (tc->depth_stencil) { | |||
pipe_put_tile_raw(ps, | |||
pipe_put_tile_raw(pt, | |||
tile->x, tile->y, TILE_SIZE, TILE_SIZE, | |||
tile->data.depth32, 0/*STRIDE*/); | |||
} | |||
else { | |||
pipe_put_tile_rgba(ps, | |||
pipe_put_tile_rgba(pt, | |||
tile->x, tile->y, TILE_SIZE, TILE_SIZE, | |||
(float *) tile->data.color); | |||
} | |||
@@ -415,7 +432,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 *pt = tc->transfer; | |||
/* tile pos in framebuffer: */ | |||
const int tile_x = x & ~(TILE_SIZE - 1); | |||
@@ -431,12 +448,12 @@ sp_get_cached_tile(struct softpipe_context *softpipe, | |||
if (tile->x != -1) { | |||
/* put dirty tile back in framebuffer */ | |||
if (tc->depth_stencil) { | |||
pipe_put_tile_raw(ps, | |||
pipe_put_tile_raw(pt, | |||
tile->x, tile->y, TILE_SIZE, TILE_SIZE, | |||
tile->data.depth32, 0/*STRIDE*/); | |||
} | |||
else { | |||
pipe_put_tile_rgba(ps, | |||
pipe_put_tile_rgba(pt, | |||
tile->x, tile->y, TILE_SIZE, TILE_SIZE, | |||
(float *) tile->data.color); | |||
} | |||
@@ -448,22 +465,22 @@ sp_get_cached_tile(struct softpipe_context *softpipe, | |||
if (is_clear_flag_set(tc->clear_flags, x, y)) { | |||
/* don't get tile from framebuffer, just clear it */ | |||
if (tc->depth_stencil) { | |||
clear_tile(tile, ps->format, tc->clear_val); | |||
clear_tile(tile, pt->format, tc->clear_val); | |||
} | |||
else { | |||
clear_tile_rgba(tile, ps->format, tc->clear_color); | |||
clear_tile_rgba(tile, pt->format, tc->clear_color); | |||
} | |||
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, | |||
pipe_get_tile_raw(pt, | |||
tile->x, tile->y, TILE_SIZE, TILE_SIZE, | |||
tile->data.depth32, 0/*STRIDE*/); | |||
} | |||
else { | |||
pipe_get_tile_rgba(ps, | |||
pipe_get_tile_rgba(pt, | |||
tile->x, tile->y, TILE_SIZE, TILE_SIZE, | |||
(float *) tile->data.color); | |||
} | |||
@@ -531,28 +548,33 @@ sp_get_cached_tile_tex(struct softpipe_context *sp, | |||
printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos, | |||
x/TILE_SIZE, y/TILE_SIZE, z, face, level); | |||
#endif | |||
/* 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->transfer) { | |||
if (tc->tex_trans_map) | |||
tc->screen->transfer_unmap(tc->screen, tc->tex_trans); | |||
if (tc->tex_surf_map) | |||
tc->screen->surface_unmap(tc->screen, tc->tex_surf); | |||
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; | |||
@@ -579,7 +601,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; |
@@ -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, |
@@ -193,6 +193,16 @@ enum pipe_texture_target { | |||
#define PIPE_SURFACE_STATUS_CLEAR 2 | |||
/** | |||
* Transfer object usage flags | |||
*/ | |||
enum pipe_transfer_usage { | |||
PIPE_TRANSFER_READ, | |||
PIPE_TRANSFER_WRITE, | |||
PIPE_TRANSFER_READ_WRITE //< Read/modify/write | |||
}; | |||
/** | |||
* Buffer usage flags | |||
*/ |
@@ -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. |
@@ -55,6 +55,7 @@ struct pipe_winsys; | |||
struct pipe_buffer; | |||
/** | |||
* Gallium screen/adapter context. Basically everything | |||
* hardware-specific that doesn't actually require a rendering | |||
@@ -128,12 +129,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 ); | |||
/** |
@@ -280,10 +280,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; | |||
@@ -296,6 +292,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. | |||
*/ |
@@ -66,7 +66,7 @@ struct vlR16SnormBufferedMC | |||
struct vlVertex2f zero_block[3]; | |||
unsigned int num_macroblocks; | |||
struct vlMpeg2MacroBlock *macroblocks; | |||
struct pipe_surface *tex_surface[3]; | |||
struct pipe_transfer *tex_transfer[3]; | |||
short *texels[3]; | |||
struct pipe_context *pipe; | |||
@@ -187,7 +187,7 @@ static inline int vlGrabBlocks | |||
assert(mc); | |||
assert(blocks); | |||
tex_pitch = mc->tex_surface[0]->stride / mc->tex_surface[0]->block.size; | |||
tex_pitch = mc->tex_transfer[0]->stride / mc->tex_transfer[0]->block.size; | |||
texels = mc->texels[0] + mbpy * tex_pitch + mbpx; | |||
for (y = 0; y < 2; ++y) | |||
@@ -235,7 +235,7 @@ static inline int vlGrabBlocks | |||
for (tb = 0; tb < 2; ++tb) | |||
{ | |||
tex_pitch = mc->tex_surface[tb + 1]->stride / mc->tex_surface[tb + 1]->block.size; | |||
tex_pitch = mc->tex_transfer[tb + 1]->stride / mc->tex_transfer[tb + 1]->block.size; | |||
texels = mc->texels[tb + 1] + mbpy * tex_pitch + mbpx; | |||
if ((coded_block_pattern >> (1 - tb)) & 1) | |||
@@ -635,8 +635,8 @@ static int vlFlush | |||
for (i = 0; i < 3; ++i) | |||
{ | |||
pipe_surface_unmap(mc->tex_surface[i]); | |||
pipe_surface_reference(&mc->tex_surface[i], NULL); | |||
pipe->screen->transfer_unmap(pipe->screen, mc->tex_transfer[i]); | |||
pipe->screen->tex_transfer_release(pipe->screen, &mc->tex_transfer[i]); | |||
} | |||
mc->render_target.cbufs[0] = pipe->screen->get_tex_surface | |||
@@ -809,14 +809,16 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered | |||
for (i = 0; i < 3; ++i) | |||
{ | |||
mc->tex_surface[i] = mc->pipe->screen->get_tex_surface | |||
mc->tex_transfer[i] = mc->pipe->screen->get_tex_transfer | |||
( | |||
mc->pipe->screen, | |||
mc->textures.all[i], | |||
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD | |||
0, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, | |||
surface->texture->width[0], | |||
surface->texture->height[0] | |||
); | |||
mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD); | |||
mc->texels[i] = mc->pipe->screen->transfer_map(mc->pipe->screen, mc->tex_transfer[i]); | |||
} | |||
} | |||
@@ -36,6 +36,7 @@ | |||
#include "pipe/p_state.h" | |||
#include "util/u_debug.h" | |||
#include "util/u_memory.h" | |||
#include "softpipe/sp_texture.h" | |||
struct brw_aubfile { | |||
@@ -322,10 +323,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 +335,9 @@ 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 = softpipe_texture(surface->texture)->stride[surface->level] / | |||
surface->texture->block.size; | |||
db.xsize = surface->width; | |||
db.ysize = surface->height; | |||
db.addr = gtt_offset; |
@@ -170,6 +170,8 @@ alloc_shm_ximage(struct xm_buffer *b, struct xmesa_buffer *xmb, | |||
(void) XSetErrorHandler(old_handler); | |||
return; | |||
} | |||
b->shm = 1; | |||
} | |||
@@ -230,8 +232,8 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b, | |||
struct pipe_surface *surf) | |||
{ | |||
XImage *ximage; | |||
struct xm_buffer *xm_buf = xm_buffer( | |||
softpipe_texture(surf->texture)->buffer); | |||
struct softpipe_texture *spt = softpipe_texture(surf->texture); | |||
struct xm_buffer *xm_buf = xm_buffer(spt->buffer); | |||
static boolean no_swap = 0; | |||
static boolean firsttime = 1; | |||
@@ -244,9 +246,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, spt->stride[surf->level] / | |||
surf->texture->block.size, surf->height); | |||
} | |||
ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage; | |||
@@ -264,7 +267,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 = spt->stride[surf->level]; | |||
XPutImage(b->xm_visual->display, b->drawable, b->gc, | |||
ximage, 0, 0, 0, 0, surf->width, surf->height); |
@@ -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); | |||
} | |||
@@ -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 *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); | |||
accBuf = (GLfloat *) _mesa_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); | |||
_mesa_free(colorBuf); | |||
_mesa_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 *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); | |||
pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, buf); | |||
pipe_get_tile_rgba(color_trans, 0, 0, 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, 0, 0, width, height, buf); | |||
_mesa_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 *) _mesa_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, 0, 0, width, height, abuf); | |||
if (!colormask[0] || !colormask[1] || !colormask[2] || !colormask[3]) { | |||
cbuf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); | |||
pipe_get_tile_rgba(color_surf, xpos, ypos, width, height, cbuf); | |||
pipe_get_tile_rgba(color_trans, 0, 0, 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, 0, 0, width, height, abuf); | |||
_mesa_free(abuf); | |||
if (cbuf) | |||
_mesa_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); | |||
} | |||
@@ -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); |
@@ -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,25 +774,25 @@ 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); | |||
*/ | |||
} | |||
else { | |||
if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { | |||
spanY = ctx->DrawBuffer->Height - spanY - 1; | |||
spanY = 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; | |||
y = 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, | |||
_mesa_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 *) _mesa_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); | |||
_mesa_free(buf); | |||
} | |||
else { | |||
/* GL_DEPTH */ | |||
GLuint *buf = (GLuint *) _mesa_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, 0, 0, width, height, buf); | |||
pipe_put_tile_z(ptTex, 0, 0, width, height, buf); | |||
_mesa_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], |
@@ -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; |
@@ -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 - height; | |||
} | |||
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 - 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; | |||
} | |||
if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { | |||
y = strb->Base.Height - y - height; | |||
} | |||
/* 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 = strb->Base.Height - 1 - y; | |||
y = height - 1; | |||
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); | |||
} |
@@ -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) { | |||
@@ -808,7 +817,7 @@ st_TexSubimage(GLcontext * ctx, | |||
if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat, | |||
texImage->TexFormat, | |||
texImage->Data, | |||
xoffset, yoffset, 0, | |||
0, 0, 0, | |||
dstRowStride, | |||
texImage->ImageOffsets, | |||
width, height, 1, | |||
@@ -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 - srcY - height; | |||
} | |||
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; | |||
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); | |||
} | |||
@@ -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); | |||
} | |||
} | |||
@@ -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; | |||
} |
@@ -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, |