summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2013-06-30 14:34:23 +0200
committerMarek Olšák <[email protected]>2013-07-08 20:25:18 +0200
commitae87aae0c4bcc448be3c965319b88f50b2d6fe36 (patch)
tree64fb52c76f516d1c32ce18980ffdb782415b98fc
parenta3263cca59b463a9c49bd165226e36fdfec96d8b (diff)
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 <[email protected]>
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h2
-rw-r--r--src/gallium/drivers/r600/r600_texture.c28
2 files changed, 14 insertions, 16 deletions
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);