summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2012-01-25 16:29:28 -0800
committerEric Anholt <[email protected]>2012-01-27 11:44:31 -0800
commit531e44415b078db105d0439ea90b3ea3bc3b0f7b (patch)
treedb675a93a09b45a9275274e1095a7b62bae50196
parent42e9936ce6bcac9f863b2f85978489e4f804e927 (diff)
mesa: Fix handling of glCopyBufferSubData() for src == dst.
Fixes piglit ARB_copy_buffer-overlap, on swrast, which previously assertion failed. Reviewed-by: Brian Paul <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r--src/mesa/main/bufferobj.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 5b6db78d821..e4f964f1826 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -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);
}