mesa: Fix handling of glCopyBufferSubData() for src == dst.
authorEric Anholt <eric@anholt.net>
Thu, 26 Jan 2012 00:29:28 +0000 (16:29 -0800)
committerEric Anholt <eric@anholt.net>
Fri, 27 Jan 2012 19:44:31 +0000 (11:44 -0800)
Fixes piglit ARB_copy_buffer-overlap, on swrast, which previously
assertion failed.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/main/bufferobj.c

index 5b6db78d821611dc8aa4b4d6bcd047302584f616..e4f964f1826171db107a996fb5f514cb8f5670fa 100644 (file)
@@ -526,11 +526,23 @@ _mesa_copy_buffer_subdata(struct gl_context *ctx,
    assert(!_mesa_bufferobj_mapped(src));
    assert(!_mesa_bufferobj_mapped(dst));
 
-   srcPtr = ctx->Driver.MapBufferRange(ctx, readOffset, size,
-                                       GL_MAP_READ_BIT, src);
-   dstPtr = ctx->Driver.MapBufferRange(ctx, writeOffset, size,
-                                       (GL_MAP_WRITE_BIT |
-                                        GL_MAP_INVALIDATE_RANGE_BIT), dst);
+   if (src == dst) {
+      srcPtr = dstPtr = ctx->Driver.MapBufferRange(ctx, 0, src->Size,
+                                                  GL_MAP_READ_BIT |
+                                                  GL_MAP_WRITE_BIT, src);
+
+      if (!srcPtr)
+        return;
+
+      srcPtr += readOffset;
+      dstPtr += writeOffset;
+   } else {
+      srcPtr = ctx->Driver.MapBufferRange(ctx, readOffset, size,
+                                         GL_MAP_READ_BIT, src);
+      dstPtr = ctx->Driver.MapBufferRange(ctx, writeOffset, size,
+                                         (GL_MAP_WRITE_BIT |
+                                          GL_MAP_INVALIDATE_RANGE_BIT), dst);
+   }
 
    /* Note: the src and dst regions will never overlap.  Trying to do so
     * would generate GL_INVALID_VALUE earlier.
@@ -539,7 +551,8 @@ _mesa_copy_buffer_subdata(struct gl_context *ctx,
       memcpy(dstPtr, srcPtr, size);
 
    ctx->Driver.UnmapBuffer(ctx, src);
-   ctx->Driver.UnmapBuffer(ctx, dst);
+   if (dst != src)
+      ctx->Driver.UnmapBuffer(ctx, dst);
 }