diff options
-rw-r--r-- | src/mesa/main/bufferobj.c | 66 | ||||
-rw-r--r-- | src/mesa/main/dd.h | 10 |
2 files changed, 76 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"); } diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index b3a85f19857..3f3102546df 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1040,6 +1040,16 @@ struct dd_function_table { * Mesa will only call this function if GL multithreading is enabled. */ void (*SetBackgroundContext)(struct gl_context *ctx); + + /** + * \name GL_ARB_sparse_buffer interface + */ + /*@{*/ + void (*BufferPageCommitment)(struct gl_context *ctx, + struct gl_buffer_object *bufferObj, + GLintptr offset, GLsizeiptr size, + GLboolean commit); + /*@}*/ }; |