summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2014-03-08 15:15:41 +0100
committerMarek Olšák <[email protected]>2014-03-11 19:18:02 +0100
commit4ca3486b195653f875003d335921fd4e7d7c2c4a (patch)
tree71d066d3bf42403a51176692966f0b552bb913dc /src/gallium/drivers/r600
parentde5094d102da0ffd8adef606b89e7a40d5843141 (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.c40
-rw-r--r--src/gallium/drivers/r600/r600_state.c44
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)