summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/bufferobj.c
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2017-02-02 23:24:35 +0100
committerNicolai Hähnle <[email protected]>2017-04-05 10:31:02 +0200
commit4e6feacf6aa589574da3b70f32ed4e87494c7000 (patch)
tree5856d4a251ac2f184ee2528926de39b95b9283e0 /src/mesa/main/bufferobj.c
parentd6fcbe1c2a88a33128bdf3ae02705d65dd9a3e8e (diff)
mesa: implement sparse buffer commitment
Reviewed-by: Ian Romanick <[email protected]> Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/mesa/main/bufferobj.c')
-rw-r--r--src/mesa/main/bufferobj.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index a4ccf8c5e51..27eaf771a38 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -4061,14 +4061,80 @@ _mesa_InvalidateBufferData(GLuint buffer)
ctx->Driver.InvalidateBufferSubData(ctx, bufObj, 0, bufObj->Size);
}
+static void
+buffer_page_commitment(struct gl_context *ctx,
+ struct gl_buffer_object *bufferObj,
+ GLintptr offset, GLsizeiptr size,
+ GLboolean commit, const char *func)
+{
+ if (!(bufferObj->StorageFlags & GL_SPARSE_STORAGE_BIT_ARB)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(not a sparse buffer object)",
+ func);
+ return;
+ }
+
+ if (size < 0 || size > bufferObj->Size ||
+ offset < 0 || offset > bufferObj->Size - size) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(out of bounds)",
+ func);
+ return;
+ }
+
+ /* The GL_ARB_sparse_buffer extension specification says:
+ *
+ * "INVALID_VALUE is generated by BufferPageCommitmentARB if <offset> is
+ * not an integer multiple of SPARSE_BUFFER_PAGE_SIZE_ARB, or if <size>
+ * is not an integer multiple of SPARSE_BUFFER_PAGE_SIZE_ARB and does
+ * not extend to the end of the buffer's data store."
+ */
+ if (offset % ctx->Const.SparseBufferPageSize != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset not aligned to page size)",
+ func);
+ return;
+ }
+
+ if (size % ctx->Const.SparseBufferPageSize != 0 &&
+ offset + size != bufferObj->Size) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(size not aligned to page size)",
+ func);
+ return;
+ }
+
+ ctx->Driver.BufferPageCommitment(ctx, bufferObj, offset, size, commit);
+}
+
void GLAPIENTRY
_mesa_BufferPageCommitmentARB(GLenum target, GLintptr offset, GLsizeiptr size,
GLboolean commit)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufferObj;
+
+ bufferObj = get_buffer(ctx, "glBufferPageCommitmentARB", target,
+ GL_INVALID_ENUM);
+ if (!bufferObj)
+ return;
+
+ buffer_page_commitment(ctx, bufferObj, offset, size, commit,
+ "glBufferPageCommitmentARB");
}
void GLAPIENTRY
_mesa_NamedBufferPageCommitmentARB(GLuint buffer, GLintptr offset,
GLsizeiptr size, GLboolean commit)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object *bufferObj;
+
+ bufferObj = _mesa_lookup_bufferobj(ctx, buffer);
+ if (!bufferObj || bufferObj == &DummyBufferObject) {
+ /* Note: the extension spec is not clear about the excpected error value. */
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glNamedBufferPageCommitmentARB(name = %u) invalid object",
+ buffer);
+ return;
+ }
+
+ buffer_page_commitment(ctx, bufferObj, offset, size, commit,
+ "glNamedBufferPageCommitmentARB");
}