X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fbufferobj.c;h=73b210d105ad1e68658e2cb957fbeb87f34bf0bb;hp=099648f4198f347685955b252af62e12e3d82ef4;hb=e3385eb0c1c9e6e0466c282d722f02dd5fd49204;hpb=46a8c4ef811ce1b909615f29a4059e079db3b930 diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 099648f4198..73b210d105a 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -46,6 +46,7 @@ #include "texstore.h" #include "transformfeedback.h" #include "varray.h" +#include "util/u_atomic.h" /* Debug flags */ @@ -72,11 +73,11 @@ buffer_usage_warning(struct gl_context *ctx, GLuint *id, const char *fmt, ...) va_list args; va_start(args, fmt); - _mesa_gl_vdebug(ctx, id, - MESA_DEBUG_SOURCE_API, - MESA_DEBUG_TYPE_PERFORMANCE, - MESA_DEBUG_SEVERITY_MEDIUM, - fmt, args); + _mesa_gl_vdebugf(ctx, id, + MESA_DEBUG_SOURCE_API, + MESA_DEBUG_TYPE_PERFORMANCE, + MESA_DEBUG_SEVERITY_MEDIUM, + fmt, args); va_end(args); } @@ -112,8 +113,13 @@ get_buffer_target(struct gl_context *ctx, GLenum target) switch (target) { case GL_ARRAY_BUFFER_ARB: + if (ctx->Array.ArrayBufferObj) + ctx->Array.ArrayBufferObj->UsageHistory |= USAGE_ARRAY_BUFFER; return &ctx->Array.ArrayBufferObj; case GL_ELEMENT_ARRAY_BUFFER_ARB: + if (ctx->Array.VAO->IndexBufferObj) + ctx->Array.VAO->IndexBufferObj->UsageHistory + |= USAGE_ELEMENT_ARRAY_BUFFER; return &ctx->Array.VAO->IndexBufferObj; case GL_PIXEL_PACK_BUFFER_EXT: return &ctx->Pack.BufferObj; @@ -128,8 +134,7 @@ get_buffer_target(struct gl_context *ctx, GLenum target) return &ctx->QueryBuffer; break; case GL_DRAW_INDIRECT_BUFFER: - if ((ctx->API == API_OPENGL_CORE && - ctx->Extensions.ARB_draw_indirect) || + if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_draw_indirect) || _mesa_is_gles31(ctx)) { return &ctx->DrawIndirectBuffer; } @@ -346,7 +351,8 @@ buffer_object_subdata_range_good(struct gl_context *ctx, /** * Test the format and type parameters and set the GL error code for - * \c glClearBufferData and \c glClearBufferSubData. + * \c glClearBufferData, \c glClearNamedBufferData, \c glClearBufferSubData + * and \c glClearNamedBufferSubData. * * \param ctx GL context. * \param internalformat Format to which the data is to be converted. @@ -356,7 +362,8 @@ buffer_object_subdata_range_good(struct gl_context *ctx, * \return If internalformat, format and type are legal the mesa_format * corresponding to internalformat, otherwise MESA_FORMAT_NONE. * - * \sa glClearBufferData and glClearBufferSubData + * \sa glClearBufferData, glClearNamedBufferData, glClearBufferSubData and + * glClearNamedBufferSubData. */ static mesa_format validate_clear_buffer_format(struct gl_context *ctx, @@ -386,14 +393,14 @@ validate_clear_buffer_format(struct gl_context *ctx, } if (!_mesa_is_color_format(format)) { - _mesa_error(ctx, GL_INVALID_ENUM, + _mesa_error(ctx, GL_INVALID_VALUE, "%s(format is not a color format)", caller); return MESA_FORMAT_NONE; } errorFormatType = _mesa_error_check_format_and_type(ctx, format, type); if (errorFormatType != GL_NO_ERROR) { - _mesa_error(ctx, GL_INVALID_ENUM, + _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid format or type)", caller); return MESA_FORMAT_NONE; } @@ -471,7 +478,7 @@ _mesa_delete_buffer_object(struct gl_context *ctx, bufObj->RefCount = -1000; bufObj->Name = ~0; - mtx_destroy(&bufObj->Mutex); + simple_mtx_destroy(&bufObj->MinMaxCacheMutex); free(bufObj->Label); free(bufObj); } @@ -490,16 +497,9 @@ _mesa_reference_buffer_object_(struct gl_context *ctx, { if (*ptr) { /* Unreference the old buffer */ - GLboolean deleteFlag = GL_FALSE; struct gl_buffer_object *oldObj = *ptr; - mtx_lock(&oldObj->Mutex); - assert(oldObj->RefCount > 0); - oldObj->RefCount--; - deleteFlag = (oldObj->RefCount == 0); - mtx_unlock(&oldObj->Mutex); - - if (deleteFlag) { + if (p_atomic_dec_zero(&oldObj->RefCount)) { assert(ctx->Driver.DeleteBuffer); ctx->Driver.DeleteBuffer(ctx, oldObj); } @@ -510,12 +510,8 @@ _mesa_reference_buffer_object_(struct gl_context *ctx, if (bufObj) { /* reference new buffer */ - mtx_lock(&bufObj->Mutex); - assert(bufObj->RefCount > 0); - - bufObj->RefCount++; + p_atomic_inc(&bufObj->RefCount); *ptr = bufObj; - mtx_unlock(&bufObj->Mutex); } } @@ -547,11 +543,11 @@ _mesa_initialize_buffer_object(struct gl_context *ctx, GLuint name) { memset(obj, 0, sizeof(struct gl_buffer_object)); - mtx_init(&obj->Mutex, mtx_plain); obj->RefCount = 1; obj->Name = name; obj->Usage = GL_STATIC_DRAW_ARB; + simple_mtx_init(&obj->MinMaxCacheMutex, mtx_plain); if (get_no_minmax_cache()) obj->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE; } @@ -608,7 +604,7 @@ _mesa_total_buffer_object_memory(struct gl_context *ctx) * \sa glBufferDataARB, dd_function_table::BufferData. */ static GLboolean -buffer_data_fallback(struct gl_context *ctx, GLenum target, GLsizeiptr size, +buffer_data_fallback(struct gl_context *ctx, GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage, GLenum storageFlags, struct gl_buffer_object *bufObj) { @@ -654,8 +650,8 @@ buffer_data_fallback(struct gl_context *ctx, GLenum target, GLsizeiptr size, * \sa glBufferSubDataARB, dd_function_table::BufferSubData. */ static void -buffer_sub_data_fallback(struct gl_context *ctx, GLintptr offset, - GLsizeiptr size, const GLvoid *data, +buffer_sub_data_fallback(struct gl_context *ctx, GLintptrARB offset, + GLsizeiptrARB size, const GLvoid *data, struct gl_buffer_object *bufObj) { (void) ctx; @@ -870,7 +866,7 @@ _mesa_init_buffer_objects( struct gl_context *ctx ) GLuint i; memset(&DummyBufferObject, 0, sizeof(DummyBufferObject)); - mtx_init(&DummyBufferObject.Mutex, mtx_plain); + simple_mtx_init(&DummyBufferObject.MinMaxCacheMutex, mtx_plain); DummyBufferObject.RefCount = 1000*1000*1000; /* never delete */ _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, @@ -1258,43 +1254,18 @@ _mesa_BindBuffer(GLenum target, GLuint buffer) } /** - * Binds a buffer object to an atomic buffer binding point. + * Binds a buffer object to a binding point. * * The caller is responsible for validating the offset, * flushing the vertices and updating NewDriverState. */ static void -set_atomic_buffer_binding(struct gl_context *ctx, - struct gl_atomic_buffer_binding *binding, - struct gl_buffer_object *bufObj, - GLintptr offset, - GLsizeiptr size) -{ - _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj); - - if (bufObj == ctx->Shared->NullBufferObj) { - binding->Offset = 0; - binding->Size = 0; - } else { - binding->Offset = offset; - binding->Size = size; - bufObj->UsageHistory |= USAGE_ATOMIC_COUNTER_BUFFER; - } -} - -/** - * Binds a buffer object to a uniform buffer binding point. - * - * The caller is responsible for flushing vertices and updating - * NewDriverState. - */ -static void -set_ubo_binding(struct gl_context *ctx, - struct gl_uniform_buffer_binding *binding, - struct gl_buffer_object *bufObj, - GLintptr offset, - GLsizeiptr size, - GLboolean autoSize) +set_buffer_binding(struct gl_context *ctx, + struct gl_buffer_binding *binding, + struct gl_buffer_object *bufObj, + GLintptr offset, + GLsizeiptr size, + bool autoSize, gl_buffer_usage usage) { _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj); @@ -1303,43 +1274,64 @@ set_ubo_binding(struct gl_context *ctx, binding->AutomaticSize = autoSize; /* If this is a real buffer object, mark it has having been used - * at some point as a UBO. + * at some point as an atomic counter buffer. */ if (size >= 0) - bufObj->UsageHistory |= USAGE_UNIFORM_BUFFER; + bufObj->UsageHistory |= usage; } -/** - * Binds a buffer object to a shader storage buffer binding point. - * - * The caller is responsible for flushing vertices and updating - * NewDriverState. - */ static void -set_ssbo_binding(struct gl_context *ctx, - struct gl_shader_storage_buffer_binding *binding, - struct gl_buffer_object *bufObj, - GLintptr offset, - GLsizeiptr size, - GLboolean autoSize) +set_buffer_multi_binding(struct gl_context *ctx, + const GLuint *buffers, + int idx, + const char *caller, + struct gl_buffer_binding *binding, + GLintptr offset, + GLsizeiptr size, + bool range, + gl_buffer_usage usage) { - _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj); + struct gl_buffer_object *bufObj; + if (binding->BufferObject && binding->BufferObject->Name == buffers[idx]) + bufObj = binding->BufferObject; + else + bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, idx, caller); - binding->Offset = offset; - binding->Size = size; - binding->AutomaticSize = autoSize; + if (bufObj) { + if (bufObj == ctx->Shared->NullBufferObj) + set_buffer_binding(ctx, binding, bufObj, -1, -1, !range, usage); + else + set_buffer_binding(ctx, binding, bufObj, offset, size, !range, usage); + } +} - /* If this is a real buffer object, mark it has having been used - * at some point as a SSBO. - */ - if (size >= 0) - bufObj->UsageHistory |= USAGE_SHADER_STORAGE_BUFFER; +static void +bind_buffer(struct gl_context *ctx, + struct gl_buffer_binding *binding, + struct gl_buffer_object *bufObj, + GLintptr offset, + GLsizeiptr size, + GLboolean autoSize, + uint64_t driver_state, + gl_buffer_usage usage) +{ + if (binding->BufferObject == bufObj && + binding->Offset == offset && + binding->Size == size && + binding->AutomaticSize == autoSize) { + return; + } + + FLUSH_VERTICES(ctx, 0); + ctx->NewDriverState |= driver_state; + + set_buffer_binding(ctx, binding, bufObj, offset, size, autoSize, usage); } /** * Binds a buffer object to a uniform buffer binding point. * - * Unlike set_ubo_binding(), this function also flushes vertices + * Unlike set_buffer_binding(), this function also flushes vertices * and updates NewDriverState. It also checks if the binding * has actually changed before updating it. */ @@ -1351,20 +1343,10 @@ bind_uniform_buffer(struct gl_context *ctx, GLsizeiptr size, GLboolean autoSize) { - struct gl_uniform_buffer_binding *binding = - &ctx->UniformBufferBindings[index]; - - if (binding->BufferObject == bufObj && - binding->Offset == offset && - binding->Size == size && - binding->AutomaticSize == autoSize) { - return; - } - - FLUSH_VERTICES(ctx, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer; - - set_ubo_binding(ctx, binding, bufObj, offset, size, autoSize); + bind_buffer(ctx, &ctx->UniformBufferBindings[index], + bufObj, offset, size, autoSize, + ctx->DriverFlags.NewUniformBuffer, + USAGE_UNIFORM_BUFFER); } /** @@ -1382,20 +1364,28 @@ bind_shader_storage_buffer(struct gl_context *ctx, GLsizeiptr size, GLboolean autoSize) { - struct gl_shader_storage_buffer_binding *binding = - &ctx->ShaderStorageBufferBindings[index]; - - if (binding->BufferObject == bufObj && - binding->Offset == offset && - binding->Size == size && - binding->AutomaticSize == autoSize) { - return; - } - - FLUSH_VERTICES(ctx, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer; + bind_buffer(ctx, &ctx->ShaderStorageBufferBindings[index], + bufObj, offset, size, autoSize, + ctx->DriverFlags.NewShaderStorageBuffer, + USAGE_SHADER_STORAGE_BUFFER); +} - set_ssbo_binding(ctx, binding, bufObj, offset, size, autoSize); +/** + * Binds a buffer object to an atomic buffer binding point. + * + * Unlike set_atomic_binding(), this function also flushes vertices + * and updates NewDriverState. It also checks if the binding + * has actually changed before updating it. + */ +static void +bind_atomic_buffer(struct gl_context *ctx, unsigned index, + struct gl_buffer_object *bufObj, GLintptr offset, + GLsizeiptr size, GLboolean autoSize) +{ + bind_buffer(ctx, &ctx->AtomicBufferBindings[index], + bufObj, offset, size, autoSize, + ctx->DriverFlags.NewAtomicBuffer, + USAGE_ATOMIC_COUNTER_BUFFER); } /** @@ -1442,25 +1432,26 @@ bind_buffer_base_shader_storage_buffer(struct gl_context *ctx, bind_shader_storage_buffer(ctx, index, bufObj, 0, 0, GL_TRUE); } +/** + * Bind a buffer object to a shader storage block binding point. + * As above, but offset = 0. + */ static void -bind_atomic_buffer(struct gl_context *ctx, unsigned index, - struct gl_buffer_object *bufObj, GLintptr offset, - GLsizeiptr size) +bind_buffer_base_atomic_buffer(struct gl_context *ctx, + GLuint index, + struct gl_buffer_object *bufObj) { - _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj); - - struct gl_atomic_buffer_binding *binding = - &ctx->AtomicBufferBindings[index]; - if (binding->BufferObject == bufObj && - binding->Offset == offset && - binding->Size == size) { + if (index >= ctx->Const.MaxAtomicBufferBindings) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index); return; } - FLUSH_VERTICES(ctx, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer; + _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj); - set_atomic_buffer_binding(ctx, binding, bufObj, offset, size); + if (bufObj == ctx->Shared->NullBufferObj) + bind_atomic_buffer(ctx, index, bufObj, -1, -1, GL_TRUE); + else + bind_atomic_buffer(ctx, index, bufObj, 0, 0, GL_TRUE); } /** @@ -1562,8 +1553,8 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids) /* unbind Atomci Buffer binding points */ for (j = 0; j < ctx->Const.MaxAtomicBufferBindings; j++) { if (ctx->AtomicBufferBindings[j].BufferObject == bufObj) { - _mesa_BindBufferBase( GL_ATOMIC_COUNTER_BUFFER, j, 0 ); - bind_atomic_buffer(ctx, j, ctx->Shared->NullBufferObj, 0, 0); + bind_buffer_base_atomic_buffer(ctx, j, + ctx->Shared->NullBufferObj); } } @@ -1946,6 +1937,21 @@ _mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, false, false, false, "glBufferStorage"); } +void GLAPIENTRY +_mesa_NamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, + const GLvoid *data, GLbitfield flags) +{ + GET_CURRENT_CONTEXT(ctx); + + struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glNamedBufferStorageEXT")) + return; + + inlined_buffer_storage(GL_NONE, buffer, size, data, flags, GL_NONE, 0, + true, false, false, "glNamedBufferStorageEXT"); +} + void GLAPIENTRY _mesa_BufferStorageMemEXT(GLenum target, GLsizeiptr size, @@ -2178,6 +2184,27 @@ _mesa_NamedBufferData(GLuint buffer, GLsizeiptr size, const GLvoid *data, "glNamedBufferData"); } +void GLAPIENTRY +_mesa_NamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const GLvoid *data, + GLenum usage) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj; + + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glNamedBufferDataEXT(buffer=0)"); + return; + } + + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glNamedBufferDataEXT")) + return; + + _mesa_buffer_data(ctx, bufObj, GL_NONE, size, data, usage, + "glNamedBufferDataEXT"); +} static bool validate_buffer_sub_data(struct gl_context *ctx, @@ -2306,6 +2333,30 @@ _mesa_NamedBufferSubData(GLuint buffer, GLintptr offset, "glNamedBufferSubData"); } +void GLAPIENTRY +_mesa_NamedBufferSubDataEXT(GLuint buffer, GLintptr offset, + GLsizeiptr size, const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj; + + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glNamedBufferSubDataEXT(buffer=0)"); + return; + } + + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glNamedBufferSubDataEXT")) + return; + + if (validate_buffer_sub_data(ctx, bufObj, offset, size, + "glNamedBufferSubDataEXT")) { + _mesa_buffer_sub_data(ctx, bufObj, offset, size, data); + } +} + void GLAPIENTRY _mesa_GetBufferSubData(GLenum target, GLintptr offset, @@ -2350,6 +2401,33 @@ _mesa_GetNamedBufferSubData(GLuint buffer, GLintptr offset, } +void GLAPIENTRY +_mesa_GetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, + GLsizeiptr size, GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj; + + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetNamedBufferSubDataEXT(buffer=0)"); + return; + } + + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glGetNamedBufferSubDataEXT")) + return; + + if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size, false, + "glGetNamedBufferSubDataEXT")) { + return; + } + + assert(ctx->Driver.GetBufferSubData); + ctx->Driver.GetBufferSubData(ctx, offset, size, data, bufObj); +} + /** * \param subdata true if caller is *SubData, false if *Data */ @@ -2495,6 +2573,22 @@ _mesa_ClearNamedBufferData(GLuint buffer, GLenum internalformat, } +void GLAPIENTRY +_mesa_ClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, + GLenum format, GLenum type, const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glClearNamedBufferDataEXT")) + return; + + clear_buffer_sub_data_error(ctx, bufObj, internalformat, 0, bufObj->Size, + format, type, data, "glClearNamedBufferDataEXT", + false); +} + + void GLAPIENTRY _mesa_ClearBufferSubData_no_error(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, @@ -2563,6 +2657,23 @@ _mesa_ClearNamedBufferSubData(GLuint buffer, GLenum internalformat, true); } +void GLAPIENTRY +_mesa_ClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, + GLintptr offset, GLsizeiptr size, + GLenum format, GLenum type, + const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glClearNamedBufferSubDataEXT")) + return; + + clear_buffer_sub_data_error(ctx, bufObj, internalformat, offset, size, + format, type, data, "glClearNamedBufferSubDataEXT", + true); +} + static GLboolean unmap_buffer(struct gl_context *ctx, struct gl_buffer_object *bufObj) { @@ -2651,7 +2762,7 @@ _mesa_UnmapBuffer(GLenum target) } GLboolean GLAPIENTRY -_mesa_UnmapNamedBuffer_no_error(GLuint buffer) +_mesa_UnmapNamedBufferEXT_no_error(GLuint buffer) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); @@ -2660,11 +2771,17 @@ _mesa_UnmapNamedBuffer_no_error(GLuint buffer) } GLboolean GLAPIENTRY -_mesa_UnmapNamedBuffer(GLuint buffer) +_mesa_UnmapNamedBufferEXT(GLuint buffer) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUnmapNamedBufferEXT(buffer=0)"); + return GL_FALSE; + } + bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glUnmapNamedBuffer"); if (!bufObj) return GL_FALSE; @@ -2786,6 +2903,31 @@ _mesa_GetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint *params) *params = (GLint) parameter; } +void GLAPIENTRY +_mesa_GetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj; + GLint64 parameter; + + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetNamedBufferParameterivEXT: buffer=0"); + return; + } + + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glGetNamedBufferParameterivEXT")) + return; + + if (!get_buffer_parameter(ctx, bufObj, pname, ¶meter, + "glGetNamedBufferParameterivEXT")) + return; /* Error already recorded. */ + + *params = (GLint) parameter; +} + void GLAPIENTRY _mesa_GetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64 *params) @@ -2847,6 +2989,30 @@ _mesa_GetNamedBufferPointerv(GLuint buffer, GLenum pname, GLvoid **params) *params = bufObj->Mappings[MAP_USER].Pointer; } +void GLAPIENTRY +_mesa_GetNamedBufferPointervEXT(GLuint buffer, GLenum pname, GLvoid **params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj; + + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetNamedBufferPointervEXT(buffer=0)"); + return; + } + if (pname != GL_BUFFER_MAP_POINTER) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetNamedBufferPointervEXT(pname != " + "GL_BUFFER_MAP_POINTER)"); + return; + } + + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glGetNamedBufferPointervEXT")) + return; + + *params = bufObj->Mappings[MAP_USER].Pointer; +} static void copy_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *src, @@ -2957,6 +3123,30 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget, "glCopyBufferSubData"); } +void GLAPIENTRY +_mesa_NamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *src, *dst; + + src = _mesa_lookup_bufferobj(ctx, readBuffer); + if (!_mesa_handle_bind_buffer_gen(ctx, readBuffer, + &src, + "glNamedCopyBufferSubDataEXT")) + return; + + dst = _mesa_lookup_bufferobj(ctx, writeBuffer); + if (!_mesa_handle_bind_buffer_gen(ctx, writeBuffer, + &dst, + "glNamedCopyBufferSubDataEXT")) + return; + + copy_buffer_sub_data(ctx, src, dst, readOffset, writeOffset, size, + "glNamedCopyBufferSubDataEXT"); +} + void GLAPIENTRY _mesa_CopyNamedBufferSubData_no_error(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, @@ -3240,30 +3430,55 @@ _mesa_MapNamedBufferRange_no_error(GLuint buffer, GLintptr offset, "glMapNamedBufferRange"); } -void * GLAPIENTRY -_mesa_MapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, - GLbitfield access) +static void * +map_named_buffer_range(GLuint buffer, GLintptr offset, GLsizeiptr length, + GLbitfield access, bool dsa_ext, const char *func) { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object *bufObj; + struct gl_buffer_object *bufObj = NULL; if (!ctx->Extensions.ARB_map_buffer_range) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glMapNamedBufferRange(" - "ARB_map_buffer_range not supported)"); + "%s(ARB_map_buffer_range not supported)", func); return NULL; } - bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMapNamedBufferRange"); - if (!bufObj) + if (dsa_ext) { + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &bufObj, func)) + return NULL; + } else { + bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, func); + if (!bufObj) + return NULL; + } + + if (!validate_map_buffer_range(ctx, bufObj, offset, length, access, func)) return NULL; - if (!validate_map_buffer_range(ctx, bufObj, offset, length, access, - "glMapNamedBufferRange")) + return map_buffer_range(ctx, bufObj, offset, length, access, func); +} + +void * GLAPIENTRY +_mesa_MapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length, + GLbitfield access) +{ + GET_CURRENT_CONTEXT(ctx); + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glMapNamedBufferRangeEXT(buffer=0)"); return NULL; + } + return map_named_buffer_range(buffer, offset, length, access, true, + "glMapNamedBufferRangeEXT"); +} - return map_buffer_range(ctx, bufObj, offset, length, access, - "glMapNamedBufferRange"); +void * GLAPIENTRY +_mesa_MapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, + GLbitfield access) +{ + return map_named_buffer_range(buffer, offset, length, access, false, + "glMapNamedBufferRange"); } /** @@ -3287,6 +3502,7 @@ get_map_buffer_access_flags(struct gl_context *ctx, GLenum access, *flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; return _mesa_is_desktop_gl(ctx); default: + *flags = 0; return false; } } @@ -3368,6 +3584,34 @@ _mesa_MapNamedBuffer(GLuint buffer, GLenum access) "glMapNamedBuffer"); } +void * GLAPIENTRY +_mesa_MapNamedBufferEXT(GLuint buffer, GLenum access) +{ + GET_CURRENT_CONTEXT(ctx); + + GLbitfield accessFlags; + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glMapNamedBufferEXT(buffer=0)"); + return NULL; + } + if (!get_map_buffer_access_flags(ctx, access, &accessFlags)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMapNamedBufferEXT(invalid access)"); + return NULL; + } + + struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glMapNamedBufferEXT")) + return NULL; + + if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags, + "glMapNamedBufferEXT")) + return NULL; + + return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags, + "glMapNamedBufferEXT"); +} static void flush_mapped_buffer_range(struct gl_context *ctx, @@ -3479,6 +3723,28 @@ _mesa_FlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, "glFlushMappedNamedBufferRange"); } +void GLAPIENTRY +_mesa_FlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, + GLsizeiptr length) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_buffer_object *bufObj; + + if (!buffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glFlushMappedNamedBufferRangeEXT(buffer=0)"); + return; + } + + bufObj = _mesa_lookup_bufferobj(ctx, buffer); + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glFlushMappedNamedBufferRangeEXT")) + return; + + flush_mapped_buffer_range(ctx, bufObj, offset, length, + "glFlushMappedNamedBufferRangeEXT"); +} + static void bind_buffer_range_uniform_buffer(struct gl_context *ctx, GLuint index, struct gl_buffer_object *bufObj, @@ -3564,32 +3830,46 @@ bind_buffer_range_shader_storage_buffer_err(struct gl_context *ctx, bind_buffer_range_shader_storage_buffer(ctx, index, bufObj, offset, size); } +static void +bind_buffer_range_atomic_buffer(struct gl_context *ctx, GLuint index, + struct gl_buffer_object *bufObj, + GLintptr offset, GLsizeiptr size) +{ + if (bufObj == ctx->Shared->NullBufferObj) { + offset = -1; + size = -1; + } + + _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj); + bind_atomic_buffer(ctx, index, bufObj, offset, size, GL_FALSE); +} + /** - * Binds a buffer object to an atomic buffer binding point. - * - * Unlike set_atomic_buffer_binding(), this function also validates the - * index and offset, flushes vertices, and updates NewDriverState. - * It also checks if the binding has actually changing before - * updating it. + * Bind a region of a buffer object to an atomic storage block binding point. + * \param index the shader storage buffer binding point index + * \param bufObj the buffer object + * \param offset offset to the start of buffer object region + * \param size size of the buffer object region */ static void -bind_atomic_buffer_err(struct gl_context *ctx, unsigned index, - struct gl_buffer_object *bufObj, GLintptr offset, - GLsizeiptr size, const char *name) +bind_buffer_range_atomic_buffer_err(struct gl_context *ctx, + GLuint index, + struct gl_buffer_object *bufObj, + GLintptr offset, GLsizeiptr size) { if (index >= ctx->Const.MaxAtomicBufferBindings) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%d)", name, index); + _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index); return; } if (offset & (ATOMIC_COUNTER_SIZE - 1)) { _mesa_error(ctx, GL_INVALID_VALUE, - "%s(offset misaligned %d/%d)", name, (int) offset, - ATOMIC_COUNTER_SIZE); + "glBindBufferRange(offset misaligned %d/%d)", (int) offset, + ATOMIC_COUNTER_SIZE); return; } - bind_atomic_buffer(ctx, index, bufObj, offset, size); + bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset, size); } static inline bool @@ -3693,8 +3973,8 @@ unbind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count) struct gl_buffer_object *bufObj = ctx->Shared->NullBufferObj; for (int i = 0; i < count; i++) - set_ubo_binding(ctx, &ctx->UniformBufferBindings[first + i], - bufObj, -1, -1, GL_TRUE); + set_buffer_binding(ctx, &ctx->UniformBufferBindings[first + i], + bufObj, -1, -1, GL_TRUE, 0); } /** @@ -3708,8 +3988,8 @@ unbind_shader_storage_buffers(struct gl_context *ctx, GLuint first, struct gl_buffer_object *bufObj = ctx->Shared->NullBufferObj; for (int i = 0; i < count; i++) - set_ssbo_binding(ctx, &ctx->ShaderStorageBufferBindings[first + i], - bufObj, -1, -1, GL_TRUE); + set_buffer_binding(ctx, &ctx->ShaderStorageBufferBindings[first + i], + bufObj, -1, -1, GL_TRUE, 0); } static void @@ -3761,9 +4041,8 @@ bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count, _mesa_HashLockMutex(ctx->Shared->BufferObjects); for (int i = 0; i < count; i++) { - struct gl_uniform_buffer_binding *binding = + struct gl_buffer_binding *binding = &ctx->UniformBufferBindings[first + i]; - struct gl_buffer_object *bufObj; GLintptr offset = 0; GLsizeiptr size = 0; @@ -3805,17 +4084,9 @@ bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count, size = sizes[i]; } - if (binding->BufferObject && binding->BufferObject->Name == buffers[i]) - bufObj = binding->BufferObject; - else - bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, caller); - - if (bufObj) { - if (bufObj == ctx->Shared->NullBufferObj) - set_ubo_binding(ctx, binding, bufObj, -1, -1, !range); - else - set_ubo_binding(ctx, binding, bufObj, offset, size, !range); - } + set_buffer_multi_binding(ctx, buffers, i, caller, + binding, offset, size, range, + USAGE_UNIFORM_BUFFER); } _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); @@ -3871,9 +4142,8 @@ bind_shader_storage_buffers(struct gl_context *ctx, GLuint first, _mesa_HashLockMutex(ctx->Shared->BufferObjects); for (int i = 0; i < count; i++) { - struct gl_shader_storage_buffer_binding *binding = + struct gl_buffer_binding *binding = &ctx->ShaderStorageBufferBindings[first + i]; - struct gl_buffer_object *bufObj; GLintptr offset = 0; GLsizeiptr size = 0; @@ -3915,17 +4185,9 @@ bind_shader_storage_buffers(struct gl_context *ctx, GLuint first, size = sizes[i]; } - if (binding->BufferObject && binding->BufferObject->Name == buffers[i]) - bufObj = binding->BufferObject; - else - bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, caller); - - if (bufObj) { - if (bufObj == ctx->Shared->NullBufferObj) - set_ssbo_binding(ctx, binding, bufObj, -1, -1, !range); - else - set_ssbo_binding(ctx, binding, bufObj, offset, size, !range); - } + set_buffer_multi_binding(ctx, buffers, i, caller, + binding, offset, size, range, + USAGE_SHADER_STORAGE_BUFFER); } _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); @@ -4055,9 +4317,6 @@ bind_xfb_buffers(struct gl_context *ctx, GLsizeiptr size = 0; if (range) { - offset = offsets[i]; - size = sizes[i]; - if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes)) continue; @@ -4152,8 +4411,8 @@ unbind_atomic_buffers(struct gl_context *ctx, GLuint first, GLsizei count) struct gl_buffer_object * const bufObj = ctx->Shared->NullBufferObj; for (int i = 0; i < count; i++) - set_atomic_buffer_binding(ctx, &ctx->AtomicBufferBindings[first + i], - bufObj, -1, -1); + set_buffer_binding(ctx, &ctx->AtomicBufferBindings[first + i], + bufObj, -1, -1, GL_TRUE, 0); } static void @@ -4208,9 +4467,8 @@ bind_atomic_buffers(struct gl_context *ctx, _mesa_HashLockMutex(ctx->Shared->BufferObjects); for (int i = 0; i < count; i++) { - struct gl_atomic_buffer_binding *binding = + struct gl_buffer_binding *binding = &ctx->AtomicBufferBindings[first + i]; - struct gl_buffer_object *bufObj; GLintptr offset = 0; GLsizeiptr size = 0; @@ -4249,13 +4507,9 @@ bind_atomic_buffers(struct gl_context *ctx, size = sizes[i]; } - if (binding->BufferObject && binding->BufferObject->Name == buffers[i]) - bufObj = binding->BufferObject; - else - bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, caller); - - if (bufObj) - set_atomic_buffer_binding(ctx, binding, bufObj, offset, size); + set_buffer_multi_binding(ctx, buffers, i, caller, + binding, offset, size, range, + USAGE_ATOMIC_COUNTER_BUFFER); } _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); @@ -4303,7 +4557,7 @@ bind_buffer_range(GLenum target, GLuint index, GLuint buffer, GLintptr offset, size); return; case GL_ATOMIC_COUNTER_BUFFER: - bind_atomic_buffer(ctx, index, bufObj, offset, size); + bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset, size); return; default: unreachable("invalid BindBufferRange target with KHR_no_error"); @@ -4337,8 +4591,8 @@ bind_buffer_range(GLenum target, GLuint index, GLuint buffer, GLintptr offset, offset, size); return; case GL_ATOMIC_COUNTER_BUFFER: - bind_atomic_buffer_err(ctx, index, bufObj, offset, size, - "glBindBufferRange"); + bind_buffer_range_atomic_buffer_err(ctx, index, bufObj, + offset, size); return; default: _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)"); @@ -4426,8 +4680,7 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer) bind_buffer_base_shader_storage_buffer(ctx, index, bufObj); return; case GL_ATOMIC_COUNTER_BUFFER: - bind_atomic_buffer_err(ctx, index, bufObj, 0, 0, - "glBindBufferBase"); + bind_buffer_base_atomic_buffer(ctx, index, bufObj); return; default: _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");