diff options
author | Marek Olšák <[email protected]> | 2014-03-08 15:15:41 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2014-03-11 19:18:02 +0100 |
commit | 4ca3486b195653f875003d335921fd4e7d7c2c4a (patch) | |
tree | 71d066d3bf42403a51176692966f0b552bb913dc /src/gallium/drivers/r600 | |
parent | de5094d102da0ffd8adef606b89e7a40d5843141 (diff) |
r600g,radeonsi: use a fallback in dma_copy instead of failing
v2: - allow byte-aligned DMA buffer copies on Evergreen
- fix piglit/texsubimage regression
- use the fallback for 3D copies (depth > 1) as well
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 40 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 44 |
2 files changed, 49 insertions, 35 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 18c2ee59b87..05cc3ef4cc2 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -3325,13 +3325,13 @@ static void evergreen_dma_copy_tile(struct r600_context *rctx, } } -static boolean evergreen_dma_blit(struct pipe_context *ctx, - struct pipe_resource *dst, - unsigned dst_level, - unsigned dst_x, unsigned dst_y, unsigned dst_z, - struct pipe_resource *src, - unsigned src_level, - const struct pipe_box *src_box) +static void evergreen_dma_blit(struct pipe_context *ctx, + struct pipe_resource *dst, + unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + unsigned src_level, + const struct pipe_box *src_box) { struct r600_context *rctx = (struct r600_context *)ctx; struct r600_texture *rsrc = (struct r600_texture*)src; @@ -3339,22 +3339,22 @@ static boolean evergreen_dma_blit(struct pipe_context *ctx, unsigned dst_pitch, src_pitch, bpp, dst_mode, src_mode, copy_height; unsigned src_w, dst_w; unsigned src_x, src_y; + unsigned dst_x = dstx, dst_y = dsty, dst_z = dstz; if (rctx->b.rings.dma.cs == NULL) { - return FALSE; + goto fallback; } if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { evergreen_dma_copy(rctx, dst, src, dst_x, src_box->x, src_box->width); - return TRUE; + return; } - if (src->format != dst->format) { - return FALSE; - } - if (rdst->dirty_level_mask != 0) { - return FALSE; + if (src->format != dst->format || src_box->depth > 1 || + rdst->dirty_level_mask != 0) { + goto fallback; } + if (rsrc->dirty_level_mask) { ctx->flush_resource(ctx, src); } @@ -3379,13 +3379,13 @@ static boolean evergreen_dma_blit(struct pipe_context *ctx, if (src_pitch != dst_pitch || src_box->x || dst_x || src_w != dst_w) { /* FIXME evergreen can do partial blit */ - return FALSE; + goto fallback; } /* the x test here are currently useless (because we don't support partial blit) * but keep them around so we don't forget about those */ if ((src_pitch & 0x7) || (src_box->x & 0x7) || (dst_x & 0x7) || (src_box->y & 0x7) || (dst_y & 0x7)) { - return FALSE; + goto fallback; } /* 128 bpp surfaces require non_disp_tiling for both @@ -3396,7 +3396,7 @@ static boolean evergreen_dma_blit(struct pipe_context *ctx, if ((rctx->b.chip_class == CAYMAN) && (src_mode != dst_mode) && (util_format_get_blocksize(src->format) >= 16)) { - return FALSE; + goto fallback; } if (src_mode == dst_mode) { @@ -3419,7 +3419,11 @@ static boolean evergreen_dma_blit(struct pipe_context *ctx, src, src_level, src_x, src_y, src_box->z, copy_height, dst_pitch, bpp); } - return TRUE; + return; + +fallback: + ctx->resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box); } void evergreen_init_state_functions(struct r600_context *rctx) diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index e6254c69a2c..39e38f4dd0d 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -2882,13 +2882,13 @@ static boolean r600_dma_copy_tile(struct r600_context *rctx, return TRUE; } -static boolean r600_dma_blit(struct pipe_context *ctx, - struct pipe_resource *dst, - unsigned dst_level, - unsigned dst_x, unsigned dst_y, unsigned dst_z, - struct pipe_resource *src, - unsigned src_level, - const struct pipe_box *src_box) +static void r600_dma_blit(struct pipe_context *ctx, + struct pipe_resource *dst, + unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + unsigned src_level, + const struct pipe_box *src_box) { struct r600_context *rctx = (struct r600_context *)ctx; struct r600_texture *rsrc = (struct r600_texture*)src; @@ -2896,18 +2896,22 @@ static boolean r600_dma_blit(struct pipe_context *ctx, unsigned dst_pitch, src_pitch, bpp, dst_mode, src_mode, copy_height; unsigned src_w, dst_w; unsigned src_x, src_y; + unsigned dst_x = dstx, dst_y = dsty, dst_z = dstz; if (rctx->b.rings.dma.cs == NULL) { - return FALSE; + goto fallback; } if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { + if (dst_x % 4 || src_box->x % 4 || src_box->width % 4) + goto fallback; + r600_dma_copy(rctx, dst, src, dst_x, src_box->x, src_box->width); - return TRUE; + return; } - if (src->format != dst->format) { - return FALSE; + if (src->format != dst->format || src_box->depth > 1) { + goto fallback; } src_x = util_format_get_nblocksx(src->format, src_box->x); @@ -2930,11 +2934,11 @@ static boolean r600_dma_blit(struct pipe_context *ctx, if (src_pitch != dst_pitch || src_box->x || dst_x || src_w != dst_w) { /* strick requirement on r6xx/r7xx */ - return FALSE; + goto fallback; } /* lot of constraint on alignment this should capture them all */ if ((src_pitch & 0x7) || (src_box->y & 0x7) || (dst_y & 0x7)) { - return FALSE; + goto fallback; } if (src_mode == dst_mode) { @@ -2954,15 +2958,21 @@ static boolean r600_dma_blit(struct pipe_context *ctx, size = src_box->height * src_pitch; /* must be dw aligned */ if ((dst_offset & 0x3) || (src_offset & 0x3) || (size & 0x3)) { - return FALSE; + goto fallback; } r600_dma_copy(rctx, dst, src, dst_offset, src_offset, size); } else { - return r600_dma_copy_tile(rctx, dst, dst_level, dst_x, dst_y, dst_z, + if (!r600_dma_copy_tile(rctx, dst, dst_level, dst_x, dst_y, dst_z, src, src_level, src_x, src_y, src_box->z, - copy_height, dst_pitch, bpp); + copy_height, dst_pitch, bpp)) { + goto fallback; + } } - return TRUE; + return; + +fallback: + ctx->resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box); } void r600_init_state_functions(struct r600_context *rctx) |