summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c28
-rw-r--r--src/mesa/state_tracker/st_texture.c35
-rw-r--r--src/mesa/state_tracker/st_texture.h11
3 files changed, 53 insertions, 21 deletions
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 304dc91677e..97bba8b7da5 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -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);
}
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index cfa0605ca2b..f664ef5f140 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -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;
}
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index f2afaf139f1..affb5681264 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -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