mesa: _mesa_CopyBufferSubData() function, and driver fall-back
authorBrian Paul <brianp@vmware.com>
Wed, 3 Jun 2009 02:29:57 +0000 (20:29 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 3 Jun 2009 03:35:11 +0000 (21:35 -0600)
src/mesa/main/bufferobj.c
src/mesa/main/bufferobj.h

index 90daa2e5b8972b77ea170f7a5c0176af3d578e36..88b51fe60ffb0bfe53972b23a36be9a471549f33 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.5
+ * Version:  7.6
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 1999-2009  VMware, Inc.  All Rights Reserved.
+ * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -73,6 +73,16 @@ get_buffer(GLcontext *ctx, GLenum target)
       case GL_PIXEL_UNPACK_BUFFER_EXT:
          bufObj = ctx->Unpack.BufferObj;
          break;
+      case GL_COPY_READ_BUFFER:
+         if (ctx->Extensions.ARB_copy_buffer) {
+            bufObj = ctx->CopyReadBuffer;
+         }
+         break;
+      case GL_COPY_WRITE_BUFFER:
+         if (ctx->Extensions.ARB_copy_buffer) {
+            bufObj = ctx->CopyWriteBuffer;
+         }
+         break;
       default:
          /* error must be recorded by caller */
          return NULL;
@@ -418,6 +428,37 @@ _mesa_buffer_unmap( GLcontext *ctx, GLenum target,
 }
 
 
+/**
+ * Default fallback for \c dd_function_table::CopyBufferSubData().
+ * Called via glCopyBuffserSubData().
+ */
+void
+_mesa_copy_buffer_subdata(GLcontext *ctx,
+                          struct gl_buffer_object *src,
+                          struct gl_buffer_object *dst,
+                          GLintptr readOffset, GLintptr writeOffset,
+                          GLsizeiptr size)
+{
+   GLubyte *srcPtr, *dstPtr;
+
+   /* buffer should not already be mapped */
+   assert(!src->Pointer);
+   assert(!dst->Pointer);
+
+   srcPtr = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_COPY_READ_BUFFER,
+                                              GL_READ_ONLY, src);
+   dstPtr = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_COPY_WRITE_BUFFER,
+                                              GL_WRITE_ONLY, dst);
+
+   if (srcPtr && dstPtr)
+      _mesa_memcpy(dstPtr + writeOffset, srcPtr + readOffset, size);
+
+   ctx->Driver.UnmapBuffer(ctx, GL_COPY_READ_BUFFER, src);
+   ctx->Driver.UnmapBuffer(ctx, GL_COPY_WRITE_BUFFER, dst);
+}
+
+
+
 /**
  * Initialize the state associated with buffer objects
  */
@@ -426,6 +467,9 @@ _mesa_init_buffer_objects( GLcontext *ctx )
 {
    ctx->Array.ArrayBufferObj = ctx->Shared->NullBufferObj;
    ctx->Array.ElementArrayBufferObj = ctx->Shared->NullBufferObj;
+
+   ctx->CopyReadBuffer = ctx->Shared->NullBufferObj;
+   ctx->CopyWriteBuffer = ctx->Shared->NullBufferObj;
 }
 
 
@@ -452,8 +496,22 @@ bind_buffer_object(GLcontext *ctx, GLenum target, GLuint buffer)
    case GL_PIXEL_UNPACK_BUFFER_EXT:
       bindTarget = &ctx->Unpack.BufferObj;
       break;
+   case GL_COPY_READ_BUFFER:
+      if (ctx->Extensions.ARB_copy_buffer) {
+         bindTarget = &ctx->CopyReadBuffer;
+      }
+      break;
+   case GL_COPY_WRITE_BUFFER:
+      if (ctx->Extensions.ARB_copy_buffer) {
+         bindTarget = &ctx->CopyWriteBuffer;
+      }
+      break;
    default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target)");
+      ; /* no-op / we'll hit the follow error test next */
+   }
+
+   if (!bindTarget) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target 0x%x)");
       return;
    }
 
@@ -1140,3 +1198,84 @@ _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
 
    *params = bufObj->Pointer;
 }
+
+
+void GLAPIENTRY
+_mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
+                        GLintptr readOffset, GLintptr writeOffset,
+                        GLsizeiptr size)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_buffer_object *src, *dst;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   src = get_buffer(ctx, readTarget);
+   if (!src || src->Name == 0) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glCopyBuffserSubData(readTarget = 0x%x)", readTarget);
+      return;
+   }
+
+   dst = get_buffer(ctx, writeTarget);
+   if (!dst || dst->Name == 0) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glCopyBuffserSubData(writeTarget = 0x%x)", writeTarget);
+      return;
+   }
+
+   if (src->Pointer) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glCopyBuffserSubData(readBuffer is mapped)");
+      return;
+   }
+
+   if (dst->Pointer) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glCopyBuffserSubData(writeBuffer is mapped)");
+      return;
+   }
+
+   if (readOffset < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyBuffserSubData(readOffset = %d)", readOffset);
+      return;
+   }
+
+   if (writeOffset < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyBuffserSubData(writeOffset = %d)", writeOffset);
+      return;
+   }
+
+   if (readOffset + size > src->Size) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyBuffserSubData(readOffset + size = %d)",
+                  readOffset, size);
+      return;
+   }
+
+   if (writeOffset + size > src->Size) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyBuffserSubData(writeOffset + size = %d)",
+                  writeOffset, size);
+      return;
+   }
+
+   if (src == dst) {
+      if (readOffset + size <= writeOffset) {
+         /* OK */
+      }
+      else if (writeOffset + size <= readOffset) {
+         /* OK */
+      }
+      else {
+         /* overlapping src/dst is illegal */
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyBuffserSubData(overlapping src/dst)");
+         return;
+      }
+   }
+
+   ctx->Driver.CopyBufferSubData(ctx, src, dst, readOffset, writeOffset, size);
+}
+
index 3c08f0083cf64fcb08fa96a57e718da958fe1c6a..79c027aa4d48321d7fb768967451866c54ae5618 100644 (file)
@@ -1,8 +1,9 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.2
+ * Version:  7.6
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -82,6 +83,13 @@ extern GLboolean
 _mesa_buffer_unmap( GLcontext *ctx, GLenum target,
                     struct gl_buffer_object * bufObj );
 
+extern void
+_mesa_copy_buffer_subdata(GLcontext *ctx,
+                          struct gl_buffer_object *src,
+                          struct gl_buffer_object *dst,
+                          GLintptr readOffset, GLintptr writeOffset,
+                          GLsizeiptr size);
+
 extern GLboolean
 _mesa_validate_pbo_access(GLuint dimensions,
                           const struct gl_pixelstore_attrib *pack,
@@ -154,4 +162,9 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params);
 extern void GLAPIENTRY
 _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params);
 
+extern void GLAPIENTRY
+_mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
+                        GLintptr readOffset, GLintptr writeOffset,
+                        GLsizeiptr size);
+
 #endif