/**
* Set ptr to bufObj w/ reference counting.
+ * This is normally only called from the _mesa_reference_buffer_object() macro
+ * when there's a real pointer change.
*/
void
-_mesa_reference_buffer_object(struct gl_context *ctx,
- struct gl_buffer_object **ptr,
- struct gl_buffer_object *bufObj)
+_mesa_reference_buffer_object_(struct gl_context *ctx,
+ struct gl_buffer_object **ptr,
+ struct gl_buffer_object *bufObj)
{
- if (*ptr == bufObj)
- return;
-
if (*ptr) {
/* Unreference the old buffer */
GLboolean deleteFlag = GL_FALSE;
* \sa glBufferSubDataARB, dd_function_table::BufferSubData.
*/
static void
-_mesa_buffer_subdata( struct gl_context *ctx, GLenum target, GLintptrARB offset,
+_mesa_buffer_subdata( struct gl_context *ctx, GLintptrARB offset,
GLsizeiptrARB size, const GLvoid * data,
struct gl_buffer_object * bufObj )
{
- (void) ctx; (void) target;
+ (void) ctx;
/* this should have been caught in _mesa_BufferSubData() */
ASSERT(size + offset <= bufObj->Size);
* \sa glBufferGetSubDataARB, dd_function_table::GetBufferSubData.
*/
static void
-_mesa_buffer_get_subdata( struct gl_context *ctx,
- GLenum target, GLintptrARB offset,
+_mesa_buffer_get_subdata( struct gl_context *ctx, GLintptrARB offset,
GLsizeiptrARB size, GLvoid * data,
struct gl_buffer_object * bufObj )
{
- (void) ctx; (void) target;
+ (void) ctx;
if (bufObj->Data && ((GLsizeiptrARB) (size + offset) <= bufObj->Size)) {
memcpy( data, (GLubyte *) bufObj->Data + offset, size );
}
-/**
- * Default callback for \c dd_function_tabel::MapBuffer().
- *
- * The function parameters will have been already tested for errors.
- *
- * \param ctx GL context.
- * \param target Buffer object target on which to operate.
- * \param access Information about how the buffer will be accessed.
- * \param bufObj Object to be mapped.
- * \return A pointer to the object's internal data store that can be accessed
- * by the processor
- *
- * \sa glMapBufferARB, dd_function_table::MapBuffer
- */
-static void *
-_mesa_buffer_map( struct gl_context *ctx, GLenum target, GLenum access,
- struct gl_buffer_object *bufObj )
-{
- (void) ctx;
- (void) target;
- (void) access;
- /* Just return a direct pointer to the data */
- if (_mesa_bufferobj_mapped(bufObj)) {
- /* already mapped! */
- return NULL;
- }
- bufObj->Pointer = bufObj->Data;
- bufObj->Length = bufObj->Size;
- bufObj->Offset = 0;
- return bufObj->Pointer;
-}
-
-
/**
* Default fallback for \c dd_function_table::MapBufferRange().
* Called via glMapBufferRange().
*/
static void *
-_mesa_buffer_map_range( struct gl_context *ctx, GLenum target, GLintptr offset,
+_mesa_buffer_map_range( struct gl_context *ctx, GLintptr offset,
GLsizeiptr length, GLbitfield access,
struct gl_buffer_object *bufObj )
{
(void) ctx;
- (void) target;
assert(!_mesa_bufferobj_mapped(bufObj));
/* Just return a direct pointer to the data */
bufObj->Pointer = bufObj->Data + offset;
* Called via glFlushMappedBufferRange().
*/
static void
-_mesa_buffer_flush_mapped_range( struct gl_context *ctx, GLenum target,
+_mesa_buffer_flush_mapped_range( struct gl_context *ctx,
GLintptr offset, GLsizeiptr length,
struct gl_buffer_object *obj )
{
(void) ctx;
- (void) target;
(void) offset;
(void) length;
(void) obj;
* \sa glUnmapBufferARB, dd_function_table::UnmapBuffer
*/
static GLboolean
-_mesa_buffer_unmap( struct gl_context *ctx, GLenum target,
- struct gl_buffer_object *bufObj )
+_mesa_buffer_unmap( struct gl_context *ctx, struct gl_buffer_object *bufObj )
{
(void) ctx;
- (void) target;
/* XXX we might assert here that bufObj->Pointer is non-null */
bufObj->Pointer = NULL;
bufObj->Length = 0;
assert(!_mesa_bufferobj_mapped(src));
assert(!_mesa_bufferobj_mapped(dst));
- 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);
+ srcPtr = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, src->Size,
+ GL_MAP_READ_BIT, src);
+ dstPtr = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, dst->Size,
+ GL_MAP_WRITE_BIT, dst);
if (srcPtr && dstPtr)
memcpy(dstPtr + writeOffset, srcPtr + readOffset, size);
- ctx->Driver.UnmapBuffer(ctx, GL_COPY_READ_BUFFER, src);
- ctx->Driver.UnmapBuffer(ctx, GL_COPY_WRITE_BUFFER, dst);
+ ctx->Driver.UnmapBuffer(ctx, src);
+ ctx->Driver.UnmapBuffer(ctx, dst);
}
driver->BufferData = _mesa_buffer_data;
driver->BufferSubData = _mesa_buffer_subdata;
driver->GetBufferSubData = _mesa_buffer_get_subdata;
- driver->MapBuffer = _mesa_buffer_map;
driver->UnmapBuffer = _mesa_buffer_unmap;
/* GL_ARB_map_buffer_range */
if (_mesa_bufferobj_mapped(bufObj)) {
/* if mapped, unmap it now */
- ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
+ ctx->Driver.UnmapBuffer(ctx, bufObj);
bufObj->AccessFlags = DEFAULT_ACCESS;
bufObj->Pointer = NULL;
}
if (_mesa_bufferobj_mapped(bufObj)) {
/* Unmap the existing buffer. We'll replace it now. Not an error. */
- ctx->Driver.UnmapBuffer(ctx, target, bufObj);
+ ctx->Driver.UnmapBuffer(ctx, bufObj);
bufObj->AccessFlags = DEFAULT_ACCESS;
ASSERT(bufObj->Pointer == NULL);
}
bufObj->Written = GL_TRUE;
ASSERT(ctx->Driver.BufferSubData);
- ctx->Driver.BufferSubData( ctx, target, offset, size, data, bufObj );
+ ctx->Driver.BufferSubData( ctx, offset, size, data, bufObj );
}
}
ASSERT(ctx->Driver.GetBufferSubData);
- ctx->Driver.GetBufferSubData( ctx, target, offset, size, data, bufObj );
+ ctx->Driver.GetBufferSubData( ctx, offset, size, data, bufObj );
}
return NULL;
}
- ASSERT(ctx->Driver.MapBuffer);
- map = ctx->Driver.MapBuffer( ctx, target, access, bufObj );
+ if (!bufObj->Size) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glMapBuffer(buffer size = 0)");
+ return NULL;
+ }
+
+ ASSERT(ctx->Driver.MapBufferRange);
+ map = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, accessFlags, bufObj);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)");
return NULL;
}
#endif
- status = ctx->Driver.UnmapBuffer( ctx, target, bufObj );
+ status = ctx->Driver.UnmapBuffer( ctx, bufObj );
bufObj->AccessFlags = DEFAULT_ACCESS;
ASSERT(bufObj->Pointer == NULL);
ASSERT(bufObj->Offset == 0);
return NULL;
}
+ if (access & ~(GL_MAP_READ_BIT |
+ GL_MAP_WRITE_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT |
+ GL_MAP_INVALIDATE_BUFFER_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT |
+ GL_MAP_UNSYNCHRONIZED_BIT)) {
+ /* generate an error if any undefind bit is set */
+ _mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(access)");
+ return NULL;
+ }
+
if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(access indicates neither read or write)");
"glMapBufferRange(buffer already mapped)");
return NULL;
}
-
+
+ if (!bufObj->Size) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY,
+ "glMapBufferRange(buffer size = 0)");
+ return NULL;
+ }
+
+ /* Mapping zero bytes should return a non-null pointer. */
+ if (!length) {
+ static long dummy = 0;
+ bufObj->Pointer = &dummy;
+ bufObj->Length = length;
+ bufObj->Offset = offset;
+ bufObj->AccessFlags = access;
+ return bufObj->Pointer;
+ }
+
ASSERT(ctx->Driver.MapBufferRange);
- map = ctx->Driver.MapBufferRange(ctx, target, offset, length,
- access, bufObj);
+ map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj);
if (!map) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)");
}
ASSERT(bufObj->AccessFlags & GL_MAP_WRITE_BIT);
if (ctx->Driver.FlushMappedBufferRange)
- ctx->Driver.FlushMappedBufferRange(ctx, target, offset, length, bufObj);
+ ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj);
}