From: Marek Olšák Date: Sun, 30 Jun 2013 12:34:23 +0000 (+0200) Subject: r600g: fix texture offset computation for mapped MSAA depth buffers X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ae87aae0c4bcc448be3c965319b88f50b2d6fe36;p=mesa.git r600g: fix texture offset computation for mapped MSAA depth buffers It was wrong, because the offset shouldn't be applied to MSAA depth buffers. This small cleanup should prevent such issues in the future. This fixes a lockup in "piglit/fbo-depthstencil default_fb -samples=n". Reviewed-by: Alex Deucher --- diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 8485cce732c..64a90c3b3e9 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -787,8 +787,6 @@ void r600_init_surface_functions(struct r600_context *r600); uint32_t r600_translate_texformat(struct pipe_screen *screen, enum pipe_format format, const unsigned char *swizzle_view, uint32_t *word4_p, uint32_t *yuv_format_p); -unsigned r600_texture_get_offset(struct r600_texture *rtex, - unsigned level, unsigned layer); struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe, struct pipe_resource *texture, const struct pipe_surface *templ, diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 60d8c3610d6..c2feb521be3 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -116,11 +116,15 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600 } } -unsigned r600_texture_get_offset(struct r600_texture *rtex, - unsigned level, unsigned layer) +static unsigned r600_texture_get_offset(struct r600_texture *rtex, unsigned level, + const struct pipe_box *box) { + enum pipe_format format = rtex->resource.b.b.format; + return rtex->surface.level[level].offset + - layer * rtex->surface.level[level].slice_size; + box->z * rtex->surface.level[level].slice_size + + box->y / util_format_get_blockheight(format) * rtex->surface.level[level].pitch_bytes + + box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } static int r600_init_surface(struct r600_screen *rscreen, @@ -805,7 +809,6 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, struct r600_texture *rtex = (struct r600_texture*)texture; struct r600_transfer *trans; boolean use_staging_texture = FALSE; - enum pipe_format format = texture->format; struct r600_resource *buf; unsigned offset = 0; char *map; @@ -849,8 +852,6 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, trans->transfer.box = *box; if (rtex->is_depth) { - /* XXX: only readback the rectangle which is being mapped? */ - /* XXX: when discard is true, no need to read back from depth texture */ struct r600_texture *staging_depth; if (rtex->resource.b.b.nr_samples > 1) { @@ -861,6 +862,8 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, * * First downsample the depth buffer to a temporary texture, * then decompress the temporary one to staging. + * + * Only the region being mapped is transfered. */ struct pipe_resource *temp; struct pipe_resource resource; @@ -880,9 +883,10 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, 0, 0, 0, box->depth, 0, 0); pipe_resource_reference((struct pipe_resource**)&temp, NULL); - trans->offset = 0; } else { + /* XXX: only readback the rectangle which is being mapped? */ + /* XXX: when discard is true, no need to read back from depth texture */ if (!r600_init_flushed_depth_texture(ctx, texture, &staging_depth)) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); FREE(trans); @@ -894,7 +898,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, box->z, box->z + box->depth - 1, 0, 0); - trans->offset = r600_texture_get_offset(staging_depth, level, box->z); + offset = r600_texture_get_offset(staging_depth, level, box); } trans->transfer.stride = staging_depth->surface.level[level].pitch_bytes; @@ -926,9 +930,10 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, rctx->rings.gfx.flush(rctx, 0); } } else { + /* the resource is mapped directly */ trans->transfer.stride = rtex->surface.level[level].pitch_bytes; trans->transfer.layer_stride = rtex->surface.level[level].slice_size; - trans->offset = r600_texture_get_offset(rtex, level, box->z); + offset = r600_texture_get_offset(rtex, level, box); } if (trans->staging) { @@ -937,11 +942,6 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx, buf = &rtex->resource; } - if (rtex->is_depth || !trans->staging) - offset = trans->offset + - box->y / util_format_get_blockheight(format) * trans->transfer.stride + - box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); - if (!(map = r600_buffer_mmap_sync_with_rings(rctx, buf, usage))) { pipe_resource_reference((struct pipe_resource**)&trans->staging, NULL); FREE(trans);