i965: Make intel_emit_linear_blit handle Gen8+ alignment restrictions.
authorKenneth Graunke <kenneth@whitecape.org>
Wed, 15 Apr 2015 10:04:33 +0000 (03:04 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 23 Apr 2015 21:05:41 +0000 (14:05 -0700)
The BLT engine on Gen8+ requires linear surfaces to be cacheline
aligned.  This restriction was added as part of converting the BLT to
use 48-bit addressing.

intel_emit_linear_blit needs to handle blits that are not cacheline
aligned, as we use it for arbitrary glBufferSubData calls and subrange
mappings.

Since intel_emit_linear_blit uses 1 byte per pixel, we can use the src/dst
pixel X offset field to represent the unaligned portion, and subtract
that from the address so it's cacheline aligned.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88521
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
Cc: mesa-stable@lists.freedesktop.org
src/mesa/drivers/dri/i965/intel_blit.c

index 4993f60..98d414c 100644 (file)
@@ -524,6 +524,7 @@ intel_emit_linear_blit(struct brw_context *brw,
 {
    struct gl_context *ctx = &brw->ctx;
    GLuint pitch, height;
+   int16_t src_x, dst_x;
    bool ok;
 
    /* The pitch given to the GPU must be DWORD aligned, and
@@ -532,11 +533,13 @@ intel_emit_linear_blit(struct brw_context *brw,
     */
    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, I915_TILING_NONE,
-                         pitch, dst_bo, dst_offset, I915_TILING_NONE,
-                         0, 0, /* src x/y */
-                         0, 0, /* dst x/y */
+                         pitch, src_bo, src_offset - src_x, I915_TILING_NONE,
+                         pitch, dst_bo, dst_offset - dst_x, I915_TILING_NONE,
+                         src_x, 0, /* src x/y */
+                         dst_x, 0, /* dst x/y */
                          pitch, height, /* w, h */
                          GL_COPY);
    if (!ok)
@@ -544,15 +547,18 @@ intel_emit_linear_blit(struct brw_context *brw,
 
    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) {
       ok = intelEmitCopyBlit(brw, 1,
-                            pitch, src_bo, src_offset, I915_TILING_NONE,
-                            pitch, dst_bo, dst_offset, I915_TILING_NONE,
-                            0, 0, /* src x/y */
-                            0, 0, /* dst x/y */
+                            pitch, src_bo, src_offset - src_x, I915_TILING_NONE,
+                            pitch, dst_bo, dst_offset - dst_x, I915_TILING_NONE,
+                            src_x, 0, /* src x/y */
+                            dst_x, 0, /* dst x/y */
                             size, 1, /* w, h */
                             GL_COPY);
       if (!ok)