mesa: implement glBufferStorage, immutable buffers; add extension enable flag

Reviewed-by: Fredrik Höglund <fredrik@kde.org>

v2: dropped the error that DYNAMIC_STORAGE is required for MAP_WRITE_BIT,
    the error is removed in the latest revision of GL 4.4
This commit is contained in:
Marek Olšák 2014-01-27 21:22:43 +01:00
parent 7e548d0507
commit e592f11227
4 changed files with 100 additions and 0 deletions

View file

@ -1233,6 +1233,68 @@ _mesa_IsBuffer(GLuint id)
}
void GLAPIENTRY
_mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
GLbitfield flags)
{
GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object *bufObj;
if (size <= 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(size <= 0)");
return;
}
if (flags & ~(GL_MAP_READ_BIT |
GL_MAP_WRITE_BIT |
GL_MAP_PERSISTENT_BIT |
GL_MAP_COHERENT_BIT |
GL_DYNAMIC_STORAGE_BIT |
GL_CLIENT_STORAGE_BIT)) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags)");
return;
}
if (flags & GL_MAP_PERSISTENT_BIT &&
!(flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags!=READ/WRITE)");
return;
}
if (flags & GL_MAP_COHERENT_BIT && !(flags & GL_MAP_PERSISTENT_BIT)) {
_mesa_error(ctx, GL_INVALID_VALUE, "glBufferStorage(flags!=PERSISTENT)");
return;
}
bufObj = get_buffer(ctx, "glBufferStorage", target, GL_INVALID_OPERATION);
if (!bufObj)
return;
if (bufObj->Immutable) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBufferStorage(immutable)");
return;
}
if (_mesa_bufferobj_mapped(bufObj)) {
/* Unmap the existing buffer. We'll replace it now. Not an error. */
ctx->Driver.UnmapBuffer(ctx, bufObj);
bufObj->AccessFlags = 0;
ASSERT(bufObj->Pointer == NULL);
}
FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
bufObj->Written = GL_TRUE;
bufObj->Immutable = GL_TRUE;
ASSERT(ctx->Driver.BufferData);
if (!ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW,
flags, bufObj)) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()");
}
}
void GLAPIENTRY
_mesa_BufferData(GLenum target, GLsizeiptrARB size,
const GLvoid * data, GLenum usage)
@ -1285,6 +1347,11 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size,
if (!bufObj)
return;
if (bufObj->Immutable) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBufferData(immutable)");
return;
}
if (_mesa_bufferobj_mapped(bufObj)) {
/* Unmap the existing buffer. We'll replace it now. Not an error. */
ctx->Driver.UnmapBuffer(ctx, bufObj);
@ -1331,6 +1398,12 @@ _mesa_BufferSubData(GLenum target, GLintptrARB offset,
return;
}
if (bufObj->Immutable &&
!(bufObj->StorageFlags & GL_DYNAMIC_STORAGE_BIT)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBufferSubData");
return;
}
if (size == 0)
return;
@ -1663,6 +1736,16 @@ _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
goto invalid_pname;
*params = (GLint) bufObj->Length;
return;
case GL_BUFFER_IMMUTABLE_STORAGE:
if (!ctx->Extensions.ARB_buffer_storage)
goto invalid_pname;
*params = bufObj->Immutable;
return;
case GL_BUFFER_STORAGE_FLAGS:
if (!ctx->Extensions.ARB_buffer_storage)
goto invalid_pname;
*params = bufObj->StorageFlags;
return;
default:
; /* fall-through */
}
@ -1717,6 +1800,16 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
goto invalid_pname;
*params = bufObj->Length;
return;
case GL_BUFFER_IMMUTABLE_STORAGE:
if (!ctx->Extensions.ARB_buffer_storage)
goto invalid_pname;
*params = bufObj->Immutable;
return;
case GL_BUFFER_STORAGE_FLAGS:
if (!ctx->Extensions.ARB_buffer_storage)
goto invalid_pname;
*params = bufObj->StorageFlags;
return;
default:
; /* fall-through */
}

View file

@ -117,6 +117,10 @@ _mesa_GenBuffers(GLsizei n, GLuint * buffer);
GLboolean GLAPIENTRY
_mesa_IsBuffer(GLuint buffer);
void GLAPIENTRY
_mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
GLbitfield flags);
void GLAPIENTRY
_mesa_BufferData(GLenum target, GLsizeiptrARB size,
const GLvoid * data, GLenum usage);

View file

@ -83,6 +83,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_arrays_of_arrays", o(ARB_arrays_of_arrays), GL, 2012 },
{ "GL_ARB_base_instance", o(ARB_base_instance), GL, 2011 },
{ "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL, 2009 },
{ "GL_ARB_buffer_storage", o(ARB_buffer_storage), GL, 2013 },
{ "GL_ARB_clear_buffer_object", o(dummy_true), GL, 2012 },
{ "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 },
{ "GL_ARB_compute_shader", o(ARB_compute_shader), GL, 2012 },

View file

@ -1462,6 +1462,7 @@ struct gl_buffer_object
GLboolean DeletePending; /**< true if buffer object is removed from the hash */
GLboolean Written; /**< Ever written to? (for debugging) */
GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */
GLboolean Immutable; /**< GL_ARB_buffer_storage */
};
@ -3474,6 +3475,7 @@ struct gl_extensions
GLboolean ARB_arrays_of_arrays;
GLboolean ARB_base_instance;
GLboolean ARB_blend_func_extended;
GLboolean ARB_buffer_storage;
GLboolean ARB_color_buffer_float;
GLboolean ARB_compute_shader;
GLboolean ARB_conservative_depth;