st/mesa: properly implement MapTextureImage with multiple mapped slices (v2)

This is needed by _mesa_generate_mipmap.

This adds an array of pipe_transfers to st_texture_image. Each transfer is
for mapping a single layer.

v2: allocate the array of transfers on demand
This commit is contained in:
Marek Olšák 2014-03-10 18:43:17 +01:00
parent 5206d4bc09
commit 26c41398cc
3 changed files with 53 additions and 21 deletions

View File

@ -175,6 +175,10 @@ st_FreeTextureImageBuffer(struct gl_context *ctx,
_mesa_align_free(stImage->TexData);
stImage->TexData = NULL;
free(stImage->transfer);
stImage->transfer = NULL;
stImage->num_transfers = 0;
}
@ -190,6 +194,7 @@ st_MapTextureImage(struct gl_context *ctx,
struct st_texture_image *stImage = st_texture_image(texImage);
unsigned pipeMode;
GLubyte *map;
struct pipe_transfer *transfer;
pipeMode = 0x0;
if (mode & GL_MAP_READ_BIT)
@ -199,10 +204,11 @@ st_MapTextureImage(struct gl_context *ctx,
if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
pipeMode |= PIPE_TRANSFER_DISCARD_RANGE;
map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1);
map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1,
&transfer);
if (map) {
*mapOut = map;
*rowStrideOut = stImage->transfer->stride;
*rowStrideOut = transfer->stride;
}
else {
*mapOut = NULL;
@ -219,7 +225,7 @@ st_UnmapTextureImage(struct gl_context *ctx,
{
struct st_context *st = st_context(ctx);
struct st_texture_image *stImage = st_texture_image(texImage);
st_texture_image_unmap(st, stImage);
st_texture_image_unmap(st, stImage, slice);
}
@ -1144,6 +1150,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,
unsigned dst_width = width;
unsigned dst_height = height;
unsigned dst_depth = 1;
struct pipe_transfer *transfer;
if (ST_DEBUG & DEBUG_FALLBACK)
debug_printf("%s: fallback processing\n", __FUNCTION__);
@ -1169,7 +1176,8 @@ fallback_copy_texsubimage(struct gl_context *ctx,
texDest = st_texture_image_map(st, stImage, transfer_usage,
destX, destY, slice,
dst_width, dst_height, dst_depth);
dst_width, dst_height, dst_depth,
&transfer);
if (baseFormat == GL_DEPTH_COMPONENT ||
baseFormat == GL_DEPTH_STENCIL) {
@ -1199,13 +1207,11 @@ fallback_copy_texsubimage(struct gl_context *ctx,
}
if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
pipe_put_tile_z(stImage->transfer,
texDest + row*stImage->transfer->layer_stride,
pipe_put_tile_z(transfer, texDest + row*transfer->layer_stride,
0, 0, width, 1, data);
}
else {
pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1,
data);
pipe_put_tile_z(transfer, texDest, 0, row, width, 1, data);
}
}
}
@ -1231,10 +1237,10 @@ fallback_copy_texsubimage(struct gl_context *ctx,
}
if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
dstRowStride = stImage->transfer->layer_stride;
dstRowStride = transfer->layer_stride;
}
else {
dstRowStride = stImage->transfer->stride;
dstRowStride = transfer->stride;
}
/* get float/RGBA image from framebuffer */
@ -1267,7 +1273,7 @@ fallback_copy_texsubimage(struct gl_context *ctx,
free(tempSrc);
}
st_texture_image_unmap(st, stImage);
st_texture_image_unmap(st, stImage, slice);
pipe->transfer_unmap(pipe, src_trans);
}

View File

@ -241,11 +241,13 @@ GLubyte *
st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
enum pipe_transfer_usage usage,
GLuint x, GLuint y, GLuint z,
GLuint w, GLuint h, GLuint d)
GLuint w, GLuint h, GLuint d,
struct pipe_transfer **transfer)
{
struct st_texture_object *stObj =
st_texture_object(stImage->base.TexObject);
GLuint level;
void *map;
DBG("%s \n", __FUNCTION__);
@ -257,22 +259,41 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
else
level = stImage->base.Level;
return pipe_transfer_map_3d(st->pipe, stImage->pt, level, usage,
x, y, z + stImage->base.Face,
w, h, d, &stImage->transfer);
z += stImage->base.Face;
map = pipe_transfer_map_3d(st->pipe, stImage->pt, level, usage,
x, y, z, w, h, d, transfer);
if (map) {
/* Enlarge the transfer array if it's not large enough. */
if (z >= stImage->num_transfers) {
unsigned new_size = z + 1;
stImage->transfer = realloc(stImage->transfer,
new_size * sizeof(void*));
memset(&stImage->transfer[stImage->num_transfers], 0,
(new_size - stImage->num_transfers) * sizeof(void*));
stImage->num_transfers = new_size;
}
assert(!stImage->transfer[z]);
stImage->transfer[z] = *transfer;
}
return map;
}
void
st_texture_image_unmap(struct st_context *st,
struct st_texture_image *stImage)
struct st_texture_image *stImage, unsigned slice)
{
struct pipe_context *pipe = st->pipe;
struct pipe_transfer **transfer =
&stImage->transfer[slice + stImage->base.Face];
DBG("%s\n", __FUNCTION__);
pipe_transfer_unmap(pipe, stImage->transfer);
stImage->transfer = NULL;
pipe_transfer_unmap(pipe, *transfer);
*transfer = NULL;
}

View File

@ -56,7 +56,11 @@ struct st_texture_image
*/
struct pipe_resource *pt;
struct pipe_transfer *transfer;
/* List of transfers, allocated on demand.
* transfer[layer] is a mapping for that layer.
*/
struct pipe_transfer **transfer;
unsigned num_transfers;
};
@ -195,11 +199,12 @@ extern GLubyte *
st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
enum pipe_transfer_usage usage,
GLuint x, GLuint y, GLuint z,
GLuint w, GLuint h, GLuint d);
GLuint w, GLuint h, GLuint d,
struct pipe_transfer **transfer);
extern void
st_texture_image_unmap(struct st_context *st,
struct st_texture_image *stImage);
struct st_texture_image *stImage, unsigned slice);
/* Return pointers to each 2d slice within an image. Indexed by depth