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
_mesa_align_free(stImage->TexData);
stImage->TexData = NULL;
+
+ free(stImage->transfer);
+ stImage->transfer = NULL;
+ stImage->num_transfers = 0;
}
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)
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;
{
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);
}
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__);
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) {
}
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);
}
}
}
}
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 */
free(tempSrc);
}
- st_texture_image_unmap(st, stImage);
+ st_texture_image_unmap(st, stImage, slice);
pipe->transfer_unmap(pipe, src_trans);
}
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__);
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;
}
*/
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;
};
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