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:
parent
5206d4bc09
commit
26c41398cc
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue