diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_blit.c | 72 |
1 files changed, 34 insertions, 38 deletions
diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c index 6d92580e725..5a1da128888 100644 --- a/src/mesa/drivers/dri/i965/intel_blit.c +++ b/src/mesa/drivers/dri/i965/intel_blit.c @@ -796,47 +796,43 @@ intel_emit_linear_blit(struct brw_context *brw, int16_t src_x, dst_x; bool ok; - /* The pitch given to the GPU must be DWORD aligned, and - * we want width to match pitch. Max width is (1 << 15 - 1), - * rounding that down to the nearest DWORD is 1 << 15 - 4 - */ - pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 1), 4); - height = (pitch == 0) ? 1 : size / pitch; - src_x = src_offset % 64; - dst_x = dst_offset % 64; - ok = intelEmitCopyBlit(brw, 1, - pitch, src_bo, src_offset - src_x, I915_TILING_NONE, - INTEL_MIPTREE_TRMODE_NONE, - pitch, dst_bo, dst_offset - dst_x, I915_TILING_NONE, - INTEL_MIPTREE_TRMODE_NONE, - src_x, 0, /* src x/y */ - dst_x, 0, /* dst x/y */ - pitch, height, /* w, h */ - GL_COPY); - if (!ok) - _mesa_problem(ctx, "Failed to linear blit %dx%d\n", pitch, height); - - src_offset += pitch * height; - dst_offset += pitch * height; - src_x = src_offset % 64; - dst_x = dst_offset % 64; - size -= pitch * height; - assert (size < (1 << 15)); - pitch = ALIGN(size, 4); - - if (size != 0) { + do { + /* The pitch given to the GPU must be DWORD aligned, and + * we want width to match pitch. Max width is (1 << 15 - 1), + * rounding that down to the nearest DWORD is 1 << 15 - 4 + */ + pitch = ROUND_DOWN_TO(MIN2(size, (1 << 15) - 64), 4); + height = (size < pitch || pitch == 0) ? 1 : size / pitch; + + src_x = src_offset % 64; + dst_x = dst_offset % 64; + pitch = ALIGN(MIN2(size, (1 << 15) - 64), 4); + assert(src_x + pitch < 1 << 15); + assert(dst_x + pitch < 1 << 15); + ok = intelEmitCopyBlit(brw, 1, - pitch, src_bo, src_offset - src_x, I915_TILING_NONE, + pitch, src_bo, src_offset - src_x, I915_TILING_NONE, INTEL_MIPTREE_TRMODE_NONE, - pitch, dst_bo, dst_offset - dst_x, I915_TILING_NONE, + pitch, dst_bo, dst_offset - dst_x, I915_TILING_NONE, INTEL_MIPTREE_TRMODE_NONE, - src_x, 0, /* src x/y */ - dst_x, 0, /* dst x/y */ - size, 1, /* w, h */ - GL_COPY); - if (!ok) - _mesa_problem(ctx, "Failed to linear blit %dx%d\n", size, 1); - } + src_x, 0, /* src x/y */ + dst_x, 0, /* dst x/y */ + MIN2(size, pitch), height, /* w, h */ + GL_COPY); + if (!ok) { + _mesa_problem(ctx, "Failed to linear blit %dx%d\n", + MIN2(size, pitch), height); + return; + } + + pitch *= height; + if (size <= pitch) + return; + + src_offset += pitch; + dst_offset += pitch; + size -= pitch; + } while (1); } /** |